Skip to content

Commit

Permalink
Merge 7d4bd4d into 9b26650
Browse files Browse the repository at this point in the history
  • Loading branch information
TomAFrench authored Sep 24, 2024
2 parents 9b26650 + 7d4bd4d commit 1e654bb
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 24 deletions.
3 changes: 2 additions & 1 deletion compiler/noirc_frontend/src/ast/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,7 @@ impl Display for TypePath {
impl FunctionDefinition {
pub fn normal(
name: &Ident,
is_unconstrained: bool,
generics: &UnresolvedGenerics,
parameters: &[(Ident, UnresolvedType)],
body: &BlockExpression,
Expand All @@ -821,7 +822,7 @@ impl FunctionDefinition {
FunctionDefinition {
name: name.clone(),
attributes: Attributes::empty(),
is_unconstrained: false,
is_unconstrained,
is_comptime: false,
visibility: ItemVisibility::Private,
generics: generics.clone(),
Expand Down
35 changes: 14 additions & 21 deletions compiler/noirc_frontend/src/elaborator/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ use crate::{
hir_def::{function::Parameters, traits::TraitFunction},
macros_api::{
BlockExpression, FunctionDefinition, FunctionReturnType, Ident, ItemVisibility,
NodeInterner, NoirFunction, Param, Pattern, UnresolvedType, Visibility,
NodeInterner, NoirFunction, UnresolvedType,
},
node_interner::{FuncId, ReferenceId, TraitId},
token::Attributes,
Kind, ResolvedGeneric, Type, TypeBindings, TypeVariableKind,
};

Expand Down Expand Up @@ -103,6 +102,7 @@ impl<'context> Elaborator<'context> {
this.resolve_trait_function(
trait_id,
name,
*is_unconstrained,
generics,
parameters,
return_type,
Expand Down Expand Up @@ -164,6 +164,7 @@ impl<'context> Elaborator<'context> {
&mut self,
trait_id: TraitId,
name: &Ident,
is_unconstrained: bool,
generics: &UnresolvedGenerics,
parameters: &[(Ident, UnresolvedType)],
return_type: &FunctionReturnType,
Expand All @@ -175,25 +176,17 @@ impl<'context> Elaborator<'context> {
self.scopes.start_function();

let kind = FunctionKind::Normal;
let def = FunctionDefinition {
name: name.clone(),
attributes: Attributes::empty(),
is_unconstrained: false,
is_comptime: false,
visibility: ItemVisibility::Public, // Trait functions are always public
generics: generics.clone(),
parameters: vecmap(parameters, |(name, typ)| Param {
visibility: Visibility::Private,
pattern: Pattern::Identifier(name.clone()),
typ: typ.clone(),
span: name.span(),
}),
body: BlockExpression { statements: Vec::new() },
span: name.span(),
where_clause: where_clause.to_vec(),
return_type: return_type.clone(),
return_visibility: Visibility::Private,
};
let mut def = FunctionDefinition::normal(
name,
is_unconstrained,
generics,
parameters,
&BlockExpression { statements: Vec::new() },
where_clause,
return_type,
);
// Trait functions are always public
def.visibility = ItemVisibility::Public;

let mut function = NoirFunction { kind, def };
self.define_function_meta(&mut function, func_id, Some(trait_id));
Expand Down
1 change: 1 addition & 0 deletions compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ impl<'a> ModCollector<'a> {
let impl_method =
NoirFunction::normal(FunctionDefinition::normal(
name,
*is_unconstrained,
generics,
parameters,
body,
Expand Down
31 changes: 29 additions & 2 deletions compiler/noirc_frontend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3046,9 +3046,7 @@ fn errors_once_on_unused_import_that_is_not_accessible() {
mod moo {
struct Foo {}
}
use moo::Foo;
fn main() {}
"#;

Expand All @@ -3061,3 +3059,32 @@ fn errors_once_on_unused_import_that_is_not_accessible() {
))
));
}

#[test]
fn trait_unconstrained_methods_typechecked_correctly() {
// This test checks that we properly track whether a method has been declared as unconstrained on the trait definition
// and preserves that through typechecking.
let src = r#"
trait Foo {
unconstrained fn identity(self) -> Self {
self
}
unconstrained fn foo(self) -> u64;
}
impl Foo for Field {
unconstrained fn foo(self) -> u64 {
self as u64
}
}
unconstrained fn main() {
assert_eq(2.foo() as Field, 2.identity());
}
"#;

let errors = get_program_errors(src);
println!("{errors:?}");
assert_eq!(errors.len(), 0);
}

0 comments on commit 1e654bb

Please sign in to comment.