diff --git a/.github/critical_libraries_status/teddav/tdd.nr/.failures.jsonl b/.github/critical_libraries_status/teddav/tdd.nr/.failures.jsonl.does_not_compile similarity index 100% rename from .github/critical_libraries_status/teddav/tdd.nr/.failures.jsonl rename to .github/critical_libraries_status/teddav/tdd.nr/.failures.jsonl.does_not_compile diff --git a/compiler/noirc_frontend/src/elaborator/comptime.rs b/compiler/noirc_frontend/src/elaborator/comptime.rs index fdf27eb8530..abbd8e28385 100644 --- a/compiler/noirc_frontend/src/elaborator/comptime.rs +++ b/compiler/noirc_frontend/src/elaborator/comptime.rs @@ -24,7 +24,7 @@ use crate::{ token::{MetaAttribute, MetaAttributeName, SecondaryAttribute, SecondaryAttributeKind}, }; -use super::{ElaborateReason, Elaborator, FunctionContext, ResolverMeta}; +use super::{ElaborateReason, Elaborator, ResolverMeta}; #[derive(Debug, Copy, Clone)] struct AttributeContext { @@ -96,7 +96,7 @@ impl<'context> Elaborator<'context> { self.elaborate_reasons.clone(), ); - elaborator.function_context.push(FunctionContext::default()); + elaborator.push_function_context(); elaborator.scopes.start_function(); elaborator.local_module = self.local_module; @@ -644,7 +644,7 @@ impl<'context> Elaborator<'context> { // in this comptime block early before the function as a whole finishes elaborating. // Otherwise the interpreter below may find expressions for which the underlying trait // call is not yet solved for. - self.function_context.push(Default::default()); + self.push_function_context(); let result = f(self); diff --git a/compiler/noirc_frontend/src/elaborator/expressions.rs b/compiler/noirc_frontend/src/elaborator/expressions.rs index 3df061157c8..f3925208fec 100644 --- a/compiler/noirc_frontend/src/elaborator/expressions.rs +++ b/compiler/noirc_frontend/src/elaborator/expressions.rs @@ -4,7 +4,7 @@ use noirc_errors::{Located, Location}; use rustc_hash::FxHashSet as HashSet; use crate::{ - DataType, Kind, QuotedType, Shared, Type, + DataType, Kind, QuotedType, Shared, Type, TypeVariable, ast::{ ArrayLiteral, AsTraitPath, BinaryOpKind, BlockExpression, CallExpression, CastExpression, ConstrainExpression, ConstrainKind, ConstructorExpression, Expression, ExpressionKind, @@ -41,6 +41,7 @@ use crate::{ use super::{ Elaborator, LambdaContext, UnsafeBlockStatus, UnstableFeature, + function_context::BindableTypeVariableKind, path_resolution::{TypedPath, TypedPathSegment}, }; @@ -278,7 +279,16 @@ impl Elaborator<'_> { ) -> (HirExpression, Type) { let (expr, elem_type, length) = match array_literal { ArrayLiteral::Standard(elements) => { - let first_elem_type = self.interner.next_type_variable(); + let type_variable_id = self.interner.next_type_variable_id(); + let type_variable = TypeVariable::unbound(type_variable_id, Kind::Any); + self.push_required_type_variable( + type_variable.id(), + Type::TypeVariable(type_variable.clone()), + BindableTypeVariableKind::ArrayLiteral { is_array }, + location, + ); + + let first_elem_type = Type::TypeVariable(type_variable); let first_location = elements.first().map(|elem| elem.location).unwrap_or(location); let elements = vecmap(elements.into_iter().enumerate(), |(i, elem)| { @@ -852,6 +862,19 @@ impl Elaborator<'_> { ); } + // Each of the struct generics must be bound at the end of the function + let struct_id = r#type.borrow().id; + for (index, generic) in generics.iter().enumerate() { + if let Type::TypeVariable(type_variable) = generic { + self.push_required_type_variable( + type_variable.id(), + Type::TypeVariable(type_variable.clone()), + BindableTypeVariableKind::StructGeneric { struct_id, index }, + location, + ); + } + } + let struct_type = r#type.clone(); let field_types = r#type diff --git a/compiler/noirc_frontend/src/elaborator/function_context.rs b/compiler/noirc_frontend/src/elaborator/function_context.rs new file mode 100644 index 00000000000..e2914a64a2e --- /dev/null +++ b/compiler/noirc_frontend/src/elaborator/function_context.rs @@ -0,0 +1,273 @@ +use noirc_errors::Location; + +use crate::{ + Kind, Type, + elaborator::lints::check_integer_literal_fits_its_type, + hir::{comptime::Value, type_check::TypeCheckError}, + hir_def::traits::TraitConstraint, + node_interner::{DefinitionKind, ExprId, GlobalValue, TypeId}, +}; +use crate::{TypeVariableId, node_interner::DefinitionId}; + +use super::Elaborator; + +#[derive(Default)] +pub(super) struct FunctionContext { + /// All type variables created in the current function. + /// This map is used to default any integer type variables at the end of + /// a function (before checking trait constraints) if a type wasn't already chosen. + defaultable_type_variables: Vec, + + /// Type variables that must be bound at the end of the function. + required_type_variables: Vec, + + /// Trait constraints are collected during type checking until they are + /// verified at the end of a function. This is because constraints arise + /// on each variable, but it is only until function calls when the types + /// needed for the trait constraint may become known. + /// The `select impl` bool indicates whether, after verifying the trait constraint, + /// the resulting trait impl should be the one used for a call (sometimes trait + /// constraints are verified but there's no call associated with them, like in the + /// case of checking generic arguments) + trait_constraints: Vec<(TraitConstraint, ExprId, bool /* select impl */)>, + + /// All ExprId in a function that correspond to integer literals. + /// At the end, if they don't fit in their type's min/max range, we'll produce an error. + integer_literal_expr_ids: Vec, +} + +/// A type variable that is required to be bound after type-checking a function. +struct RequiredTypeVariable { + type_variable_id: TypeVariableId, + typ: Type, + kind: BindableTypeVariableKind, + location: Location, +} + +/// The kind of required type variable. +#[derive(Debug, Copy, Clone)] +pub(super) enum BindableTypeVariableKind { + /// The type variable corresponds to a struct generic, in a constructor. + StructGeneric { struct_id: TypeId, index: usize }, + /// The type variable corresponds to the type of an array literal. + ArrayLiteral { is_array: bool }, + /// The type variable corresponds to an identifier, whose definition ID is the given one. + Ident(DefinitionId), +} + +impl Elaborator<'_> { + /// Push a type variable into the current FunctionContext to be defaulted if needed + /// at the end of the earlier of either the current function or the current comptime scope. + pub(super) fn push_defaultable_type_variable(&mut self, typ: Type) { + self.get_function_context_mut().defaultable_type_variables.push(typ); + } + + /// Push a type variable (its ID and type) as a required type variable: it must be + /// bound after type-checking the current function. + pub(super) fn push_required_type_variable( + &mut self, + type_variable_id: TypeVariableId, + typ: Type, + kind: BindableTypeVariableKind, + location: Location, + ) { + let var = RequiredTypeVariable { type_variable_id, typ, kind, location }; + self.get_function_context_mut().required_type_variables.push(var); + } + + /// Push a trait constraint into the current FunctionContext to be solved if needed + /// at the end of the earlier of either the current function or the current comptime scope. + pub(super) fn push_trait_constraint( + &mut self, + constraint: TraitConstraint, + expr_id: ExprId, + select_impl: bool, + ) { + self.get_function_context_mut().trait_constraints.push((constraint, expr_id, select_impl)); + } + + /// Push an `ExprId` that corresponds to an integer literal. + /// At the end of the current function we'll check that they fit in their type's range. + pub fn push_integer_literal_expr_id(&mut self, literal_expr_id: ExprId) { + self.get_function_context_mut().integer_literal_expr_ids.push(literal_expr_id); + } + + fn get_function_context_mut(&mut self) -> &mut FunctionContext { + let context = self.function_context.last_mut(); + context.expect("The function_context stack should always be non-empty") + } + + pub(super) fn push_function_context(&mut self) { + self.function_context.push(FunctionContext::default()); + } + + /// Defaults all type variables used in this function context then solves + /// all still-unsolved trait constraints in this context. + pub(super) fn check_and_pop_function_context(&mut self) { + let context = self.function_context.pop().expect("Imbalanced function_context pushes"); + self.check_defaultable_type_variables(context.defaultable_type_variables); + self.check_integer_literal_fit_their_type(context.integer_literal_expr_ids); + self.check_trait_constraints(context.trait_constraints); + self.check_required_type_variables(context.required_type_variables); + } + + fn check_defaultable_type_variables(&self, type_variables: Vec) { + for typ in type_variables { + if let Type::TypeVariable(variable) = typ.follow_bindings() { + let msg = "TypeChecker should only track defaultable type vars"; + variable.bind(variable.kind().default_type().expect(msg)); + } + } + } + + fn check_integer_literal_fit_their_type(&mut self, expr_ids: Vec) { + for expr_id in expr_ids { + if let Some(error) = check_integer_literal_fits_its_type(self.interner, &expr_id) { + self.push_err(error); + } + } + } + + fn check_trait_constraints(&mut self, trait_constraints: Vec<(TraitConstraint, ExprId, bool)>) { + for (mut constraint, expr_id, select_impl) in trait_constraints { + let location = self.interner.expr_location(&expr_id); + + if matches!(&constraint.typ, Type::Reference(..)) { + let (_, dereferenced_typ) = + self.insert_auto_dereferences(expr_id, constraint.typ.clone()); + constraint.typ = dereferenced_typ; + } + + self.verify_trait_constraint( + &constraint.typ, + constraint.trait_bound.trait_id, + &constraint.trait_bound.trait_generics.ordered, + &constraint.trait_bound.trait_generics.named, + expr_id, + select_impl, + location, + ); + } + } + + fn check_required_type_variables(&mut self, type_variables: Vec) { + for var in type_variables { + let id = var.type_variable_id; + if let Type::TypeVariable(_) = var.typ.follow_bindings() { + let location = var.location; + match var.kind { + BindableTypeVariableKind::StructGeneric { struct_id, index } => { + let data_type = self.interner.get_type(struct_id); + let generic = &data_type.borrow().generics[index]; + let generic_name = generic.name.to_string(); + let item_kind = "struct"; + let item_name = data_type.borrow().name.to_string(); + let is_numeric = matches!(generic.type_var.kind(), Kind::Numeric(..)); + self.push_err(TypeCheckError::TypeAnnotationNeededOnItem { + location, + generic_name, + item_kind, + item_name, + is_numeric, + }); + } + BindableTypeVariableKind::ArrayLiteral { is_array } => { + self.push_err(TypeCheckError::TypeAnnotationNeededOnArrayLiteral { + location, + is_array, + }); + } + BindableTypeVariableKind::Ident(definition_id) => { + let definition = self.interner.definition(definition_id); + let definition_kind = definition.kind.clone(); + match definition_kind { + DefinitionKind::Function(func_id) => { + // Try to find the type variable in the function's generic arguments + let mut direct_generics = + self.interner.function_meta(&func_id).direct_generics.iter(); + let generic = + direct_generics.find(|generic| generic.type_var.id() == id); + if let Some(generic) = generic { + let item_name = + self.interner.definition_name(definition_id).to_string(); + let is_numeric = + matches!(generic.type_var.kind(), Kind::Numeric(..)); + self.push_err(TypeCheckError::TypeAnnotationNeededOnItem { + location, + generic_name: generic.name.to_string(), + item_kind: "function", + item_name, + is_numeric, + }); + continue; + } + + // If we find one in `all_generics` it means it's a generic on the type + // the function is in. + let Some(Type::DataType(typ, ..)) = + &self.interner.function_meta(&func_id).self_type + else { + continue; + }; + let typ = typ.borrow(); + let item_name = typ.name.to_string(); + let item_kind = if typ.is_struct() { "struct" } else { "enum" }; + drop(typ); + + let mut all_generics = + self.interner.function_meta(&func_id).all_generics.iter(); + let generic = + all_generics.find(|generic| generic.type_var.id() == id); + if let Some(generic) = generic { + let is_numeric = + matches!(generic.type_var.kind(), Kind::Numeric(..)); + self.push_err(TypeCheckError::TypeAnnotationNeededOnItem { + location, + generic_name: generic.name.to_string(), + item_kind, + item_name: item_name.clone(), + is_numeric, + }); + } + } + DefinitionKind::Global(global_id) => { + // Check if this global points to an enum variant, then get the enum's generics + // and find the type variable there. + let global = self.interner.get_global(global_id); + let GlobalValue::Resolved(Value::Enum(_, _, Type::Forall(_, typ))) = + &global.value + else { + continue; + }; + + let typ: &Type = typ; + let Type::DataType(def, _) = typ else { + continue; + }; + + let def = def.borrow(); + let item_name = def.name.to_string(); + let mut generics = def.generics.iter(); + let generic = + generics.find(|generic| generic.type_var.id() == id).cloned(); + drop(def); + if let Some(generic) = generic { + let is_numeric = + matches!(generic.type_var.kind(), Kind::Numeric(..)); + self.push_err(TypeCheckError::TypeAnnotationNeededOnItem { + location, + generic_name: generic.name.to_string(), + item_kind: "enum", + item_name: item_name.clone(), + is_numeric, + }); + } + } + _ => (), + } + } + } + } + } + } +} diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index 7621a7309ca..57f62f2870a 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -7,7 +7,6 @@ use std::{ use crate::{ DataType, NamedGeneric, StructField, TypeBindings, ast::{ItemVisibility, UnresolvedType}, - elaborator::lints::check_integer_literal_fits_its_type, graph::CrateGraph, hir::def_collector::dc_crate::UnresolvedTrait, hir_def::traits::ResolvedTraitBound, @@ -46,7 +45,7 @@ use crate::{ types::{Generics, Kind, ResolvedGeneric}, }, node_interner::{ - DefinitionKind, DependencyId, ExprId, FuncId, FunctionModifiers, GlobalId, NodeInterner, + DefinitionKind, DependencyId, FuncId, FunctionModifiers, GlobalId, NodeInterner, ReferenceId, TraitId, TraitImplId, TypeAliasId, TypeId, }, parser::{ParserError, ParserErrorReason}, @@ -55,6 +54,7 @@ use crate::{ mod comptime; mod enums; mod expressions; +mod function_context; mod lints; mod options; mod path_resolution; @@ -67,6 +67,7 @@ mod traits; pub mod types; mod unquote; +use function_context::FunctionContext; use fxhash::FxHashMap as HashMap; use im::HashSet; use iter_extended::vecmap; @@ -235,28 +236,6 @@ impl ElaborateReason { } } -#[derive(Default)] -struct FunctionContext { - /// All type variables created in the current function. - /// This map is used to default any integer type variables at the end of - /// a function (before checking trait constraints) if a type wasn't already chosen. - type_variables: Vec, - - /// Trait constraints are collected during type checking until they are - /// verified at the end of a function. This is because constraints arise - /// on each variable, but it is only until function calls when the types - /// needed for the trait constraint may become known. - /// The `select impl` bool indicates whether, after verifying the trait constraint, - /// the resulting trait impl should be the one used for a call (sometimes trait - /// constraints are verified but there's no call associated with them, like in the - /// case of checking generic arguments) - trait_constraints: Vec<(TraitConstraint, ExprId, bool /* select impl */)>, - - /// All ExprId in a function that correspond to integer literals. - /// At the end, if they don't fit in their type's min/max range, we'll produce an error. - integer_literal_expr_ids: Vec, -} - impl<'context> Elaborator<'context> { #[allow(clippy::too_many_arguments)] pub fn new( @@ -484,7 +463,7 @@ impl<'context> Elaborator<'context> { let old_item = self.current_item.replace(DependencyId::Function(id)); self.trait_bounds = func_meta.all_trait_constraints().cloned().collect(); - self.function_context.push(FunctionContext::default()); + self.push_function_context(); let modifiers = self.interner.function_modifiers(&id).clone(); @@ -588,45 +567,6 @@ impl<'context> Elaborator<'context> { self.current_item = old_item; } - /// Defaults all type variables used in this function context then solves - /// all still-unsolved trait constraints in this context. - fn check_and_pop_function_context(&mut self) { - let context = self.function_context.pop().expect("Imbalanced function_context pushes"); - - for typ in context.type_variables { - if let Type::TypeVariable(variable) = typ.follow_bindings() { - let msg = "TypeChecker should only track defaultable type vars"; - variable.bind(variable.kind().default_type().expect(msg)); - } - } - - for expr_id in context.integer_literal_expr_ids { - if let Some(error) = check_integer_literal_fits_its_type(self.interner, &expr_id) { - self.push_err(error); - } - } - - for (mut constraint, expr_id, select_impl) in context.trait_constraints { - let location = self.interner.expr_location(&expr_id); - - if matches!(&constraint.typ, Type::Reference(..)) { - let (_, dereferenced_typ) = - self.insert_auto_dereferences(expr_id, constraint.typ.clone()); - constraint.typ = dereferenced_typ; - } - - self.verify_trait_constraint( - &constraint.typ, - constraint.trait_bound.trait_id, - &constraint.trait_bound.trait_generics.ordered, - &constraint.trait_bound.trait_generics.named, - expr_id, - select_impl, - location, - ); - } - } - /// This turns function parameters of the form: /// `fn foo(x: impl Bar)` /// diff --git a/compiler/noirc_frontend/src/elaborator/patterns.rs b/compiler/noirc_frontend/src/elaborator/patterns.rs index dd533cbafb2..706936a61ab 100644 --- a/compiler/noirc_frontend/src/elaborator/patterns.rs +++ b/compiler/noirc_frontend/src/elaborator/patterns.rs @@ -30,6 +30,7 @@ use crate::{ use super::{ Elaborator, ResolverMeta, + function_context::BindableTypeVariableKind, path_resolution::{PathResolutionItem, TypedPath, TypedPathSegment}, }; @@ -630,7 +631,15 @@ impl Elaborator<'_> { let id = self.interner.push_expr(HirExpression::Ident(expr.clone(), generics.clone())); self.interner.push_expr_location(id, location); - let typ = self.type_check_variable_with_bindings(expr, id, generics, bindings); + // TODO: set this to `true`. See https://github.com/noir-lang/noir/issues/8687 + let push_required_type_variables = self.current_trait.is_none(); + let typ = self.type_check_variable_with_bindings( + expr, + id, + generics, + bindings, + push_required_type_variables, + ); self.interner.push_expr_type(id, typ.clone()); // If this variable it a comptime local variable, use its current value as the final expression @@ -974,15 +983,24 @@ impl Elaborator<'_> { generics: Option>, ) -> Type { let bindings = TypeBindings::default(); - self.type_check_variable_with_bindings(ident, expr_id, generics, bindings) + // TODO: set this to `true`. See https://github.com/noir-lang/noir/issues/8687 + let push_required_type_variables = self.current_trait.is_none(); + self.type_check_variable_with_bindings( + ident, + expr_id, + generics, + bindings, + push_required_type_variables, + ) } - pub(super) fn type_check_variable_with_bindings( + pub(crate) fn type_check_variable_with_bindings( &mut self, ident: HirIdent, expr_id: ExprId, generics: Option>, mut bindings: TypeBindings, + push_required_type_variables: bool, ) -> Type { // Add type bindings from any constraints that were used. // We need to do this first since otherwise instantiating the type below @@ -1054,6 +1072,17 @@ impl Elaborator<'_> { } } + if push_required_type_variables { + for (type_variable, _kind, typ) in bindings.values() { + self.push_required_type_variable( + type_variable.id(), + typ.clone(), + BindableTypeVariableKind::Ident(ident.id), + ident.location, + ); + } + } + self.interner.store_instantiation_bindings(expr_id, bindings); typ } diff --git a/compiler/noirc_frontend/src/elaborator/types.rs b/compiler/noirc_frontend/src/elaborator/types.rs index cf9cf382347..a51da20b35e 100644 --- a/compiler/noirc_frontend/src/elaborator/types.rs +++ b/compiler/noirc_frontend/src/elaborator/types.rs @@ -41,7 +41,7 @@ use crate::{ }; use super::{ - Elaborator, FunctionContext, PathResolutionTarget, UnsafeBlockStatus, lints, + Elaborator, PathResolutionTarget, UnsafeBlockStatus, lints, path_resolution::{PathResolutionItem, PathResolutionMode, TypedPath}, }; @@ -947,7 +947,7 @@ impl Elaborator<'_> { /// in self.type_variables to default it later. pub(super) fn polymorphic_integer_or_field(&mut self) -> Type { let typ = Type::polymorphic_integer_or_field(self.interner); - self.push_type_variable(typ.clone()); + self.push_defaultable_type_variable(typ.clone()); typ } @@ -955,7 +955,7 @@ impl Elaborator<'_> { /// in self.type_variables to default it later. pub(super) fn polymorphic_integer(&mut self) -> Type { let typ = Type::polymorphic_integer(self.interner); - self.push_type_variable(typ.clone()); + self.push_defaultable_type_variable(typ.clone()); typ } @@ -963,7 +963,7 @@ impl Elaborator<'_> { /// in self.type_variables to default it later. pub(super) fn type_variable_with_kind(&mut self, type_var_kind: Kind) -> Type { let typ = Type::type_variable_with_kind(self.interner, type_var_kind); - self.push_type_variable(typ.clone()); + self.push_defaultable_type_variable(typ.clone()); typ } @@ -2248,34 +2248,6 @@ impl Elaborator<'_> { } } - /// Push a type variable into the current FunctionContext to be defaulted if needed - /// at the end of the earlier of either the current function or the current comptime scope. - fn push_type_variable(&mut self, typ: Type) { - self.get_function_context().type_variables.push(typ); - } - - /// Push a trait constraint into the current FunctionContext to be solved if needed - /// at the end of the earlier of either the current function or the current comptime scope. - pub fn push_trait_constraint( - &mut self, - constraint: TraitConstraint, - expr_id: ExprId, - select_impl: bool, - ) { - self.get_function_context().trait_constraints.push((constraint, expr_id, select_impl)); - } - - /// Push an `ExprId` that corresponds to an integer literal. - /// At the end of the current function we'll check that they fit in their type's range. - pub fn push_integer_literal_expr_id(&mut self, literal_expr_id: ExprId) { - self.get_function_context().integer_literal_expr_ids.push(literal_expr_id); - } - - fn get_function_context(&mut self) -> &mut FunctionContext { - let context = self.function_context.last_mut(); - context.expect("The function_context stack should always be non-empty") - } - pub fn bind_generics_from_trait_constraint( &self, constraint: &TraitConstraint, diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 4551673132e..84fee05651b 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -18,7 +18,7 @@ use num_bigint::BigUint; use rustc_hash::FxHashMap as HashMap; use crate::{ - Kind, NamedGeneric, QuotedType, ResolvedGeneric, Shared, Type, TypeVariable, + Kind, NamedGeneric, QuotedType, ResolvedGeneric, Shared, Type, TypeBindings, TypeVariable, ast::{ ArrayLiteral, BlockExpression, ConstrainKind, Expression, ExpressionKind, ForRange, FunctionKind, FunctionReturnType, Ident, IntegerBitSize, LValue, Literal, Pattern, @@ -2492,7 +2492,15 @@ fn function_def_as_typed_expr( )); let typ = interpreter.elaborate_in_function(interpreter.current_function, reason, |elaborator| { - elaborator.type_check_variable(hir_ident, expr_id, generics) + let bindings = TypeBindings::default(); + let push_required_type_variables = false; + elaborator.type_check_variable_with_bindings( + hir_ident, + expr_id, + generics, + bindings, + push_required_type_variables, + ) }); interpreter.elaborator.interner.push_expr_type(expr_id, typ); Ok(Value::TypedExpr(TypedExpr::ExprId(expr_id))) diff --git a/compiler/noirc_frontend/src/hir/type_check/errors.rs b/compiler/noirc_frontend/src/hir/type_check/errors.rs index 53d4dc2a3cb..0970f148f11 100644 --- a/compiler/noirc_frontend/src/hir/type_check/errors.rs +++ b/compiler/noirc_frontend/src/hir/type_check/errors.rs @@ -235,6 +235,16 @@ pub enum TypeCheckError { MissingManyCases { typ: String, location: Location }, #[error("Expected a tuple with {} elements, found one with {} elements", tuple_types.len(), actual_count)] TupleMismatch { tuple_types: Vec, actual_count: usize, location: Location }, + #[error("Type annotation needed on item")] + TypeAnnotationNeededOnItem { + location: Location, + generic_name: String, + item_kind: &'static str, + item_name: String, + is_numeric: bool, + }, + #[error("Type annotation needed on array literal")] + TypeAnnotationNeededOnArrayLiteral { is_array: bool, location: Location }, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -322,7 +332,9 @@ impl TypeCheckError { | TypeCheckError::MissingCases { location, .. } | TypeCheckError::MissingManyCases { location, .. } | TypeCheckError::NestedUnsafeBlock { location } - | TypeCheckError::TupleMismatch { location, .. } => *location, + | TypeCheckError::TupleMismatch { location, .. } + | TypeCheckError::TypeAnnotationNeededOnItem { location, .. } + | TypeCheckError::TypeAnnotationNeededOnArrayLiteral { location, .. } => *location, TypeCheckError::DuplicateNamedTypeArg { name: ident, .. } | TypeCheckError::NoSuchNamedTypeArg { name: ident, .. } => ident.location(), @@ -723,6 +735,26 @@ impl<'a> From<&'a TypeCheckError> for Diagnostic { let secondary = format!("The expression the tuple is assigned to has type `({})`", vecmap(tuple_types, ToString::to_string).join(",")); Diagnostic::simple_error(msg, secondary, *location) } + TypeCheckError::TypeAnnotationNeededOnItem { + location, + generic_name, + item_kind, + item_name, + is_numeric, + } => { + let message = "Type annotation needed".into(); + let type_or_value = if *is_numeric { "value" } else { "type" }; + let secondary = format!( + "Could not determine the {type_or_value} of the generic argument `{generic_name}` declared on the {item_kind} `{item_name}`", + ); + Diagnostic::simple_error(message, secondary, *location) + } + TypeCheckError::TypeAnnotationNeededOnArrayLiteral { is_array, location } => { + let message = "Type annotation needed".into(); + let array_or_slice = if *is_array { "array" } else { "slice" }; + let secondary = format!("Could not determine the type of the {array_or_slice}"); + Diagnostic::simple_error(message, secondary, *location) + } } } } diff --git a/compiler/noirc_frontend/src/monomorphization/errors.rs b/compiler/noirc_frontend/src/monomorphization/errors.rs index ae8e9a66b22..3a00f1947d4 100644 --- a/compiler/noirc_frontend/src/monomorphization/errors.rs +++ b/compiler/noirc_frontend/src/monomorphization/errors.rs @@ -7,64 +7,19 @@ use crate::{ #[derive(Debug)] pub enum MonomorphizationError { - UnknownArrayLength { - length: Type, - err: TypeCheckError, - location: Location, - }, - UnknownConstant { - location: Location, - }, - NoDefaultType { - location: Location, - }, - NoDefaultTypeInItem { - location: Location, - generic_name: String, - item_kind: &'static str, - item_name: String, - is_numeric: bool, - }, - InternalError { - message: &'static str, - location: Location, - }, + UnknownArrayLength { length: Type, err: TypeCheckError, location: Location }, + UnknownConstant { location: Location }, + NoDefaultType { location: Location }, + InternalError { message: &'static str, location: Location }, InterpreterError(InterpreterError), - ComptimeFnInRuntimeCode { - name: String, - location: Location, - }, - ComptimeTypeInRuntimeCode { - typ: String, - location: Location, - }, - CheckedTransmuteFailed { - actual: Type, - expected: Type, - location: Location, - }, - CheckedCastFailed { - actual: Type, - expected: Type, - location: Location, - }, - RecursiveType { - typ: Type, - location: Location, - }, - CannotComputeAssociatedConstant { - name: String, - err: TypeCheckError, - location: Location, - }, - ReferenceReturnedFromIfOrMatch { - typ: String, - location: Location, - }, - AssignedToVarContainingReference { - typ: String, - location: Location, - }, + ComptimeFnInRuntimeCode { name: String, location: Location }, + ComptimeTypeInRuntimeCode { typ: String, location: Location }, + CheckedTransmuteFailed { actual: Type, expected: Type, location: Location }, + CheckedCastFailed { actual: Type, expected: Type, location: Location }, + RecursiveType { typ: Type, location: Location }, + CannotComputeAssociatedConstant { name: String, err: TypeCheckError, location: Location }, + ReferenceReturnedFromIfOrMatch { typ: String, location: Location }, + AssignedToVarContainingReference { typ: String, location: Location }, } impl MonomorphizationError { @@ -79,7 +34,6 @@ impl MonomorphizationError { | MonomorphizationError::CheckedCastFailed { location, .. } | MonomorphizationError::RecursiveType { location, .. } | MonomorphizationError::NoDefaultType { location, .. } - | MonomorphizationError::NoDefaultTypeInItem { location, .. } | MonomorphizationError::ReferenceReturnedFromIfOrMatch { location, .. } | MonomorphizationError::AssignedToVarContainingReference { location, .. } | MonomorphizationError::CannotComputeAssociatedConstant { location, .. } => *location, @@ -108,20 +62,6 @@ impl From for CustomDiagnostic { let secondary = "Could not determine type of generic argument".into(); return CustomDiagnostic::simple_error(message, secondary, *location); } - MonomorphizationError::NoDefaultTypeInItem { - location, - generic_name, - item_kind, - item_name, - is_numeric, - } => { - let message = "Type annotation needed".into(); - let type_or_value = if *is_numeric { "value" } else { "type" }; - let secondary = format!( - "Could not determine the {type_or_value} of the generic argument `{generic_name}` declared on the {item_kind} `{item_name}`", - ); - return CustomDiagnostic::simple_error(message, secondary, *location); - } MonomorphizationError::InterpreterError(error) => return error.into(), MonomorphizationError::InternalError { message, .. } => message.to_string(), MonomorphizationError::ComptimeFnInRuntimeCode { name, location } => { diff --git a/compiler/noirc_frontend/src/monomorphization/mod.rs b/compiler/noirc_frontend/src/monomorphization/mod.rs index a95203fd635..1b483a618b2 100644 --- a/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -8,14 +8,14 @@ //! //! The entry point to this pass is the `monomorphize` function which, starting from a given //! function, will monomorphize the entire reachable program. +use crate::NamedGeneric; use crate::ast::{FunctionKind, IntegerBitSize, ItemVisibility, UnaryOp}; -use crate::hir::comptime::{InterpreterError, Value}; +use crate::hir::comptime::InterpreterError; use crate::hir::type_check::{NoMatchingImplFoundError, TypeCheckError}; use crate::node_interner::{ExprId, GlobalValue, ImplSearchErrorKind}; use crate::shared::{Signedness, Visibility}; use crate::signed_field::SignedField; use crate::token::FmtStrFragment; -use crate::{DataType, NamedGeneric, Shared, TypeVariableId}; use crate::{ Kind, Type, TypeBinding, TypeBindings, debug::DebugInstrumenter, @@ -1051,20 +1051,15 @@ impl<'interner> Monomorphizer<'interner> { // Ensure all instantiation bindings are bound. // This ensures even unused type variables like `fn foo() {}` have concrete types if let Some(bindings) = self.interner.try_get_instantiation_bindings(expr_id) { - for (var, kind, binding) in bindings.values() { + for (_, kind, binding) in bindings.values() { match kind { Kind::Any => (), Kind::Normal => (), Kind::Integer => (), Kind::IntegerOrField => (), - Kind::Numeric(typ) => self.check_hir_ident_type_variable_type( - typ, - ident.location, - var.id(), - &ident, - )?, + Kind::Numeric(typ) => Self::check_type(typ, ident.location)?, } - self.check_hir_ident_type_variable_type(binding, ident.location, var.id(), &ident)?; + Self::check_type(binding, ident.location)?; } } @@ -1455,93 +1450,6 @@ impl<'interner> Monomorphizer<'interner> { }) } - /// Similar to `check_type` but knowing that this is checking the type of a type variable, - /// while also checking a HirIdent. If this fails with `NoDefaultType` we try to find out - /// the name of the unbound generic argument. - fn check_hir_ident_type_variable_type( - &self, - typ: &HirType, - location: Location, - id: TypeVariableId, - ident: &HirIdent, - ) -> Result<(), MonomorphizationError> { - let result = Self::check_type(typ, location); - let Err(MonomorphizationError::NoDefaultType { location, .. }) = result else { - return result; - }; - - let definition = self.interner.definition(ident.id); - match &definition.kind { - DefinitionKind::Function(func_id) => { - // Try to find the type variable in the function's generic arguments - let meta = self.interner.function_meta(func_id); - for generic in &meta.direct_generics { - if generic.type_var.id() == id { - let item_name = self.interner.definition_name(ident.id).to_string(); - let is_numeric = matches!(generic.type_var.kind(), Kind::Numeric(..)); - return Err(MonomorphizationError::NoDefaultTypeInItem { - location, - generic_name: generic.name.to_string(), - item_kind: "function", - item_name, - is_numeric, - }); - } - } - // If we find one in `all_generics` it means it's a generic on the type - // the function is in. - if let Some(Type::DataType(typ, ..)) = &meta.self_type { - for generic in &meta.all_generics { - if generic.type_var.id() == id { - let typ = typ.borrow(); - let item_name = typ.name.to_string(); - let item_kind = if typ.is_struct() { "struct" } else { "enum" }; - let is_numeric = matches!(generic.type_var.kind(), Kind::Numeric(..)); - return Err(MonomorphizationError::NoDefaultTypeInItem { - location, - generic_name: generic.name.to_string(), - item_kind, - item_name, - is_numeric, - }); - } - } - } - } - DefinitionKind::Global(global_id) => { - // Check if this global points to an enum variant, then get the enum's generics - // and find the type variable there. - let global = self.interner.get_global(*global_id); - let GlobalValue::Resolved(Value::Enum(_, _, Type::Forall(_, typ))) = &global.value - else { - return result; - }; - - let typ: &Type = typ; - let Type::DataType(def, _) = typ else { - return result; - }; - - let def = def.borrow(); - for generic in &def.generics { - if generic.type_var.id() == id { - let is_numeric = matches!(generic.type_var.kind(), Kind::Numeric(..)); - return Err(MonomorphizationError::NoDefaultTypeInItem { - location, - generic_name: generic.name.to_string(), - item_kind: "enum", - item_name: def.name.to_string(), - is_numeric, - }); - } - } - } - _ => (), - } - - result - } - // Similar to `convert_type` but returns an error if any type variable can't be defaulted. fn check_type(typ: &HirType, location: Location) -> Result<(), MonomorphizationError> { let typ = typ.follow_bindings_shallow(); @@ -2507,8 +2415,8 @@ fn unwrap_struct_type( match typ.follow_bindings() { HirType::DataType(def, args) => { // Some of args might not be mentioned in fields, so we need to check that they aren't unbound. - for (index, arg) in args.iter().enumerate() { - check_struct_generic_type(arg, location, &def, index)?; + for arg in &args { + Monomorphizer::check_type(arg, location)?; } Ok(def.borrow().get_fields(&args).unwrap()) @@ -2534,32 +2442,6 @@ fn unwrap_enum_type( } } -fn check_struct_generic_type( - typ: &HirType, - location: Location, - def: &Shared, - index: usize, -) -> Result<(), MonomorphizationError> { - let result = Monomorphizer::check_type(typ, location); - let Err(MonomorphizationError::NoDefaultType { location, .. }) = result else { - return result; - }; - - let def = def.borrow(); - if let Some(generic) = def.generics.get(index) { - let is_numeric = matches!(generic.type_var.kind(), Kind::Numeric(..)); - return Err(MonomorphizationError::NoDefaultTypeInItem { - location, - generic_name: generic.name.to_string(), - item_kind: "struct", - item_name: def.name.to_string(), - is_numeric, - }); - } - - result -} - pub fn perform_instantiation_bindings(bindings: &TypeBindings) { for (var, _kind, binding) in bindings.values() { var.force_bind(binding.clone()); diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index 57a786da9bf..ccc34bdcd7a 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -176,7 +176,7 @@ pub struct NodeInterner { /// Map from ExprId (referring to a Function/Method call) to its corresponding TypeBindings, /// filled out during type checking from instantiated variables. Used during monomorphization /// to map call site types back onto function parameter types, and undo this binding as needed. - instantiation_bindings: HashMap, + pub instantiation_bindings: HashMap, /// Remembers the field index a given HirMemberAccess expression was resolved to during type /// checking. diff --git a/compiler/noirc_frontend/src/tests.rs b/compiler/noirc_frontend/src/tests.rs index 336c647e24f..d23db713b0e 100644 --- a/compiler/noirc_frontend/src/tests.rs +++ b/compiler/noirc_frontend/src/tests.rs @@ -1782,6 +1782,8 @@ fn numeric_generic_as_return_type() { ^^^ unused function foo ~~~ unused function x.zeroed() + ^^^^^^^^ Type annotation needed + ~~~~~~~~ Could not determine the type of the generic argument `T` declared on the function `zeroed` } fn main() {} @@ -1964,6 +1966,8 @@ fn numeric_generic_u16_array_size() { ^^^^^^^^^^ The numeric generic is not of type `u32` ~~~~~~~~~~ expected `u32`, found `u16` len(fields) + ^^^ Type annotation needed + ~~~ Could not determine the value of the generic argument `N` declared on the function `len` } "#; check_errors!(src); @@ -2408,53 +2412,6 @@ fn impl_stricter_than_trait_different_trait_generics() { check_errors!(src); } -#[named] -#[test] -fn impl_not_found_for_inner_impl() { - // We want to guarantee that we get a no impl found error - let src = r#" - trait Serialize { - fn serialize(self) -> [Field; N]; - } - - trait ToField { - fn to_field(self) -> Field; - } - - fn process_array(array: [Field; N]) -> Field { - array[0] - } - - fn serialize_thing(thing: A) -> [Field; N] where A: Serialize { - thing.serialize() - } - - struct MyType { - a: T, - b: T, - } - - impl Serialize<2> for MyType where T: ToField { - fn serialize(self) -> [Field; 2] { - [ self.a.to_field(), self.b.to_field() ] - } - } - - impl MyType { - fn do_thing_with_serialization_with_extra_steps(self) -> Field { - process_array(serialize_thing(self)) - ^^^^^^^^^^^^^^^ No matching impl found for `T: ToField` - ~~~~~~~~~~~~~~~ No impl for `T: ToField` - } - } - - fn main() { - let _ = MyType { a: 1, b: 1 }; // silence MyType never constructed warning - } - "#; - check_errors!(src); -} - #[named] #[test] fn cannot_call_unconstrained_function_outside_of_unsafe() { @@ -4507,7 +4464,7 @@ fn indexing_array_with_non_u32_on_lvalue_produces_an_error() { #[named] #[test] -fn cannot_determine_type_of_generic_argument_in_function_call() { +fn cannot_determine_type_of_generic_argument_in_function_call_with_regular_generic() { let src = r#" fn foo() {} @@ -4519,7 +4476,7 @@ fn cannot_determine_type_of_generic_argument_in_function_call() { } "#; - check_monomorphization_error!(src); + check_errors!(src); } #[named] @@ -4531,12 +4488,12 @@ fn cannot_determine_type_of_generic_argument_in_struct_constructor() { fn main() { let _ = Foo {}; - ^^^^^^ Type annotation needed - ~~~~~~ Could not determine the type of the generic argument `T` declared on the struct `Foo` + ^^^ Type annotation needed + ~~~ Could not determine the type of the generic argument `T` declared on the struct `Foo` } "#; - check_monomorphization_error!(src); + check_errors!(src); } #[named] @@ -4556,7 +4513,7 @@ fn cannot_determine_type_of_generic_argument_in_enum_constructor() { "#; let features = vec![UnstableFeature::Enums]; - check_monomorphization_error_using_features!(src, &features); + check_errors_using_features!(src, &features); } #[named] @@ -4568,14 +4525,14 @@ fn cannot_determine_type_of_generic_argument_in_function_call_for_generic_impl() impl Foo { fn one() {} } - + fn main() { Foo::one(); ^^^ Type annotation needed ~~~ Could not determine the type of the generic argument `T` declared on the struct `Foo` } "#; - check_monomorphization_error!(src); + check_errors!(src); } #[named] @@ -4589,7 +4546,7 @@ fn unconstrained_type_parameter_in_impl() { ~ Hint: remove the `U` type parameter fn main() { - let _ = Foo {}; + let _ = Foo:: {}; } "#; check_errors!(src); @@ -4728,7 +4685,33 @@ fn cannot_determine_type_of_generic_argument_in_function_call_when_it_is_a_numer } "#; let features = vec![UnstableFeature::Enums]; - check_monomorphization_error_using_features!(src, &features); + check_errors_using_features!(src, &features); +} + +#[named] +#[test] +fn cannot_determine_array_type() { + let src = r#" + fn main() { + let _ = []; + ^^ Type annotation needed + ~~ Could not determine the type of the array + } + "#; + check_errors!(src); +} + +#[named] +#[test] +fn cannot_determine_slice_type() { + let src = r#" + fn main() { + let _ = &[]; + ^^^ Type annotation needed + ~~~ Could not determine the type of the slice + } + "#; + check_errors!(src); } #[named] diff --git a/compiler/noirc_frontend/src/tests/traits.rs b/compiler/noirc_frontend/src/tests/traits.rs index d611d9b7aa9..92eed274bdc 100644 --- a/compiler/noirc_frontend/src/tests/traits.rs +++ b/compiler/noirc_frontend/src/tests/traits.rs @@ -1,8 +1,7 @@ -use crate::elaborator::FrontendOptions; - -use crate::tests::Expect; -use crate::{assert_no_errors, check_monomorphization_error}; -use crate::{check_errors, get_program_with_options}; +use crate::{ + assert_no_errors, check_errors, check_monomorphization_error, elaborator::FrontendOptions, + get_program_with_options, tests::Expect, +}; #[named] #[test] @@ -405,61 +404,6 @@ fn trait_alias_polymorphic_inheritance() { assert_no_errors!(src); } -// TODO(https://github.com/noir-lang/noir/issues/6467): currently fails with the -// same errors as the desugared version -#[named] -#[test] -fn trait_alias_polymorphic_where_clause() { - let src = r#" - trait Foo { - fn foo(self) -> Self; - } - - trait Bar { - fn bar(self) -> T; - } - - trait Baz { - fn baz(self) -> bool; - } - - trait Qux = Foo + Bar where T: Baz; - - fn qux(x: T) -> bool where T: Qux { - x.foo().bar().baz() - ^^^^^^^^^^^^^^^^^^^ No method named 'baz' found for type 'U' - } - - impl Foo for Field { - fn foo(self) -> Self { - self + 1 - } - } - - impl Bar for Field { - fn bar(self) -> bool { - true - } - } - - impl Baz for bool { - fn baz(self) -> bool { - self - } - } - - fn main() { - assert(0.foo().bar().baz() == qux(0)); - ^^^ No matching impl found for `T: Baz` - ~~~ No impl for `T: Baz` - } - "#; - - // TODO(https://github.com/noir-lang/noir/issues/6467) - // assert_no_errors!(src); - check_errors!(src); -} - // TODO(https://github.com/noir-lang/noir/issues/6467): currently failing, so // this just tests that the trait alias has an equivalent error to the expected // desugared version diff --git a/compiler/noirc_frontend/src/tests/turbofish.rs b/compiler/noirc_frontend/src/tests/turbofish.rs index 9d58b441224..b15a1194762 100644 --- a/compiler/noirc_frontend/src/tests/turbofish.rs +++ b/compiler/noirc_frontend/src/tests/turbofish.rs @@ -24,8 +24,11 @@ fn turbofish_numeric_generic_nested_function_call() { assert_no_errors!(src); } +// TODO: this test should pass, but it doesn't because of this issue: +// https://github.com/noir-lang/noir/issues/8900 #[named] #[test] +#[should_panic] fn turbofish_numeric_generic_nested_method_call() { // Check for turbofish numeric generics used with method calls let src = r#" @@ -44,7 +47,7 @@ fn turbofish_numeric_generic_nested_method_call() { } fn bar() -> [u8; N] { - let _ = Foo::static_method::(); + let _ = Foo::::static_method::(); let x: Foo = Foo { a: 0 }; x.impl_method::() } diff --git a/noir_stdlib/src/meta/ctstring.nr b/noir_stdlib/src/meta/ctstring.nr index 00b4f1fdb6f..a3f03019fd3 100644 --- a/noir_stdlib/src/meta/ctstring.nr +++ b/noir_stdlib/src/meta/ctstring.nr @@ -94,7 +94,7 @@ mod test { comptime { // docs:start:as_quoted_str_example let my_ctstring = "foo bar".as_ctstring(); - let my_str = my_ctstring.as_quoted_str!(); + let my_str: str<7> = my_ctstring.as_quoted_str!(); assert_eq(crate::meta::type_of(my_str), quote { str<7> }.as_type()); // docs:end:as_quoted_str_example diff --git a/test_programs/compile_failure/impl_not_found_for_inner_impl/Nargo.toml b/test_programs/compile_failure/impl_not_found_for_inner_impl/Nargo.toml new file mode 100644 index 00000000000..c04c7acc943 --- /dev/null +++ b/test_programs/compile_failure/impl_not_found_for_inner_impl/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "impl_not_found_for_inner_impl" +type = "bin" +authors = [""] +compiler_version = ">=0.33.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/compile_failure/impl_not_found_for_inner_impl/src/main.nr b/test_programs/compile_failure/impl_not_found_for_inner_impl/src/main.nr new file mode 100644 index 00000000000..9f9674ab2ee --- /dev/null +++ b/test_programs/compile_failure/impl_not_found_for_inner_impl/src/main.nr @@ -0,0 +1,42 @@ +trait Serialize { + fn serialize(self) -> [Field; N]; +} + +trait ToField { + fn to_field(self) -> Field; +} + +fn process_array(array: [Field; N]) -> Field { + array[0] +} + +fn serialize_thing(thing: A) -> [Field; N] +where + A: Serialize, +{ + thing.serialize() +} + +struct MyType { + a: T, + b: T, +} + +impl Serialize<2> for MyType +where + T: ToField, +{ + fn serialize(self) -> [Field; 2] { + [self.a.to_field(), self.b.to_field()] + } +} + +impl MyType { + fn do_thing_with_serialization_with_extra_steps(self) -> Field { + process_array(serialize_thing(self)) + } +} + +fn main() { + let _ = MyType { a: 1, b: 1 }; // silence MyType never constructed warning +} diff --git a/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_array_type/Nargo.toml b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_array_type/Nargo.toml new file mode 100644 index 00000000000..f4310869ced --- /dev/null +++ b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_array_type/Nargo.toml @@ -0,0 +1,7 @@ + + [package] + name = "noirc_frontend_tests_cannot_determine_array_type" + type = "bin" + authors = [""] + + [dependencies] \ No newline at end of file diff --git a/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_array_type/src/main.nr b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_array_type/src/main.nr new file mode 100644 index 00000000000..def4d0c5875 --- /dev/null +++ b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_array_type/src/main.nr @@ -0,0 +1,5 @@ + + fn main() { + let _ = []; + } + \ No newline at end of file diff --git a/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_array_type/src_hash.txt b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_array_type/src_hash.txt new file mode 100644 index 00000000000..ae3d44198e3 --- /dev/null +++ b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_array_type/src_hash.txt @@ -0,0 +1 @@ +2106807571799906179 \ No newline at end of file diff --git a/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_slice_type/Nargo.toml b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_slice_type/Nargo.toml new file mode 100644 index 00000000000..9ee80d504ec --- /dev/null +++ b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_slice_type/Nargo.toml @@ -0,0 +1,7 @@ + + [package] + name = "noirc_frontend_tests_cannot_determine_slice_type" + type = "bin" + authors = [""] + + [dependencies] \ No newline at end of file diff --git a/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_slice_type/src/main.nr b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_slice_type/src/main.nr new file mode 100644 index 00000000000..c633e85008b --- /dev/null +++ b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_slice_type/src/main.nr @@ -0,0 +1,5 @@ + + fn main() { + let _ = &[]; + } + \ No newline at end of file diff --git a/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_slice_type/src_hash.txt b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_slice_type/src_hash.txt new file mode 100644 index 00000000000..6ec671badcb --- /dev/null +++ b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_slice_type/src_hash.txt @@ -0,0 +1 @@ +4321272040692519803 \ No newline at end of file diff --git a/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_for_generic_impl/src/main.nr b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_for_generic_impl/src/main.nr index a3c23bd8124..498659fa9b0 100644 --- a/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_for_generic_impl/src/main.nr +++ b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_for_generic_impl/src/main.nr @@ -4,7 +4,7 @@ impl Foo { fn one() {} } - + fn main() { Foo::one(); } diff --git a/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_for_generic_impl/src_hash.txt b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_for_generic_impl/src_hash.txt index fc3e58e0b82..a8b5314fe55 100644 --- a/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_for_generic_impl/src_hash.txt +++ b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_for_generic_impl/src_hash.txt @@ -1 +1 @@ -5512692969643136434 \ No newline at end of file +127637158036360596 \ No newline at end of file diff --git a/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_with_regular_generic/Nargo.toml b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_with_regular_generic/Nargo.toml new file mode 100644 index 00000000000..ae76414c32b --- /dev/null +++ b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_with_regular_generic/Nargo.toml @@ -0,0 +1,7 @@ + + [package] + name = "noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_with_regular_generic" + type = "bin" + authors = [""] + + [dependencies] \ No newline at end of file diff --git a/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_with_regular_generic/src/main.nr b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_with_regular_generic/src/main.nr new file mode 100644 index 00000000000..5dcb07e4eb5 --- /dev/null +++ b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_with_regular_generic/src/main.nr @@ -0,0 +1,9 @@ + + fn foo() {} + + fn main() + { + foo(); + } + + \ No newline at end of file diff --git a/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_with_regular_generic/src_hash.txt b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_with_regular_generic/src_hash.txt new file mode 100644 index 00000000000..6d742034371 --- /dev/null +++ b/test_programs/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_with_regular_generic/src_hash.txt @@ -0,0 +1 @@ +18413755304929648438 \ No newline at end of file diff --git a/test_programs/compile_failure/noirc_frontend_tests_unconstrained_type_parameter_in_impl/src/main.nr b/test_programs/compile_failure/noirc_frontend_tests_unconstrained_type_parameter_in_impl/src/main.nr index 9c53a79ac1c..9da9f80fba4 100644 --- a/test_programs/compile_failure/noirc_frontend_tests_unconstrained_type_parameter_in_impl/src/main.nr +++ b/test_programs/compile_failure/noirc_frontend_tests_unconstrained_type_parameter_in_impl/src/main.nr @@ -4,6 +4,6 @@ impl Foo {} fn main() { - let _ = Foo {}; + let _ = Foo:: {}; } \ No newline at end of file diff --git a/test_programs/compile_failure/noirc_frontend_tests_unconstrained_type_parameter_in_impl/src_hash.txt b/test_programs/compile_failure/noirc_frontend_tests_unconstrained_type_parameter_in_impl/src_hash.txt index 7058e6db6f3..550dc0c08c8 100644 --- a/test_programs/compile_failure/noirc_frontend_tests_unconstrained_type_parameter_in_impl/src_hash.txt +++ b/test_programs/compile_failure/noirc_frontend_tests_unconstrained_type_parameter_in_impl/src_hash.txt @@ -1 +1 @@ -5158513121244495309 \ No newline at end of file +12299367657260516465 \ No newline at end of file diff --git a/test_programs/execution_success/prelude/src/main.nr b/test_programs/execution_success/prelude/src/main.nr index 4fe6080222e..b0981c873c1 100644 --- a/test_programs/execution_success/prelude/src/main.nr +++ b/test_programs/execution_success/prelude/src/main.nr @@ -12,8 +12,8 @@ mod a { use std::option::Option; fn main() { - let _xs = Vec::new(); - let _option = Option::none(); + let _xs: Vec = Vec::new(); + let _option: Option = Option::none(); print("42\n"); println("42"); @@ -22,8 +22,8 @@ mod a { mod b { fn main() { - let _xs = Vec::new(); - let _option = Option::none(); + let _xs: Vec = Vec::new(); + let _option: Option = Option::none(); print("42\n"); println("42"); diff --git a/test_programs/noir_test_success/bounded_vec/src/main.nr b/test_programs/noir_test_success/bounded_vec/src/main.nr index 00706105d99..ff4c191d4e3 100644 --- a/test_programs/noir_test_success/bounded_vec/src/main.nr +++ b/test_programs/noir_test_success/bounded_vec/src/main.nr @@ -3,11 +3,6 @@ fn test_vec_new_good() { good(); } -#[test(should_fail)] -fn test_vec_new_bad() { - bad(); -} - // docs:start:new_example fn good() -> BoundedVec { // Ok! MaxLen is specified with a type annotation @@ -17,13 +12,6 @@ fn good() -> BoundedVec { // Ok! MaxLen is known from the type of `good`'s return value v2 } - -fn bad() { - // Error: Type annotation needed - // The compiler can't infer `MaxLen` from this code. - let mut v3 = BoundedVec::new(); - v3.push(5); -} // docs:end:new_example #[test] diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/array_length_defaulting/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/array_length_defaulting/execute__tests__stderr.snap index fc38c0892b5..d1a5d0928cb 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/array_length_defaulting/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/array_length_defaulting/execute__tests__stderr.snap @@ -9,4 +9,11 @@ error: Type provided when a numeric generic was expected │ ---------- the numeric generic is not of type `u32` │ -Aborting due to 1 previous error +error: Type annotation needed + ┌─ src/main.nr:3:5 + │ +3 │ foo(x); + │ --- Could not determine the type of the generic argument `N` declared on the function `foo` + │ + +Aborting due to 2 previous errors diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/brillig_slice_to_acir/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/brillig_slice_to_acir/execute__tests__stderr.snap index f9c9646c82e..dbfeb2422b1 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/brillig_slice_to_acir/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/brillig_slice_to_acir/execute__tests__stderr.snap @@ -37,6 +37,13 @@ error: Cannot assign an expression of type [u32] to a value of type [_; 0] │ ----------- │ +error: Type annotation needed + ┌─ src/main.nr:4:21 + │ +4 │ let mut new_x = []; + │ -- Could not determine the type of the array + │ + error: No method named 'push_back' found for type '[u32; 0]' ┌─ src/main.nr:11:13 │ @@ -44,4 +51,4 @@ error: No method named 'push_back' found for type '[u32; 0]' │ ----------------- │ -Aborting due to 4 previous errors +Aborting due to 5 previous errors diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/foreign_function_declaration/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/foreign_function_declaration/execute__tests__stderr.snap index f7881ae4462..aa4cd9044c1 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/foreign_function_declaration/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/foreign_function_declaration/execute__tests__stderr.snap @@ -16,4 +16,11 @@ error: Definition of low-level function outside of standard library │ ------------------------- Usage of the `#[foreign]` or `#[builtin]` function attributes are not allowed outside of the Noir standard library │ -Aborting due to 2 previous errors +error: Type annotation needed + ┌─ src/main.nr:9:5 + │ +9 │ my_pedersen_hash([1]) + │ ---------------- Could not determine the type of the generic argument `N` declared on the function `my_pedersen_hash` + │ + +Aborting due to 3 previous errors diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/impl_not_found_for_inner_impl/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/impl_not_found_for_inner_impl/execute__tests__stderr.snap new file mode 100644 index 00000000000..0866a22f926 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/impl_not_found_for_inner_impl/execute__tests__stderr.snap @@ -0,0 +1,27 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: stderr +--- +error: No matching impl found for `T: ToField` + ┌─ src/main.nr:36:23 + │ +36 │ process_array(serialize_thing(self)) + │ --------------- No impl for `T: ToField` + │ + = Required by `MyType: Serialize<_>` + +error: Type annotation needed + ┌─ src/main.nr:36:9 + │ +36 │ process_array(serialize_thing(self)) + │ ------------- Could not determine the value of the generic argument `N` declared on the function `process_array` + │ + +error: Type annotation needed + ┌─ src/main.nr:36:23 + │ +36 │ process_array(serialize_thing(self)) + │ --------------- Could not determine the value of the generic argument `N` declared on the function `serialize_thing` + │ + +Aborting due to 3 previous errors diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/macro_result_type/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/macro_result_type/execute__tests__stderr.snap index 462881e130e..2bd2d0c7eab 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/macro_result_type/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/macro_result_type/execute__tests__stderr.snap @@ -9,6 +9,13 @@ error: trait `meta::ctstring::AsCtString` which provides `as_ctstring` is implem │ --------------------- │ +error: Type annotation needed + ┌─ src/main.nr:6:22 + │ +6 │ let result = half(string); + │ ---- Could not determine the value of the generic argument `N` declared on the function `half` + │ + error: Non-integer array length: `_` ┌─ src/main.nr:12:5 │ @@ -16,4 +23,4 @@ error: Non-integer array length: `_` │ - Array lengths must be integers, but evaluating `_` resulted in `Expected a constant, but found `_`` │ -Aborting due to 2 previous errors +Aborting due to 3 previous errors diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/mutability_regression_2911/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/mutability_regression_2911/execute__tests__stderr.snap index 139cd81f541..05312bf7790 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/mutability_regression_2911/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/mutability_regression_2911/execute__tests__stderr.snap @@ -16,4 +16,11 @@ error: Variable `slice` must be mutable to be assigned to │ ----- │ -Aborting due to 2 previous errors +error: Type annotation needed + ┌─ src/main.nr:3:37 + │ +3 │ let slice : &mut [Field] = &mut []; + │ -- Could not determine the type of the array + │ + +Aborting due to 3 previous errors diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/negate_unsigned/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/negate_unsigned/execute__tests__stderr.snap index 2f95d99c8c2..b6095e9319c 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/negate_unsigned/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/negate_unsigned/execute__tests__stderr.snap @@ -9,4 +9,11 @@ error: Cannot apply unary operator `-` to type `u8` │ -------- │ -Aborting due to 1 previous error +error: Type annotation needed + ┌─ src/main.nr:3:10 + │ +3 │ std::println(var); + │ ------- Could not determine the type of the generic argument `T` declared on the function `println` + │ + +Aborting due to 2 previous errors diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_cannot_determine_array_type/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_cannot_determine_array_type/execute__tests__stderr.snap new file mode 100644 index 00000000000..4c4f7531b65 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_cannot_determine_array_type/execute__tests__stderr.snap @@ -0,0 +1,12 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: stderr +--- +error: Type annotation needed + ┌─ src/main.nr:3:17 + │ +3 │ let _ = []; + │ -- Could not determine the type of the array + │ + +Aborting due to 1 previous error diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_cannot_determine_slice_type/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_cannot_determine_slice_type/execute__tests__stderr.snap new file mode 100644 index 00000000000..bc5a387512f --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_cannot_determine_slice_type/execute__tests__stderr.snap @@ -0,0 +1,12 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: stderr +--- +error: Type annotation needed + ┌─ src/main.nr:3:17 + │ +3 │ let _ = &[]; + │ --- Could not determine the type of the slice + │ + +Aborting due to 1 previous error diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_with_regular_generic/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_with_regular_generic/execute__tests__stderr.snap new file mode 100644 index 00000000000..619185fc734 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_function_call_with_regular_generic/execute__tests__stderr.snap @@ -0,0 +1,12 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: stderr +--- +error: Type annotation needed + ┌─ src/main.nr:6:9 + │ +6 │ foo(); + │ --- Could not determine the type of the generic argument `T` declared on the function `foo` + │ + +Aborting due to 1 previous error diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_struct_constructor/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_struct_constructor/execute__tests__stderr.snap index c0ca416bb77..2fc9aaf1796 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_struct_constructor/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_cannot_determine_type_of_generic_argument_in_struct_constructor/execute__tests__stderr.snap @@ -6,7 +6,7 @@ error: Type annotation needed ┌─ src/main.nr:6:17 │ 6 │ let _ = Foo {}; - │ ------ Could not determine the type of the generic argument `T` declared on the struct `Foo` + │ --- Could not determine the type of the generic argument `T` declared on the struct `Foo` │ Aborting due to 1 previous error diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_impl_not_found_for_inner_impl/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_impl_not_found_for_inner_impl/execute__tests__stderr.snap index b35efb18e36..5a634e8c75c 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_impl_not_found_for_inner_impl/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_impl_not_found_for_inner_impl/execute__tests__stderr.snap @@ -10,4 +10,18 @@ error: No matching impl found for `T: ToField` │ = Required by `MyType: Serialize<_>` -Aborting due to 1 previous error +error: Type annotation needed + ┌─ src/main.nr:31:13 + │ +31 │ process_array(serialize_thing(self)) + │ ------------- Could not determine the value of the generic argument `N` declared on the function `process_array` + │ + +error: Type annotation needed + ┌─ src/main.nr:31:27 + │ +31 │ process_array(serialize_thing(self)) + │ --------------- Could not determine the value of the generic argument `N` declared on the function `serialize_thing` + │ + +Aborting due to 3 previous errors diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_numeric_generic_as_return_type/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_numeric_generic_as_return_type/execute__tests__stderr.snap index b619c9b6e07..ba49a9d171d 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_numeric_generic_as_return_type/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_numeric_generic_as_return_type/execute__tests__stderr.snap @@ -16,4 +16,11 @@ error: Expected type, found numeric generic │ - not a type │ -Aborting due to 1 previous error +error: Type annotation needed + ┌─ src/main.nr:8:9 + │ +8 │ x.zeroed() + │ -------- Could not determine the type of the generic argument `T` declared on the function `zeroed` + │ + +Aborting due to 2 previous errors diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_numeric_generic_u16_array_size/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_numeric_generic_u16_array_size/execute__tests__stderr.snap index e5dc4a7db92..a8d9eee5df3 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_numeric_generic_u16_array_size/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_numeric_generic_u16_array_size/execute__tests__stderr.snap @@ -16,4 +16,11 @@ error: The numeric generic is not of type `u32` │ - expected `u32`, found `u16` │ -Aborting due to 2 previous errors +error: Type annotation needed + ┌─ src/main.nr:8:9 + │ +8 │ len(fields) + │ --- Could not determine the value of the generic argument `N` declared on the function `len` + │ + +Aborting due to 3 previous errors diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_traits_trait_alias_polymorphic_where_clause/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_traits_trait_alias_polymorphic_where_clause/execute__tests__stderr.snap index 95f3b55bc42..5807850a3a3 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_traits_trait_alias_polymorphic_where_clause/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/noirc_frontend_tests_traits_trait_alias_polymorphic_where_clause/execute__tests__stderr.snap @@ -17,4 +17,11 @@ error: No matching impl found for `T: Baz` │ = Required by `Field: Qux<_>` -Aborting due to 2 previous errors +error: Type annotation needed + ┌─ src/main.nr:39:43 + │ +39 │ assert(0.foo().bar().baz() == qux(0)); + │ --- Could not determine the type of the generic argument `U` declared on the function `qux` + │ + +Aborting due to 3 previous errors diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/option_expect_bad_input/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/option_expect_bad_input/execute__tests__stderr.snap index e1c9075b616..9dc9fde6082 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/option_expect_bad_input/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/option_expect_bad_input/execute__tests__stderr.snap @@ -9,4 +9,18 @@ error: Expected type fmtstr<_, _>, found type str<35> │ ------------------------------------- │ -Aborting due to 1 previous error +error: Type annotation needed + ┌─ src/main.nr:5:12 + │ +5 │ assert(some.expect("Should have the value {inner_value}") == 3); + │ ----------- Could not determine the value of the generic argument `N` declared on the function `expect` + │ + +error: Type annotation needed + ┌─ src/main.nr:5:12 + │ +5 │ assert(some.expect("Should have the value {inner_value}") == 3); + │ ----------- Could not determine the type of the generic argument `MessageTypes` declared on the function `expect` + │ + +Aborting due to 3 previous errors diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/trait_incorrect_generic_count/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/trait_incorrect_generic_count/execute__tests__stderr.snap index 69d7bf70bfd..ef4c655d478 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/trait_incorrect_generic_count/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/trait_incorrect_generic_count/execute__tests__stderr.snap @@ -16,6 +16,13 @@ warning: unused variable x │ - unused variable │ +error: Type annotation needed + ┌─ src/main.nr:3:5 + │ +3 │ x.trait_fn(); + │ ---------- Could not determine the type of the generic argument `B` declared on the function `trait_fn` + │ + error: expected type T, found type () ┌─ src/main.nr:7:8 │ @@ -33,4 +40,4 @@ error: trait_fn expects 1 generic but 2 were given │ -------- │ -Aborting due to 2 previous errors +Aborting due to 3 previous errors diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/type_annotation_needed_on_struct_constructor/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/type_annotation_needed_on_struct_constructor/execute__tests__stderr.snap index 6a46afd12a1..7af4e6c5b8e 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/type_annotation_needed_on_struct_constructor/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/type_annotation_needed_on_struct_constructor/execute__tests__stderr.snap @@ -2,11 +2,18 @@ source: tooling/nargo_cli/tests/execute.rs expression: stderr --- +warning: unused variable foo + ┌─ src/main.nr:5:9 + │ +5 │ let foo = Foo {}; + │ --- unused variable + │ + error: Type annotation needed ┌─ src/main.nr:5:15 │ 5 │ let foo = Foo {}; - │ ------ Could not determine the type of the generic argument `T` declared on the struct `Foo` + │ --- Could not determine the type of the generic argument `T` declared on the struct `Foo` │ Aborting due to 1 previous error diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/type_annotation_needed_on_struct_new/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/type_annotation_needed_on_struct_new/execute__tests__stderr.snap index bf52b7180b6..4c23e59112a 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/type_annotation_needed_on_struct_new/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/type_annotation_needed_on_struct_new/execute__tests__stderr.snap @@ -2,6 +2,13 @@ source: tooling/nargo_cli/tests/execute.rs expression: stderr --- +warning: unused variable foo + ┌─ src/main.nr:11:9 + │ +11 │ let foo = Foo::new(); + │ --- unused variable + │ + error: Type annotation needed ┌─ src/main.nr:11:20 │ diff --git a/tooling/nargo_cli/tests/snapshots/compile_failure/typevar_default/execute__tests__stderr.snap b/tooling/nargo_cli/tests/snapshots/compile_failure/typevar_default/execute__tests__stderr.snap index 587565e68a2..cb10d7b7771 100644 --- a/tooling/nargo_cli/tests/snapshots/compile_failure/typevar_default/execute__tests__stderr.snap +++ b/tooling/nargo_cli/tests/snapshots/compile_failure/typevar_default/execute__tests__stderr.snap @@ -9,6 +9,13 @@ error: Type provided when a numeric generic was expected │ ---------- the numeric generic is not of type `u32` │ +error: Type annotation needed + ┌─ src/main.nr:3:13 + │ +3 │ let _ = slice_to_array(&[1, 2, 3]); + │ -------------- Could not determine the type of the generic argument `N` declared on the function `slice_to_array` + │ + error: Type provided when a numeric generic was expected ┌─ src/main.nr:7:25 │ @@ -23,4 +30,4 @@ error: cannot find `N` in this scope │ - not found in this scope │ -Aborting due to 3 previous errors +Aborting due to 4 previous errors diff --git a/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__expanded.snap b/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__expanded.snap index 8434682df60..6465c4e92b2 100644 --- a/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__expanded.snap +++ b/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__expanded.snap @@ -13,8 +13,8 @@ mod a { use std::{collections::vec::Vec, option::Option}; fn main() { - let _xs: Vec<_> = Vec::new(); - let _option: Option<_> = Option::none(); + let _xs: Vec = Vec::new(); + let _option: Option = Option::none(); print("42\n"); println("42"); } @@ -22,8 +22,8 @@ mod a { mod b { fn main() { - let _xs: Vec<_> = Vec::new(); - let _option: Option<_> = Option::none(); + let _xs: Vec = Vec::new(); + let _option: Option = Option::none(); print("42\n"); println("42"); } diff --git a/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_false_inliner_-9223372036854775808.snap b/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_false_inliner_-9223372036854775808.snap index d5139f9de41..9383dea1abb 100644 --- a/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_false_inliner_-9223372036854775808.snap +++ b/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_false_inliner_-9223372036854775808.snap @@ -35,7 +35,7 @@ expression: artifact "path": "std/lib.nr" }, "50": { - "source": "fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n}\n\nmod a {\n // We don't want to give an error due to re-importing elements that are already in the prelude.\n use std::collections::vec::Vec;\n use std::option::Option;\n\n fn main() {\n let _xs = Vec::new();\n let _option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n\nmod b {\n fn main() {\n let _xs = Vec::new();\n let _option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n", + "source": "fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n}\n\nmod a {\n // We don't want to give an error due to re-importing elements that are already in the prelude.\n use std::collections::vec::Vec;\n use std::option::Option;\n\n fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n\nmod b {\n fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n", "path": "" } }, diff --git a/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_false_inliner_0.snap b/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_false_inliner_0.snap index d5139f9de41..9383dea1abb 100644 --- a/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_false_inliner_0.snap +++ b/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_false_inliner_0.snap @@ -35,7 +35,7 @@ expression: artifact "path": "std/lib.nr" }, "50": { - "source": "fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n}\n\nmod a {\n // We don't want to give an error due to re-importing elements that are already in the prelude.\n use std::collections::vec::Vec;\n use std::option::Option;\n\n fn main() {\n let _xs = Vec::new();\n let _option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n\nmod b {\n fn main() {\n let _xs = Vec::new();\n let _option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n", + "source": "fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n}\n\nmod a {\n // We don't want to give an error due to re-importing elements that are already in the prelude.\n use std::collections::vec::Vec;\n use std::option::Option;\n\n fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n\nmod b {\n fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n", "path": "" } }, diff --git a/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_false_inliner_9223372036854775807.snap b/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_false_inliner_9223372036854775807.snap index d5139f9de41..9383dea1abb 100644 --- a/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_false_inliner_9223372036854775807.snap +++ b/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_false_inliner_9223372036854775807.snap @@ -35,7 +35,7 @@ expression: artifact "path": "std/lib.nr" }, "50": { - "source": "fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n}\n\nmod a {\n // We don't want to give an error due to re-importing elements that are already in the prelude.\n use std::collections::vec::Vec;\n use std::option::Option;\n\n fn main() {\n let _xs = Vec::new();\n let _option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n\nmod b {\n fn main() {\n let _xs = Vec::new();\n let _option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n", + "source": "fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n}\n\nmod a {\n // We don't want to give an error due to re-importing elements that are already in the prelude.\n use std::collections::vec::Vec;\n use std::option::Option;\n\n fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n\nmod b {\n fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n", "path": "" } }, diff --git a/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_true_inliner_-9223372036854775808.snap b/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_true_inliner_-9223372036854775808.snap index 6ef05c26f45..73de3e77e6c 100644 --- a/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_true_inliner_-9223372036854775808.snap +++ b/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_true_inliner_-9223372036854775808.snap @@ -32,7 +32,7 @@ expression: artifact "path": "std/lib.nr" }, "50": { - "source": "fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n}\n\nmod a {\n // We don't want to give an error due to re-importing elements that are already in the prelude.\n use std::collections::vec::Vec;\n use std::option::Option;\n\n fn main() {\n let _xs = Vec::new();\n let _option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n\nmod b {\n fn main() {\n let _xs = Vec::new();\n let _option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n", + "source": "fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n}\n\nmod a {\n // We don't want to give an error due to re-importing elements that are already in the prelude.\n use std::collections::vec::Vec;\n use std::option::Option;\n\n fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n\nmod b {\n fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n", "path": "" } }, diff --git a/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_true_inliner_0.snap b/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_true_inliner_0.snap index 6ef05c26f45..73de3e77e6c 100644 --- a/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_true_inliner_0.snap +++ b/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_true_inliner_0.snap @@ -32,7 +32,7 @@ expression: artifact "path": "std/lib.nr" }, "50": { - "source": "fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n}\n\nmod a {\n // We don't want to give an error due to re-importing elements that are already in the prelude.\n use std::collections::vec::Vec;\n use std::option::Option;\n\n fn main() {\n let _xs = Vec::new();\n let _option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n\nmod b {\n fn main() {\n let _xs = Vec::new();\n let _option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n", + "source": "fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n}\n\nmod a {\n // We don't want to give an error due to re-importing elements that are already in the prelude.\n use std::collections::vec::Vec;\n use std::option::Option;\n\n fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n\nmod b {\n fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n", "path": "" } }, diff --git a/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_true_inliner_9223372036854775807.snap b/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_true_inliner_9223372036854775807.snap index 6ef05c26f45..73de3e77e6c 100644 --- a/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_true_inliner_9223372036854775807.snap +++ b/tooling/nargo_cli/tests/snapshots/execution_success/prelude/execute__tests__force_brillig_true_inliner_9223372036854775807.snap @@ -32,7 +32,7 @@ expression: artifact "path": "std/lib.nr" }, "50": { - "source": "fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n}\n\nmod a {\n // We don't want to give an error due to re-importing elements that are already in the prelude.\n use std::collections::vec::Vec;\n use std::option::Option;\n\n fn main() {\n let _xs = Vec::new();\n let _option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n\nmod b {\n fn main() {\n let _xs = Vec::new();\n let _option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n", + "source": "fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n}\n\nmod a {\n // We don't want to give an error due to re-importing elements that are already in the prelude.\n use std::collections::vec::Vec;\n use std::option::Option;\n\n fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n\nmod b {\n fn main() {\n let _xs: Vec = Vec::new();\n let _option: Option = Option::none();\n\n print(\"42\\n\");\n println(\"42\");\n }\n}\n", "path": "" } },