Skip to content

Commit

Permalink
Merge branch 'master' into aztec-packages
Browse files Browse the repository at this point in the history
* master:
  feat: LSP completion function detail (#5993)
  feat: add `TypedExpr::get_type` (#5992)
  feat: better error message for misplaced doc comments (#5990)
  fix: Error when comptime types are used in runtime code (#5987)
  fix: suggest trait attributes in LSP (#5972)
  fix: Error when `quote` is used in runtime code (#5978)
  chore: document HashMap (#5984)
  fix: Restrict keccak256_injective test input to 8 bits (#5977)
  fix: Error when comptime functions are used in runtime code (#5976)
  chore: document BoundedVec (#5974)
  feat: add `Expr::as_let` (#5964)
  chore: remove 3 unused functions warnings in the stdlib (#5973)
  feat: let `nargo` and LSP work well in the stdlib (#5969)
  • Loading branch information
TomAFrench committed Sep 11, 2024
2 parents ac61ec1 + e84f7d2 commit 3eb2a5b
Show file tree
Hide file tree
Showing 26 changed files with 280 additions and 179 deletions.
10 changes: 9 additions & 1 deletion compiler/noirc_frontend/src/elaborator/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,15 @@ impl<'context> Elaborator<'context> {
let fields = self.resolve_type_inner(*fields, kind);
Type::FmtString(Box::new(resolved_size), Box::new(fields))
}
Quoted(quoted) => Type::Quoted(quoted),
Quoted(quoted) => {
let in_function = matches!(self.current_item, Some(DependencyId::Function(_)));
if in_function && !self.in_comptime_context() {
let span = typ.span;
let typ = quoted.to_string();
self.push_err(ResolverError::ComptimeTypeInRuntimeCode { span, typ });
}
Type::Quoted(quoted)
}
Unit => Type::Unit,
Unspecified => {
let span = typ.span;
Expand Down
26 changes: 26 additions & 0 deletions compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ impl<'local, 'context> Interpreter<'local, 'context> {
"typed_expr_as_function_definition" => {
typed_expr_as_function_definition(interner, arguments, return_type, location)
}
"typed_expr_get_type" => {
typed_expr_get_type(interner, arguments, return_type, location)
}
"unresolved_type_is_field" => unresolved_type_is_field(interner, arguments, location),
"zeroed" => zeroed(return_type),
_ => {
Expand Down Expand Up @@ -1070,6 +1073,7 @@ fn trait_impl_trait_generic_args(
Ok(Value::Slice(trait_generics, slice_type))
}

// fn as_function_definition(self) -> Option<FunctionDefinition>
fn typed_expr_as_function_definition(
interner: &NodeInterner,
arguments: Vec<(Value, Location)>,
Expand All @@ -1087,6 +1091,28 @@ fn typed_expr_as_function_definition(
option(return_type, option_value)
}

// fn get_type(self) -> Option<Type>
fn typed_expr_get_type(
interner: &NodeInterner,
arguments: Vec<(Value, Location)>,
return_type: Type,
location: Location,
) -> IResult<Value> {
let self_argument = check_one_argument(arguments, location)?;
let typed_expr = get_typed_expr(self_argument)?;
let option_value = if let TypedExpr::ExprId(expr_id) = typed_expr {
let typ = interner.id_type(expr_id);
if typ == Type::Error {
None
} else {
Some(Value::Type(typ))
}
} else {
None
};
option(return_type, option_value)
}

// fn is_field(self) -> bool
fn unresolved_type_is_field(
interner: &NodeInterner,
Expand Down
9 changes: 9 additions & 0 deletions compiler/noirc_frontend/src/hir/resolution/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ pub enum ResolverError {
OverflowInType { lhs: u32, op: crate::BinaryTypeOperator, rhs: u32, span: Span },
#[error("`quote` cannot be used in runtime code")]
QuoteInRuntimeCode { span: Span },
#[error("Comptime-only type `{typ}` cannot be used in runtime code")]
ComptimeTypeInRuntimeCode { typ: String, span: Span },
}

impl ResolverError {
Expand Down Expand Up @@ -513,6 +515,13 @@ impl<'a> From<&'a ResolverError> for Diagnostic {
*span,
)
},
ResolverError::ComptimeTypeInRuntimeCode { typ, span } => {
Diagnostic::simple_error(
format!("Comptime-only type `{typ}` cannot be used in runtime code"),
"Comptime-only type used here".to_string(),
*span,
)
},
}
}
}
7 changes: 7 additions & 0 deletions compiler/noirc_frontend/src/monomorphization/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub enum MonomorphizationError {
InternalError { message: &'static str, location: Location },
InterpreterError(InterpreterError),
ComptimeFnInRuntimeCode { name: String, location: Location },
ComptimeTypeInRuntimeCode { typ: String, location: Location },
}

impl MonomorphizationError {
Expand All @@ -17,6 +18,7 @@ impl MonomorphizationError {
MonomorphizationError::UnknownArrayLength { location, .. }
| MonomorphizationError::InternalError { location, .. }
| MonomorphizationError::ComptimeFnInRuntimeCode { location, .. }
| MonomorphizationError::ComptimeTypeInRuntimeCode { location, .. }
| MonomorphizationError::NoDefaultType { location, .. } => *location,
MonomorphizationError::InterpreterError(error) => error.get_location(),
}
Expand Down Expand Up @@ -51,6 +53,11 @@ impl MonomorphizationError {
"Comptime functions must be in a comptime block to be called".into();
return CustomDiagnostic::simple_error(message, secondary, location.span);
}
MonomorphizationError::ComptimeTypeInRuntimeCode { typ, location } => {
let message = format!("Comptime-only type `{typ}` used in runtime code");
let secondary = "Comptime type used here".into();
return CustomDiagnostic::simple_error(message, secondary, location.span);
}
};

let location = self.location();
Expand Down
5 changes: 4 additions & 1 deletion compiler/noirc_frontend/src/monomorphization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,10 @@ impl<'interner> Monomorphizer<'interner> {
let message = "Unexpected Type::Error found during monomorphization";
return Err(MonomorphizationError::InternalError { message, location });
}
HirType::Quoted(_) => unreachable!("Tried to translate Code type into runtime code"),
HirType::Quoted(typ) => {
let typ = typ.to_string();
return Err(MonomorphizationError::ComptimeTypeInRuntimeCode { typ, location });
}
})
}

Expand Down
14 changes: 12 additions & 2 deletions compiler/noirc_frontend/src/parser/errors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::ast::{Expression, IntegerBitSize};
use crate::lexer::errors::LexerErrorKind;
use crate::lexer::token::Token;
use crate::token::TokenKind;
use small_ord_set::SmallOrdSet;
use thiserror::Error;

Expand Down Expand Up @@ -211,8 +212,17 @@ impl<'a> From<&'a ParserError> for Diagnostic {
other => Diagnostic::simple_error(format!("{other}"), String::new(), error.span),
},
None => {
let primary = error.to_string();
Diagnostic::simple_error(primary, String::new(), error.span)
if matches!(
error.found.kind(),
TokenKind::InnerDocComment | TokenKind::OuterDocComment
) {
let primary = "This doc comment doesn't document anything".to_string();
let secondary = "Consider changing it to a regular `//` comment".to_string();
Diagnostic::simple_error(primary, secondary, error.span)
} else {
let primary = error.to_string();
Diagnostic::simple_error(primary, String::new(), error.span)
}
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions compiler/noirc_frontend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3451,3 +3451,14 @@ fn constrained_reference_to_unconstrained() {
panic!("Expected an error about passing a constrained reference to unconstrained");
};
}

#[test]
fn comptime_type_in_runtime_code() {
let source = "pub fn foo(_f: FunctionDefinition) {}";
let errors = get_program_errors(source);
assert_eq!(errors.len(), 1);
assert!(matches!(
errors[0].0,
CompilationError::ResolverError(ResolverError::ComptimeTypeInRuntimeCode { .. })
));
}
10 changes: 8 additions & 2 deletions docs/docs/noir/standard_library/meta/typed_expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ title: TypedExpr

## Methods

### as_function_definition
### get_type

#include_code as_function_definition noir_stdlib/src/meta/typed_expr.nr rust

If this expression refers to a function definitions, returns it. Otherwise returns `Option::none()`.
If this expression refers to a function definitions, returns it. Otherwise returns `Option::none()`.

### get_type

#include_code get_type noir_stdlib/src/meta/typed_expr.nr rust

Returns the type of the expression, or `Option::none()` if there were errors when the expression was previously resolved.
Loading

0 comments on commit 3eb2a5b

Please sign in to comment.