Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: try_unify no longer binds types on failure #3697

Merged
merged 13 commits into from
Dec 7, 2023
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ pub(crate) fn check_methods_signatures(
let self_type = resolver.get_self_type().expect("trait impl must have a Self type");

// Temporarily bind the trait's Self type to self_type so we can type check
let _ = the_trait.self_type_typevar.borrow_mut().bind_to(self_type.clone(), the_trait.span);
the_trait.self_type_typevar.bind(self_type.clone());

for (file_id, func_id) in impl_methods {
let impl_method = resolver.interner.function_meta(func_id);
Expand Down Expand Up @@ -494,5 +494,5 @@ pub(crate) fn check_methods_signatures(
}
}

the_trait.self_type_typevar.borrow_mut().unbind(the_trait.self_type_typevar_id);
the_trait.self_type_typevar.unbind(the_trait.self_type_typevar_id);
}
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/hir/resolution/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
def_map::{CrateDefMap, ModuleId},
},
node_interner::{FuncId, NodeInterner, TraitImplId},
Shared, Type, TypeBinding,
Type, TypeVariable,
};

use super::{path_resolver::StandardPathResolver, resolver::Resolver};
Expand All @@ -24,7 +24,7 @@ pub(crate) fn resolve_function_set(
mut unresolved_functions: UnresolvedFunctions,
self_type: Option<Type>,
trait_impl_id: Option<TraitImplId>,
impl_generics: Vec<(Rc<String>, Shared<TypeBinding>, Span)>,
impl_generics: Vec<(Rc<String>, TypeVariable, Span)>,
errors: &mut Vec<(CompilationError, FileId)>,
) -> Vec<(FileId, FuncId)> {
let file_id = unresolved_functions.file_id;
Expand Down
9 changes: 3 additions & 6 deletions compiler/noirc_frontend/src/hir/resolution/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ impl<'a> Resolver<'a> {
match length {
None => {
let id = self.interner.next_type_variable_id();
let typevar = Shared::new(TypeBinding::Unbound(id));
let typevar = TypeVariable::unbound(id);
new_variables.push((id, typevar.clone()));

// 'Named'Generic is a bit of a misnomer here, we want a type variable that
Expand Down Expand Up @@ -682,7 +682,7 @@ impl<'a> Resolver<'a> {
vecmap(generics, |generic| {
// Map the generic to a fresh type variable
let id = self.interner.next_type_variable_id();
let typevar = Shared::new(TypeBinding::Unbound(id));
let typevar = TypeVariable::unbound(id);
let span = generic.0.span();

// Check for name collisions of this generic
Expand Down Expand Up @@ -925,10 +925,7 @@ impl<'a> Resolver<'a> {
found.into_iter().collect()
}

fn find_numeric_generics_in_type(
typ: &Type,
found: &mut BTreeMap<String, Shared<TypeBinding>>,
) {
fn find_numeric_generics_in_type(typ: &Type, found: &mut BTreeMap<String, TypeVariable>) {
match typ {
Type::FieldElement
| Type::Integer(_, _)
Expand Down
16 changes: 12 additions & 4 deletions compiler/noirc_frontend/src/hir/type_check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
types::Type,
},
node_interner::{DefinitionKind, ExprId, FuncId, TraitId, TraitMethodId},
BinaryOpKind, Signedness, TypeBinding, TypeVariableKind, UnaryOp,
BinaryOpKind, Signedness, TypeBinding, TypeBindings, TypeVariableKind, UnaryOp,
};

use super::{errors::TypeCheckError, TypeChecker};
Expand Down Expand Up @@ -778,7 +778,11 @@ impl<'interner> TypeChecker<'interner> {
}));
}

if other.try_bind_to_polymorphic_int(int).is_ok() || other == &Type::Error {
let mut bindings = TypeBindings::new();
if other.try_bind_to_polymorphic_int(int, &mut bindings).is_ok()
|| other == &Type::Error
{
Type::apply_type_bindings(bindings);
Ok(Bool)
} else {
Err(TypeCheckError::TypeMismatchWithSource {
Expand Down Expand Up @@ -1009,7 +1013,7 @@ impl<'interner> TypeChecker<'interner> {
let env_type = self.interner.next_type_variable();
let expected = Type::Function(args, Box::new(ret.clone()), Box::new(env_type));

if let Err(error) = binding.borrow_mut().bind_to(expected, span) {
if let Err(error) = binding.try_bind(expected, span) {
self.errors.push(error);
}
ret
Expand Down Expand Up @@ -1077,7 +1081,11 @@ impl<'interner> TypeChecker<'interner> {
}));
}

if other.try_bind_to_polymorphic_int(int).is_ok() || other == &Type::Error {
let mut bindings = TypeBindings::new();
if other.try_bind_to_polymorphic_int(int, &mut bindings).is_ok()
|| other == &Type::Error
{
Type::apply_type_bindings(bindings);
Ok(other.clone())
} else {
Err(TypeCheckError::TypeMismatchWithSource {
Expand Down
5 changes: 1 addition & 4 deletions compiler/noirc_frontend/src/hir/type_check/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use crate::hir_def::stmt::{
};
use crate::hir_def::types::Type;
use crate::node_interner::{DefinitionId, ExprId, StmtId};
use crate::{Shared, TypeBinding, TypeVariableKind};

use super::errors::{Source, TypeCheckError};
use super::TypeChecker;
Expand Down Expand Up @@ -71,9 +70,7 @@ impl<'interner> TypeChecker<'interner> {
expr_span: range_span,
});

let fresh_id = self.interner.next_type_variable_id();
let type_variable = Shared::new(TypeBinding::Unbound(fresh_id));
let expected_type = Type::TypeVariable(type_variable, TypeVariableKind::IntegerOrField);
let expected_type = Type::polymorphic_integer(self.interner);

self.unify(&start_range_type, &expected_type, || {
TypeCheckError::TypeCannotBeUsed {
Expand Down
Loading
Loading