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
8 changes: 0 additions & 8 deletions compiler/noirc_frontend/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,14 +339,6 @@ impl std::fmt::Display for UnresolvedTypeExpression {
}

impl UnresolvedType {
pub fn is_synthesized(&self) -> bool {
match &self.typ {
UnresolvedTypeData::Reference(ty, _) => ty.is_synthesized(),
UnresolvedTypeData::Named(_, _, synthesized) => *synthesized,
_ => false,
}
}

pub(crate) fn is_type_expression(&self) -> bool {
matches!(&self.typ, UnresolvedTypeData::Expression(_))
}
Expand Down
39 changes: 38 additions & 1 deletion compiler/noirc_frontend/src/elaborator/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl Elaborator<'_> {

/// Add the given generics to scope.
/// Each generic will have a fresh `Shared<TypeBinding>` associated with it.
pub fn add_generics(&mut self, generics: &UnresolvedGenerics) -> Generics {
pub(super) fn add_generics(&mut self, generics: &UnresolvedGenerics) -> Generics {
vecmap(generics, |generic| {
let mut is_error = false;
let (type_var, name) = match self.resolve_generic(generic) {
Expand Down Expand Up @@ -68,6 +68,43 @@ impl Elaborator<'_> {
})
}

pub(super) fn add_existing_generics(
&mut self,
unresolved_generics: &UnresolvedGenerics,
generics: &Generics,
) {
assert_eq!(unresolved_generics.len(), generics.len());

for (unresolved_generic, generic) in unresolved_generics.iter().zip(generics) {
self.add_existing_generic(unresolved_generic, unresolved_generic.location(), generic);
}
}

pub(super) fn add_existing_generic(
&mut self,
unresolved_generic: &UnresolvedGeneric,
location: Location,
resolved_generic: &ResolvedGeneric,
) {
if let Some(name) = unresolved_generic.ident().ident() {
let name = name.as_str();

if let Some(generic) = self.find_generic(name) {
self.push_err(ResolverError::DuplicateDefinition {
name: name.to_string(),
first_location: generic.location,
second_location: location,
});
} else {
self.generics.push(resolved_generic.clone());
}
}
}

pub(super) fn find_generic(&self, target_name: &str) -> Option<&ResolvedGeneric> {
self.generics.iter().find(|generic| generic.name.as_ref() == target_name)
}

pub(super) fn resolve_generic(
&mut self,
generic: &UnresolvedGeneric,
Expand Down
10 changes: 3 additions & 7 deletions compiler/noirc_frontend/src/elaborator/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,10 @@ impl Elaborator<'_> {

let wildcard_allowed = false;
let fields = vecmap(&unresolved.fields, |field| {
let ident = &field.item.name;
let typ = &field.item.typ;
let name = field.item.name.clone();
let typ = this.resolve_type(field.item.typ.clone(), wildcard_allowed);
let visibility = field.item.visibility;
StructField {
visibility,
name: ident.clone(),
typ: this.resolve_type(typ.clone(), wildcard_allowed),
}
StructField { visibility, name, typ }
});

this.resolving_ids.remove(&struct_id);
Expand Down
23 changes: 22 additions & 1 deletion compiler/noirc_frontend/src/elaborator/trait_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::{
Kind, NamedGeneric, ResolvedGeneric, Shared, TypeBindings, TypeVariable,
ast::{GenericTypeArgs, Ident, UnresolvedType, UnresolvedTypeData, UnresolvedTypeExpression},
elaborator::types::bind_ordered_generics,
elaborator::{PathResolutionMode, types::bind_ordered_generics},
graph::CrateId,
hir::{
def_collector::{
Expand Down Expand Up @@ -880,4 +880,25 @@ impl Elaborator<'_> {

trait_impl.unresolved_associated_types = associated_types;
}

/// Identical to [Self::resolve_type_or_trait_args_inner] but does not allow
/// associated types to be elided since trait impls must specify them.
fn resolve_trait_args_from_trait_impl(
&mut self,
args: GenericTypeArgs,
item: TraitId,
location: Location,
) -> (Vec<Type>, Vec<NamedType>) {
let mode = PathResolutionMode::MarkAsReferenced;
let allow_implicit_named_args = false;
let wildcard_allowed = true;
self.resolve_type_or_trait_args_inner(
args,
item,
location,
allow_implicit_named_args,
mode,
wildcard_allowed,
)
}
}
91 changes: 8 additions & 83 deletions compiler/noirc_frontend/src/elaborator/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@ use noirc_errors::Location;
use rustc_hash::FxHashMap as HashMap;

use crate::{
Generics, Kind, NamedGeneric, ResolvedGeneric, Type, TypeBinding, TypeBindings,
UnificationError,
Kind, NamedGeneric, ResolvedGeneric, Type, TypeBinding, TypeBindings, UnificationError,
ast::{
AsTraitPath, BinaryOpKind, GenericTypeArgs, Ident, PathKind, UnaryOp, UnresolvedGeneric,
UnresolvedGenerics, UnresolvedType, UnresolvedTypeData, UnresolvedTypeExpression,
WILDCARD_TYPE,
AsTraitPath, BinaryOpKind, GenericTypeArgs, Ident, PathKind, UnaryOp, UnresolvedType,
UnresolvedTypeData, UnresolvedTypeExpression, WILDCARD_TYPE,
},
elaborator::UnstableFeature,
hir::{
Expand Down Expand Up @@ -62,6 +60,7 @@ pub(super) enum TraitPathResolutionMethod {
}

impl Elaborator<'_> {
/// Resolves a type and marks it, and any generic types it contains, as referenced.
pub(crate) fn resolve_type(&mut self, typ: UnresolvedType, wildcard_allowed: bool) -> Type {
self.resolve_type_inner(
typ,
Expand All @@ -71,6 +70,7 @@ impl Elaborator<'_> {
)
}

/// Resolves a type and marks it, and any generic types it contains, as used.
pub(crate) fn use_type(&mut self, typ: UnresolvedType, wildcard_allowed: bool) -> Type {
self.use_type_with_kind(typ, &Kind::Normal, wildcard_allowed)
}
Expand Down Expand Up @@ -109,8 +109,7 @@ impl Elaborator<'_> {
self.resolve_type_inner(typ, kind, PathResolutionMode::MarkAsReferenced, wildcard_allowed)
}

/// Translates an UnresolvedType into a Type and appends any
/// freshly created TypeVariables created to new_variables.
/// Translates an UnresolvedType into a Type.
fn resolve_type_with_kind_inner(
&mut self,
typ: UnresolvedType,
Expand Down Expand Up @@ -251,10 +250,6 @@ impl Elaborator<'_> {
self.check_kind(resolved_type, kind, location)
}

pub fn find_generic(&self, target_name: &str) -> Option<&ResolvedGeneric> {
self.generics.iter().find(|generic| generic.name.as_ref() == target_name)
}

// Resolve Self::Foo to an associated type on the current trait or trait impl
fn lookup_associated_type_on_self(&self, path: &TypedPath) -> Option<Type> {
if path.segments.len() == 2 && path.first_name() == Some(SELF_TYPE_NAME) {
Expand Down Expand Up @@ -457,27 +452,6 @@ impl Elaborator<'_> {
}
}

/// Identical to `resolve_type_args` but does not allow
/// associated types to be elided since trait impls must specify them.
pub(super) fn resolve_trait_args_from_trait_impl(
&mut self,
args: GenericTypeArgs,
item: TraitId,
location: Location,
) -> (Vec<Type>, Vec<NamedType>) {
let mode = PathResolutionMode::MarkAsReferenced;
let allow_implicit_named_args = false;
let wildcard_allowed = true;
self.resolve_type_or_trait_args_inner(
args,
item,
location,
allow_implicit_named_args,
mode,
wildcard_allowed,
)
}

pub(super) fn use_type_args(
&mut self,
args: GenericTypeArgs,
Expand Down Expand Up @@ -1041,22 +1015,6 @@ impl Elaborator<'_> {
}
}

/// Do not apply type bindings even after a successful unification.
/// This function is used by the interpreter for some comptime code
/// which can change types e.g. on each iteration of a for loop.
pub fn unify_without_applying_bindings(
&mut self,
actual: &Type,
expected: &Type,
make_error: impl FnOnce() -> TypeCheckError,
) {
let mut bindings = TypeBindings::default();
if actual.try_unify(expected, &mut bindings).is_err() {
let error: CompilationError = make_error().into();
self.push_err(error);
}
}

/// Wrapper of Type::unify_with_coercions using self.errors
pub(super) fn unify_with_coercions(
&mut self,
Expand Down Expand Up @@ -2330,39 +2288,6 @@ impl Elaborator<'_> {
}
}

pub fn add_existing_generics(
&mut self,
unresolved_generics: &UnresolvedGenerics,
generics: &Generics,
) {
assert_eq!(unresolved_generics.len(), generics.len());

for (unresolved_generic, generic) in unresolved_generics.iter().zip(generics) {
self.add_existing_generic(unresolved_generic, unresolved_generic.location(), generic);
}
}

pub fn add_existing_generic(
&mut self,
unresolved_generic: &UnresolvedGeneric,
location: Location,
resolved_generic: &ResolvedGeneric,
) {
if let Some(name) = unresolved_generic.ident().ident() {
let name = name.as_str();

if let Some(generic) = self.find_generic(name) {
self.push_err(ResolverError::DuplicateDefinition {
name: name.to_string(),
first_location: generic.location,
second_location: location,
});
} else {
self.generics.push(resolved_generic.clone());
}
}
}

pub fn bind_generics_from_trait_constraint(
&self,
constraint: &TraitConstraint,
Expand Down Expand Up @@ -2468,7 +2393,7 @@ impl Elaborator<'_> {
}
}

pub(crate) fn bind_ordered_generics(
pub(super) fn bind_ordered_generics(
params: &[ResolvedGeneric],
args: &[Type],
bindings: &mut TypeBindings,
Expand All @@ -2480,7 +2405,7 @@ pub(crate) fn bind_ordered_generics(
}
}

pub(crate) fn bind_named_generics(
fn bind_named_generics(
mut params: Vec<ResolvedGeneric>,
args: &[NamedType],
bindings: &mut TypeBindings,
Expand Down
12 changes: 8 additions & 4 deletions compiler/noirc_frontend/src/hir/comptime/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1039,14 +1039,18 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
}
}

/// This function is used by the interpreter for some comptime code
/// which can change types e.g. on each iteration of a for loop.
fn unify_without_binding(&mut self, actual: &Type, expected: &Type, location: Location) {
self.elaborator.unify_without_applying_bindings(actual, expected, || {
TypeCheckError::TypeMismatch {
let mut bindings = TypeBindings::default();
if actual.try_unify(expected, &mut bindings).is_err() {
let error = TypeCheckError::TypeMismatch {
expected_typ: expected.to_string(),
expr_typ: actual.to_string(),
expr_location: location,
}
});
};
self.elaborator.push_err(error);
}
}

fn evaluate_cast(&mut self, cast: &HirCastExpression, id: ExprId) -> IResult<Value> {
Expand Down
Loading