diff --git a/compiler/noirc_frontend/src/elaborator/globals.rs b/compiler/noirc_frontend/src/elaborator/globals.rs index daad421f564..c2056f308b2 100644 --- a/compiler/noirc_frontend/src/elaborator/globals.rs +++ b/compiler/noirc_frontend/src/elaborator/globals.rs @@ -21,7 +21,8 @@ //! must be elaborated first. It is assumed that the caller of this module has enforced elaborating globals in their dependency order. use crate::{ - ast::Pattern, + Type, + ast::{Pattern, UnresolvedTypeData}, hir::{def_collector::dc_crate::UnresolvedGlobal, resolution::errors::ResolverError}, hir_def::stmt::HirStatement, node_interner::{DependencyId, GlobalId, GlobalValue}, @@ -69,6 +70,11 @@ impl Elaborator<'_> { }; let location = let_stmt.pattern.location(); + let type_location = if matches!(let_stmt.r#type.typ, UnresolvedTypeData::Unspecified) { + location + } else { + let_stmt.r#type.location + }; // ABI attributes are only meaningful within contracts, so error if used elsewhere. if !self.in_contract() { @@ -98,6 +104,12 @@ impl Elaborator<'_> { self.push_err(ResolverError::ReferencesNotAllowedInGlobals { location }); } + if !let_statement.comptime && matches!(let_statement.r#type, Type::Quoted(_)) { + let typ = let_statement.r#type.to_string(); + let location = type_location; + self.push_err(ResolverError::ComptimeTypeInNonComptimeGlobal { typ, location }); + } + let let_statement = HirStatement::Let(let_statement); // Replace the placeholder statement that was created during def collection with diff --git a/compiler/noirc_frontend/src/hir/resolution/errors.rs b/compiler/noirc_frontend/src/hir/resolution/errors.rs index 706eb2876c6..fc98f9cec02 100644 --- a/compiler/noirc_frontend/src/hir/resolution/errors.rs +++ b/compiler/noirc_frontend/src/hir/resolution/errors.rs @@ -134,6 +134,8 @@ pub enum ResolverError { QuoteInRuntimeCode { location: Location }, #[error("Comptime-only type `{typ}` cannot be used in runtime code")] ComptimeTypeInRuntimeCode { typ: String, location: Location }, + #[error("Comptime-only type `{typ}` cannot be used in non-comptime global")] + ComptimeTypeInNonComptimeGlobal { typ: String, location: Location }, #[error("Comptime variable `{name}` cannot be mutated in a non-comptime context")] MutatingComptimeInNonComptimeContext { name: String, location: Location }, #[error("Failed to parse `{statement}` as an expression")] @@ -238,6 +240,7 @@ impl ResolverError { | ResolverError::BinaryOpError { location, .. } | ResolverError::QuoteInRuntimeCode { location } | ResolverError::ComptimeTypeInRuntimeCode { location, .. } + | ResolverError::ComptimeTypeInNonComptimeGlobal { location, .. } | ResolverError::MutatingComptimeInNonComptimeContext { location, .. } | ResolverError::InvalidInternedStatementInExpr { location, .. } | ResolverError::InvalidSyntaxInPattern { location } @@ -285,134 +288,132 @@ impl<'a> From<&'a ResolverError> for Diagnostic { fn from(error: &'a ResolverError) -> Diagnostic { match error { ResolverError::DuplicateDefinition { name, first_location, second_location} => { - let mut diag = Diagnostic::simple_error( - format!("duplicate definitions of {name} found"), - "second definition found here".to_string(), - *second_location, - ); - diag.add_secondary("first definition found here".to_string(), *first_location); - diag - } + let mut diag = Diagnostic::simple_error( + format!("duplicate definitions of {name} found"), + "second definition found here".to_string(), + *second_location, + ); + diag.add_secondary("first definition found here".to_string(), *first_location); + diag + } ResolverError::UnusedVariable { ident } => { - let mut diagnostic = Diagnostic::simple_warning( - format!("unused variable {ident}"), - "unused variable".to_string(), - ident.location(), - ); - diagnostic.unnecessary = true; - diagnostic - } + let mut diagnostic = Diagnostic::simple_warning( + format!("unused variable {ident}"), + "unused variable".to_string(), + ident.location(), + ); + diagnostic.unnecessary = true; + diagnostic + } ResolverError::UnusedItem { ident, item} => { - let item_type = item.item_type(); + let item_type = item.item_type(); - let mut diagnostic = - if let UnusedItem::Struct(..) = item { - Diagnostic::simple_warning( - format!("{item_type} `{ident}` is never constructed"), - format!("{item_type} is never constructed"), - ident.location(), - ) - } else { - Diagnostic::simple_warning( - format!("unused {item_type} {ident}"), - format!("unused {item_type}"), - ident.location(), - ) - }; - diagnostic.unnecessary = true; - diagnostic - } + let mut diagnostic = + if let UnusedItem::Struct(..) = item { + Diagnostic::simple_warning( + format!("{item_type} `{ident}` is never constructed"), + format!("{item_type} is never constructed"), + ident.location(), + ) + } else { + Diagnostic::simple_warning( + format!("unused {item_type} {ident}"), + format!("unused {item_type}"), + ident.location(), + ) + }; + diagnostic.unnecessary = true; + diagnostic + } ResolverError::UnconditionalRecursion { name, location} => { - Diagnostic::simple_warning( - format!("function `{name}` cannot return without recursing"), - "function cannot return without recursing".to_string(), - *location, - ) - } + Diagnostic::simple_warning( + format!("function `{name}` cannot return without recursing"), + "function cannot return without recursing".to_string(), + *location, + ) + } ResolverError::VariableNotDeclared { name, location } => { - if name == "_" { - Diagnostic::simple_error( - "in expressions, `_` can only be used on the left-hand side of an assignment".to_string(), - "`_` not allowed here".to_string(), - *location, - ) - } else { - Diagnostic::simple_error( - format!("cannot find `{name}` in this scope"), - "not found in this scope".to_string(), - *location, - ) - } - }, + if name == "_" { + Diagnostic::simple_error( + "in expressions, `_` can only be used on the left-hand side of an assignment".to_string(), + "`_` not allowed here".to_string(), + *location, + ) + } else { + Diagnostic::simple_error( + format!("cannot find `{name}` in this scope"), + "not found in this scope".to_string(), + *location, + ) + } + } ResolverError::PathResolutionError(error) => error.into(), ResolverError::Expected { location, expected, got } => Diagnostic::simple_error( - format!("expected {expected} got {got}"), - String::new(), - *location, - ), + format!("expected {expected} got {got}"), + String::new(), + *location, + ), ResolverError::DuplicateField { field } => Diagnostic::simple_error( - format!("duplicate field {field}"), - String::new(), - field.location(), - ), + format!("duplicate field {field}"), + String::new(), + field.location(), + ), ResolverError::NoSuchField { field, struct_definition } => { - Diagnostic::simple_error( - format!("no such field {field} defined in struct {struct_definition}"), - String::new(), - field.location(), - ) - } + Diagnostic::simple_error( + format!("no such field {field} defined in struct {struct_definition}"), + String::new(), + field.location(), + ) + } ResolverError::MissingFields { location, missing_fields, struct_definition } => { - let plural = if missing_fields.len() != 1 { "s" } else { "" }; - let remaining_fields_names = match &missing_fields[..] { - [field1] => field1.clone(), - [field1, field2] => format!("{field1} and {field2}"), - [field1, field2, field3] => format!("{field1}, {field2} and {field3}"), - _ => { - let len = missing_fields.len() - 3; - let len_plural = if len != 1 {"s"} else {""}; + let plural = if missing_fields.len() != 1 { "s" } else { "" }; + let remaining_fields_names = match &missing_fields[..] { + [field1] => field1.clone(), + [field1, field2] => format!("{field1} and {field2}"), + [field1, field2, field3] => format!("{field1}, {field2} and {field3}"), + _ => { + let len = missing_fields.len() - 3; + let len_plural = if len != 1 {"s"} else {""}; - let truncated_fields = format!(" and {len} other field{len_plural}"); - let missing_fields = &missing_fields[0..3]; - format!("{}{truncated_fields}", missing_fields.join(", ")) - } - }; + let truncated_fields = format!(" and {len} other field{len_plural}"); + let missing_fields = &missing_fields[0..3]; + format!("{}{truncated_fields}", missing_fields.join(", ")) + } + }; - Diagnostic::simple_error( - format!("missing field{plural} {remaining_fields_names} in struct {struct_definition}"), - String::new(), - *location, - ) - } + Diagnostic::simple_error( + format!("missing field{plural} {remaining_fields_names} in struct {struct_definition}"), + String::new(), + *location, + ) + } ResolverError::UnnecessaryMut { first_mut, second_mut } => { - let mut error = Diagnostic::simple_error( - "'mut' here is not necessary".to_owned(), - "".to_owned(), - *second_mut, - ); - error.add_secondary( - "Pattern was already made mutable from this 'mut'".to_owned(), - *first_mut, - ); - error - } + let mut error = Diagnostic::simple_error( + "'mut' here is not necessary".to_owned(), + "".to_owned(), + *second_mut, + ); + error.add_secondary( + "Pattern was already made mutable from this 'mut'".to_owned(), + *first_mut, + ); + error + } ResolverError::UnnecessaryPub { ident, position } => { - let mut diag = Diagnostic::simple_error( - format!("unnecessary pub keyword on {position} for function {ident}"), - format!("unnecessary pub {position}"), - ident.location(), - ); - - diag.add_note("The `pub` keyword only has effects on arguments to the entry-point function of a program. Thus, adding it to other function parameters can be deceiving and should be removed".to_owned()); - diag - } + let mut diag = Diagnostic::simple_error( + format!("unnecessary pub keyword on {position} for function {ident}"), + format!("unnecessary pub {position}"), + ident.location(), + ); + diag.add_note("The `pub` keyword only has effects on arguments to the entry-point function of a program. Thus, adding it to other function parameters can be deceiving and should be removed".to_owned()); + diag + } ResolverError::NecessaryPub { ident } => { - let mut diag = Diagnostic::simple_error( - format!("missing pub keyword on return type of function {ident}"), - "missing pub on return type".to_string(), - ident.location(), - ); - + let mut diag = Diagnostic::simple_error( + format!("missing pub keyword on return type of function {ident}"), + "missing pub on return type".to_string(), + ident.location(), + ); diag.add_note("The `pub` keyword is mandatory for the entry-point function return type because the verifier cannot retrieve private witness and thus the function will not be able to return a 'priv' value".to_owned()); diag } @@ -427,24 +428,25 @@ impl<'a> From<&'a ResolverError> for Diagnostic { *location, ), ResolverError::GenericsOnSelfType { location } => Diagnostic::simple_error( - "Cannot apply generics to Self type".into(), - "Use an explicit type name or apply the generics at the start of the impl instead".into(), - *location, - ), + "Cannot apply generics to Self type".into(), + "Use an explicit type name or apply the generics at the start of the impl instead".into(), + *location, + ), ResolverError::GenericsOnAssociatedType { location } => Diagnostic::simple_error( - "Generic Associated Types (GATs) are currently unsupported in Noir".into(), - "Cannot apply generics to an associated type".into(), - *location, - ), + "Generic Associated Types (GATs) are currently unsupported in Noir".into(), + "Cannot apply generics to an associated type".into(), + *location, + ), ResolverError::ParserError(error) => error.as_ref().into(), ResolverError::InvalidClosureEnvironment { location, typ } => Diagnostic::simple_error( - format!("{typ} is not a valid closure environment type"), - "Closure environment must be a tuple or unit type".to_string(), *location), + format!("{typ} is not a valid closure environment type"), + "Closure environment must be a tuple or unit type".to_string(), *location + ), ResolverError::NestedSlices { location } => Diagnostic::simple_error( - "Nested slices, i.e. slices within an array or slice, are not supported".into(), - "Try to use a constant sized array or BoundedVec instead".into(), - *location, - ), + "Nested slices, i.e. slices within an array or slice, are not supported".into(), + "Try to use a constant sized array or BoundedVec instead".into(), + *location, + ), ResolverError::AbiAttributeOutsideContract { location } => { Diagnostic::simple_error( "#[abi(tag)] attributes can only be used in contracts".to_string(), @@ -467,84 +469,84 @@ impl<'a> From<&'a ResolverError> for Diagnostic { diagnostic }, ResolverError::UnconstrainedOracleReturnToConstrained { location } => Diagnostic::simple_error( - error.to_string(), - "This oracle call must be wrapped in a call to another unconstrained function before being returned to a constrained runtime".into(), - *location, - ), + error.to_string(), + "This oracle call must be wrapped in a call to another unconstrained function before being returned to a constrained runtime".into(), + *location, + ), ResolverError::DependencyCycle { location, item, cycle } => { - Diagnostic::simple_error( - "Dependency cycle found".into(), - format!("'{item}' recursively depends on itself: {cycle}"), - *location, - ) - }, + Diagnostic::simple_error( + "Dependency cycle found".into(), + format!("'{item}' recursively depends on itself: {cycle}"), + *location, + ) + }, ResolverError::JumpInConstrainedFn { is_break, location } => { - let item = if *is_break { "break" } else { "continue" }; - Diagnostic::simple_error( - format!("{item} is only allowed in unconstrained functions"), - "Constrained code must always have a known number of loop iterations".into(), - *location, - ) - }, + let item = if *is_break { "break" } else { "continue" }; + Diagnostic::simple_error( + format!("{item} is only allowed in unconstrained functions"), + "Constrained code must always have a known number of loop iterations".into(), + *location, + ) + }, ResolverError::LoopInConstrainedFn { location } => { - Diagnostic::simple_error( - "`loop` is only allowed in unconstrained functions".into(), - "Constrained code must always have a known number of loop iterations".into(), - *location, - ) - }, + Diagnostic::simple_error( + "`loop` is only allowed in unconstrained functions".into(), + "Constrained code must always have a known number of loop iterations".into(), + *location, + ) + }, ResolverError::LoopWithoutBreak { location } => { - Diagnostic::simple_error( - "`loop` must have at least one `break` in it".into(), - "Infinite loops are disallowed".into(), - *location, - ) - }, + Diagnostic::simple_error( + "`loop` must have at least one `break` in it".into(), + "Infinite loops are disallowed".into(), + *location, + ) + }, ResolverError::WhileInConstrainedFn { location } => { - Diagnostic::simple_error( - "`while` is only allowed in unconstrained functions".into(), - "Constrained code must always have a known number of loop iterations".into(), - *location, - ) - }, + Diagnostic::simple_error( + "`while` is only allowed in unconstrained functions".into(), + "Constrained code must always have a known number of loop iterations".into(), + *location, + ) + }, ResolverError::JumpOutsideLoop { is_break, location } => { - let item = if *is_break { "break" } else { "continue" }; - Diagnostic::simple_error( - format!("{item} is only allowed within loops"), - "".into(), - *location, - ) - }, + let item = if *is_break { "break" } else { "continue" }; + Diagnostic::simple_error( + format!("{item} is only allowed within loops"), + "".into(), + *location, + ) + }, ResolverError::MutableGlobal { location } => { - Diagnostic::simple_error( - "Only `comptime` globals may be mutable".into(), - String::new(), - *location, - ) - }, + Diagnostic::simple_error( + "Only `comptime` globals may be mutable".into(), + String::new(), + *location, + ) + }, ResolverError::UnspecifiedGlobalType { pattern_location, expr_location, expected_type } => { - let mut diagnostic = Diagnostic::simple_error( - "Globals must have a specified type".to_string(), - String::new(), - *pattern_location, - ); - diagnostic.add_secondary(format!("Inferred type is `{expected_type}`"), *expr_location); - diagnostic - }, + let mut diagnostic = Diagnostic::simple_error( + "Globals must have a specified type".to_string(), + String::new(), + *pattern_location, + ); + diagnostic.add_secondary(format!("Inferred type is `{expected_type}`"), *expr_location); + diagnostic + }, ResolverError::UnevaluatedGlobalType { location } => { - Diagnostic::simple_error( - "Global failed to evaluate".to_string(), - String::new(), - *location, - ) - } + Diagnostic::simple_error( + "Global failed to evaluate".to_string(), + String::new(), + *location, + ) + } ResolverError::NegativeGlobalType { location, global_value } => { - Diagnostic::simple_error( - "Globals used in a type position must be non-negative".to_string(), - format!("But found value `{global_value:?}`"), - *location, - ) - } + Diagnostic::simple_error( + "Globals used in a type position must be non-negative".to_string(), + format!("But found value `{global_value:?}`"), + *location, + ) + } ResolverError::NonIntegralGlobalType { location, global_value } => { Diagnostic::simple_error( "Globals used in a type position must be integers".to_string(), @@ -587,89 +589,96 @@ impl<'a> From<&'a ResolverError> for Diagnostic { diag } ResolverError::UnquoteUsedOutsideQuote { location } => { - Diagnostic::simple_error( - "The unquote operator '$' can only be used within a quote expression".into(), - "".into(), - *location, - ) - }, + Diagnostic::simple_error( + "The unquote operator '$' can only be used within a quote expression".into(), + "".into(), + *location, + ) + }, ResolverError::InvalidSyntaxInMacroCall { location } => { - Diagnostic::simple_error( - "Invalid syntax in macro call".into(), - "Macro calls must call a comptime function directly, they cannot use higher-order functions".into(), - *location, - ) - }, + Diagnostic::simple_error( + "Invalid syntax in macro call".into(), + "Macro calls must call a comptime function directly, they cannot use higher-order functions".into(), + *location, + ) + }, ResolverError::MacroIsNotComptime { location } => { - Diagnostic::simple_error( - "This macro call is to a non-comptime function".into(), - "Macro calls must be to comptime functions".into(), - *location, - ) - }, + Diagnostic::simple_error( + "This macro call is to a non-comptime function".into(), + "Macro calls must be to comptime functions".into(), + *location, + ) + }, ResolverError::NonFunctionInAnnotation { location } => { - Diagnostic::simple_error( - "Unknown annotation".into(), - "The name of an annotation must refer to a comptime function".into(), - *location, - ) - }, + Diagnostic::simple_error( + "Unknown annotation".into(), + "The name of an annotation must refer to a comptime function".into(), + *location, + ) + }, ResolverError::MacroResultInGenericsListNotAGeneric { location, typ } => { - Diagnostic::simple_error( - format!("Type `{typ}` was inserted into a generics list from a macro, but it is not a generic"), - format!("Type `{typ}` is not a generic"), - *location, - ) - } + Diagnostic::simple_error( + format!("Type `{typ}` was inserted into a generics list from a macro, but it is not a generic"), + format!("Type `{typ}` is not a generic"), + *location, + ) + } ResolverError::NamedTypeArgs { location, item_kind } => { - Diagnostic::simple_error( - format!("Named type arguments aren't allowed on a {item_kind}"), - "Named type arguments are only allowed for associated types on traits".to_string(), - *location, - ) - } + Diagnostic::simple_error( + format!("Named type arguments aren't allowed on a {item_kind}"), + "Named type arguments are only allowed for associated types on traits".to_string(), + *location, + ) + } ResolverError::AssociatedConstantsMustBeNumeric { location } => { - Diagnostic::simple_error( - "Associated constants may only be a field or integer type".to_string(), - "Only numeric constants are allowed".to_string(), - *location, - ) - } + Diagnostic::simple_error( + "Associated constants may only be a field or integer type".to_string(), + "Only numeric constants are allowed".to_string(), + *location, + ) + } ResolverError::BinaryOpError { lhs, op, rhs, err, location } => { - Diagnostic::simple_error( - format!("Computing `{lhs} {op} {rhs}` failed with error {err}"), - String::new(), - *location, - ) - } + Diagnostic::simple_error( + format!("Computing `{lhs} {op} {rhs}` failed with error {err}"), + String::new(), + *location, + ) + } ResolverError::QuoteInRuntimeCode { location } => { - Diagnostic::simple_error( - "`quote` cannot be used in runtime code".to_string(), - "Wrap this in a `comptime` block or function to use it".to_string(), - *location, - ) - }, + Diagnostic::simple_error( + "`quote` cannot be used in runtime code".to_string(), + "Wrap this in a `comptime` block or function to use it".to_string(), + *location, + ) + }, ResolverError::ComptimeTypeInRuntimeCode { typ, location } => { - Diagnostic::simple_error( - format!("Comptime-only type `{typ}` cannot be used in runtime code"), - "Comptime-only type used here".to_string(), - *location, - ) - }, + Diagnostic::simple_error( + format!("Comptime-only type `{typ}` cannot be used in runtime code"), + "Comptime-only type used here".to_string(), + *location, + ) + }, + ResolverError::ComptimeTypeInNonComptimeGlobal { typ, location } => { + Diagnostic::simple_error( + format!("Comptime-only type `{typ}` cannot be used in non-comptime global"), + "Comptime-only type used here".to_string(), + *location, + ) + }, ResolverError::MutatingComptimeInNonComptimeContext { name, location } => { - Diagnostic::simple_error( - format!("Comptime variable `{name}` cannot be mutated in a non-comptime context"), - format!("`{name}` mutated here"), - *location, - ) - }, + Diagnostic::simple_error( + format!("Comptime variable `{name}` cannot be mutated in a non-comptime context"), + format!("`{name}` mutated here"), + *location, + ) + }, ResolverError::InvalidInternedStatementInExpr { statement, location } => { - Diagnostic::simple_error( - format!("Failed to parse `{statement}` as an expression"), - "The statement was used from a macro here".to_string(), - *location, - ) - }, + Diagnostic::simple_error( + format!("Failed to parse `{statement}` as an expression"), + "The statement was used from a macro here".to_string(), + *location, + ) + }, ResolverError::UnsupportedNumericGenericType(err) => err.into(), ResolverError::TypeIsMorePrivateThenItem { typ, item, location } => { Diagnostic::simple_error( @@ -679,19 +688,19 @@ impl<'a> From<&'a ResolverError> for Diagnostic { ) }, ResolverError::AttributeFunctionIsNotAPath { function, location } => { - Diagnostic::simple_error( - format!("Attribute function `{function}` is not a path"), - "An attribute's function should be a single identifier or a path".into(), - *location, - ) - }, + Diagnostic::simple_error( + format!("Attribute function `{function}` is not a path"), + "An attribute's function should be a single identifier or a path".into(), + *location, + ) + }, ResolverError::AttributeFunctionNotInScope { name, location } => { - Diagnostic::simple_error( - format!("Attribute function `{name}` is not in scope"), - String::new(), - *location, - ) - }, + Diagnostic::simple_error( + format!("Attribute function `{name}` is not in scope"), + String::new(), + *location, + ) + }, ResolverError::TraitNotImplemented { impl_trait, missing_trait: the_trait, type_missing_trait: typ, location, missing_trait_location} => { let mut diagnostic = Diagnostic::simple_error( format!("The trait bound `{typ}: {the_trait}` is not satisfied"), @@ -701,58 +710,59 @@ impl<'a> From<&'a ResolverError> for Diagnostic { diagnostic }, ResolverError::ExpectedTrait { found, location } => { - Diagnostic::simple_error( - format!("Expected a trait, found {found}"), - String::new(), - *location) - - } + Diagnostic::simple_error( + format!("Expected a trait, found {found}"), + String::new(), + *location, + ) + } ResolverError::InvalidSyntaxInPattern { location } => { - Diagnostic::simple_error( - "Invalid syntax in match pattern".into(), - "Only literal, constructor, and variable patterns are allowed".into(), - *location) - }, + Diagnostic::simple_error( + "Invalid syntax in match pattern".into(), + "Only literal, constructor, and variable patterns are allowed".into(), + *location, + ) + }, ResolverError::VariableAlreadyDefinedInPattern { existing, new_location } => { - let message = format!("Variable `{existing}` was already defined in the same match pattern"); - let secondary = format!("`{existing}` redefined here"); - let mut error = Diagnostic::simple_error(message, secondary, *new_location); - error.add_secondary(format!("`{existing}` was previously defined here"), existing.location()); - error - }, + let message = format!("Variable `{existing}` was already defined in the same match pattern"); + let secondary = format!("`{existing}` redefined here"); + let mut error = Diagnostic::simple_error(message, secondary, *new_location); + error.add_secondary(format!("`{existing}` was previously defined here"), existing.location()); + error + }, ResolverError::NonIntegerGlobalUsedInPattern { location } => { - let message = "Only integer or boolean globals can be used in match patterns".to_string(); - let secondary = "This global is not an integer or boolean".to_string(); - Diagnostic::simple_error(message, secondary, *location) - }, + let message = "Only integer or boolean globals can be used in match patterns".to_string(); + let secondary = "This global is not an integer or boolean".to_string(); + Diagnostic::simple_error(message, secondary, *location) + }, ResolverError::TypeUnsupportedInMatch { typ, location } => { - Diagnostic::simple_error( - format!("Cannot match on values of type `{typ}`"), - String::new(), - *location, - ) - }, + Diagnostic::simple_error( + format!("Cannot match on values of type `{typ}`"), + String::new(), + *location, + ) + }, ResolverError::UnexpectedItemInPattern { item, location } => { - Diagnostic::simple_error( - format!("Expected a struct, enum, or literal pattern, but found a {item}"), - String::new(), - *location, - ) - }, + Diagnostic::simple_error( + format!("Expected a struct, enum, or literal pattern, but found a {item}"), + String::new(), + *location, + ) + }, ResolverError::NoSuchMethodInTrait { trait_name, method_name, location } => { - Diagnostic::simple_error( - format!("Trait `{trait_name}` has no method named `{method_name}`"), - String::new(), - *location, - ) - }, + Diagnostic::simple_error( + format!("Trait `{trait_name}` has no method named `{method_name}`"), + String::new(), + *location, + ) + }, ResolverError::RecursiveTypeAlias { location } => { - Diagnostic::simple_error( - "Cannot use a type alias inside a type alias".to_string(), - String::new(), - *location, - ) - }, + Diagnostic::simple_error( + "Cannot use a type alias inside a type alias".to_string(), + String::new(), + *location, + ) + }, ResolverError::ExpectedNumericExpression { typ, location } => { Diagnostic::simple_error( format!("Expected a numeric expression, but got `{typ}`"), diff --git a/test_programs/compile_failure/regression_10365/Nargo.toml b/test_programs/compile_failure/regression_10365/Nargo.toml new file mode 100644 index 00000000000..f20ab48dba2 --- /dev/null +++ b/test_programs/compile_failure/regression_10365/Nargo.toml @@ -0,0 +1,6 @@ +[package] +name = "regression_10365" +type = "bin" +authors = [""] + +[dependencies] diff --git a/test_programs/compile_failure/regression_10365/src/main.nr b/test_programs/compile_failure/regression_10365/src/main.nr new file mode 100644 index 00000000000..048c425ab70 --- /dev/null +++ b/test_programs/compile_failure/regression_10365/src/main.nr @@ -0,0 +1,5 @@ +global foo: Quoted = quote { 1}; + +fn main() { + let _ = foo; +} diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/regression_10365/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/regression_10365/execute__tests__stderr.snap new file mode 100644 index 00000000000..35b98b023bd --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/regression_10365/execute__tests__stderr.snap @@ -0,0 +1,12 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: stderr +--- +error: Comptime-only type `Quoted` cannot be used in non-comptime global + ┌─ src/main.nr:1:13 + │ +1 │ global foo: Quoted = quote { 1}; + │ ------ Comptime-only type used here + │ + +Aborting due to 1 previous error