Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions compiler/noirc_frontend/src/ast/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,7 @@ pub struct TypeImpl {
pub struct NoirTraitImpl {
pub impl_generics: UnresolvedGenerics,

pub trait_name: Path,

pub trait_generics: GenericTypeArgs,
pub r#trait: UnresolvedType,

pub object_type: UnresolvedType,

Expand Down Expand Up @@ -247,7 +245,7 @@ impl Display for NoirTraitImpl {
)?;
}

write!(f, " {}{} for {}", self.trait_name, self.trait_generics, self.object_type)?;
write!(f, " {} for {}", self.r#trait, self.object_type)?;
if !self.where_clause.is_empty() {
write!(
f,
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/ast/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ impl NoirTraitImpl {
}

pub fn accept_children(&self, visitor: &mut impl Visitor) {
self.trait_name.accept(visitor);
self.r#trait.accept(visitor);
self.object_type.accept(visitor);

for item in &self.items {
Expand Down
3 changes: 1 addition & 2 deletions compiler/noirc_frontend/src/elaborator/comptime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,7 @@ impl<'context> Elaborator<'context> {
generated_items.trait_impls.push(UnresolvedTraitImpl {
file_id: self.file,
module_id: self.local_module,
trait_generics: trait_impl.trait_generics,
trait_path: trait_impl.trait_name,
r#trait: trait_impl.r#trait,
object_type: trait_impl.object_type,
methods,
generics: trait_impl.impl_generics,
Expand Down
101 changes: 81 additions & 20 deletions compiler/noirc_frontend/src/elaborator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ use crate::{
},
graph::CrateId,
hir::{
def_collector::dc_crate::{
filter_literal_globals, CollectedItems, CompilationError, ImplMap, UnresolvedEnum,
UnresolvedFunctions, UnresolvedGlobal, UnresolvedStruct, UnresolvedTraitImpl,
UnresolvedTypeAlias,
def_collector::{
dc_crate::{
filter_literal_globals, CollectedItems, CompilationError, ImplMap, UnresolvedEnum,
UnresolvedFunctions, UnresolvedGlobal, UnresolvedStruct, UnresolvedTraitImpl,
UnresolvedTypeAlias,
},
errors::DefCollectorErrorKind,
},
def_collector::errors::DefCollectorErrorKind,
def_map::{DefMaps, ModuleData},
def_map::{LocalModuleId, ModuleId, MAIN_FUNCTION},
def_map::{DefMaps, LocalModuleId, ModuleData, ModuleId, MAIN_FUNCTION},
resolution::errors::ResolverError,
scope::ScopeForest as GenericScopeForest,
type_check::{generics::TraitGenerics, TypeCheckError},
Expand Down Expand Up @@ -1458,9 +1459,26 @@ impl<'context> Elaborator<'context> {
}

let trait_generics = trait_impl.resolved_trait_generics.clone();
let ident = match &trait_impl.r#trait.typ {
UnresolvedTypeData::Named(trait_path, _, _) => trait_path.last_ident(),
UnresolvedTypeData::Resolved(quoted_type_id) => {
let typ = self.interner.get_quoted_type(*quoted_type_id);
let name = if let Type::TraitAsType(_, name, _) = typ {
name.to_string()
} else {
typ.to_string()
};
Ident::new(name, trait_impl.r#trait.span)
}
_ => {
// We don't error in this case because an error will be produced later on when
// solving the trait impl trait type
Ident::new(trait_impl.r#trait.to_string(), trait_impl.r#trait.span)
}
};

let resolved_trait_impl = Shared::new(TraitImpl {
ident: trait_impl.trait_path.last_ident(),
ident,
typ: self_type.clone(),
trait_id,
trait_generics,
Expand Down Expand Up @@ -1983,7 +2001,49 @@ impl<'context> Elaborator<'context> {
self.file = trait_impl.file_id;
self.local_module = trait_impl.module_id;

let trait_id = self.resolve_trait_by_path(trait_impl.trait_path.clone());
let (trait_id, mut trait_generics, path_span) = match &trait_impl.r#trait.typ {
UnresolvedTypeData::Named(trait_path, trait_generics, _) => {
let trait_id = self.resolve_trait_by_path(trait_path.clone());
(trait_id, trait_generics.clone(), trait_path.span)
}
UnresolvedTypeData::Resolved(quoted_type_id) => {
let typ = self.interner.get_quoted_type(*quoted_type_id);
let span = trait_impl.r#trait.span;
let Type::TraitAsType(trait_id, _, trait_generics) = typ else {
let found = typ.to_string();
self.push_err(ResolverError::ExpectedTrait { span, found });
continue;
};

// In order to take associated types into account we turn these resolved generics
// into unresolved ones, but ones that point to solved types.
let trait_id = *trait_id;
let trait_generics = trait_generics.clone();
let trait_generics = GenericTypeArgs {
ordered_args: vecmap(&trait_generics.ordered, |typ| {
let quoted_type_id = self.interner.push_quoted_type(typ.clone());
let typ = UnresolvedTypeData::Resolved(quoted_type_id);
UnresolvedType { typ, span }
}),
named_args: vecmap(&trait_generics.named, |named_type| {
let quoted_type_id =
self.interner.push_quoted_type(named_type.typ.clone());
let typ = UnresolvedTypeData::Resolved(quoted_type_id);
(named_type.name.clone(), UnresolvedType { typ, span })
}),
kinds: Vec::new(),
};

(Some(trait_id), trait_generics, span)
}
_ => {
let span = trait_impl.r#trait.span;
let found = trait_impl.r#trait.typ.to_string();
self.push_err(ResolverError::ExpectedTrait { span, found });
continue;
}
};

trait_impl.trait_id = trait_id;
let unresolved_type = trait_impl.object_type.clone();

Expand All @@ -2006,14 +2066,12 @@ impl<'context> Elaborator<'context> {
method.def.where_clause.append(&mut trait_impl.where_clause.clone());
}

// Add each associated type to the list of named type arguments
let mut trait_generics = trait_impl.trait_generics.clone();
trait_generics.named_args.extend(self.take_unresolved_associated_types(trait_impl));

let impl_id = self.interner.next_trait_impl_id();
self.current_trait_impl = Some(impl_id);

let path_span = trait_impl.trait_path.span;
// Add each associated type to the list of named type arguments
trait_generics.named_args.extend(self.take_unresolved_associated_types(trait_impl));

let (ordered_generics, named_generics) = trait_impl
.trait_id
.map(|trait_id| {
Expand All @@ -2038,12 +2096,15 @@ impl<'context> Elaborator<'context> {
self.generics.clear();

if let Some(trait_id) = trait_id {
let trait_name = trait_impl.trait_path.last_ident();
self.interner.add_trait_reference(
trait_id,
Location::new(trait_name.span(), trait_impl.file_id),
trait_name.is_self_type_name(),
);
let (span, is_self_type_name) = match &trait_impl.r#trait.typ {
UnresolvedTypeData::Named(trait_path, _, _) => {
let trait_name = trait_path.last_ident();
(trait_name.span(), trait_name.is_self_type_name())
}
_ => (trait_impl.r#trait.span, false),
};
let location = Location::new(span, trait_impl.file_id);
self.interner.add_trait_reference(trait_id, location, is_self_type_name);
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions compiler/noirc_frontend/src/hir/comptime/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,11 @@ impl Value {
Value::UnresolvedType(typ) => {
Token::InternedUnresolvedTypeData(interner.push_unresolved_type_data(typ))
}
Value::TraitConstraint(trait_id, generics) => {
let name = Rc::new(interner.get_trait(trait_id).name.0.contents.clone());
let typ = Type::TraitAsType(trait_id, name, generics);
Token::QuotedType(interner.push_quoted_type(typ))
Comment thread
jfecher marked this conversation as resolved.
}
Value::TypedExpr(TypedExpr::ExprId(expr_id)) => Token::UnquoteMarker(expr_id),
Value::U1(bool) => Token::Bool(bool),
Value::U8(value) => Token::Int((value as u128).into()),
Expand Down
7 changes: 3 additions & 4 deletions compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ use crate::node_interner::{
};

use crate::ast::{
ExpressionKind, GenericTypeArgs, Ident, ItemVisibility, LetStatement, Literal, NoirFunction,
NoirStruct, NoirTrait, NoirTypeAlias, Path, PathKind, PathSegment, UnresolvedGenerics,
ExpressionKind, Ident, ItemVisibility, LetStatement, Literal, NoirFunction, NoirStruct,
NoirTrait, NoirTypeAlias, Path, PathKind, PathSegment, UnresolvedGenerics,
UnresolvedTraitConstraint, UnresolvedType, UnsupportedNumericGenericType,
};

Expand Down Expand Up @@ -83,8 +83,7 @@ pub struct UnresolvedTrait {
pub struct UnresolvedTraitImpl {
pub file_id: FileId,
pub module_id: LocalModuleId,
pub trait_generics: GenericTypeArgs,
pub trait_path: Path,
pub r#trait: UnresolvedType,
pub object_type: UnresolvedType,
pub methods: UnresolvedFunctions,
pub generics: UnresolvedGenerics,
Expand Down
5 changes: 1 addition & 4 deletions compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,6 @@ impl<'a> ModCollector<'a> {
let mut errors = Vec::new();

for mut trait_impl in impls {
let trait_name = trait_impl.trait_name.clone();

let (mut unresolved_functions, associated_types, associated_constants) =
collect_trait_impl_items(
&mut context.def_interner,
Expand Down Expand Up @@ -233,12 +231,11 @@ impl<'a> ModCollector<'a> {
let unresolved_trait_impl = UnresolvedTraitImpl {
file_id: self.file_id,
module_id: self.module_id,
trait_path: trait_name,
r#trait: trait_impl.r#trait,
methods: unresolved_functions,
object_type: trait_impl.object_type,
generics: trait_impl.impl_generics,
where_clause: trait_impl.where_clause,
trait_generics: trait_impl.trait_generics,
associated_constants,
associated_types,

Expand Down
9 changes: 9 additions & 0 deletions compiler/noirc_frontend/src/hir/resolution/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ pub enum ResolverError {
},
#[error("`loop` statements are not yet implemented")]
LoopNotYetSupported { span: Span },
#[error("Expected a trait but found {found}")]
ExpectedTrait { found: String, span: Span },
}

impl ResolverError {
Expand Down Expand Up @@ -687,6 +689,13 @@ impl<'a> From<&'a ResolverError> for Diagnostic {
*span)

}
ResolverError::ExpectedTrait { found, span } => {
Diagnostic::simple_error(
format!("Expected a trait, found {found}"),
String::new(),
*span)

}
}
}
}
2 changes: 0 additions & 2 deletions compiler/noirc_frontend/src/parser/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ pub enum ParserErrorReason {
ExpectedMutAfterAmpersand { found: Token },
#[error("Invalid left-hand side of assignment")]
InvalidLeftHandSideOfAssignment,
#[error("Expected trait, found {found}")]
ExpectedTrait { found: String },
#[error("Visibility `{visibility}` is not followed by an item")]
VisibilityNotFollowedByAnItem { visibility: ItemVisibility },
#[error("`unconstrained` is not followed by an item")]
Expand Down
Loading