diff --git a/base/src/types/mod.rs b/base/src/types/mod.rs index 019b0702f8..4fe2bc83af 100644 --- a/base/src/types/mod.rs +++ b/base/src/types/mod.rs @@ -1012,13 +1012,17 @@ where } pub fn alias(name: Id, args: Vec>, typ: T) -> T { + Self::alias_implicit(name, args, typ, false) + } + + pub fn alias_implicit(name: Id, args: Vec>, typ: T, is_implicit: bool) -> T { T::from(Type::Alias(AliasRef { index: 0, group: Arc::from(vec![AliasData { name, args, typ, - is_implicit: false, + is_implicit, }]), })) } diff --git a/check/src/implicits.rs b/check/src/implicits.rs index 33f45bff0c..1a56b2a15f 100644 --- a/check/src/implicits.rs +++ b/check/src/implicits.rs @@ -1,4 +1,4 @@ -use std::{cell::RefCell, convert::TryInto, fmt, rc::Rc, sync::Arc}; +use std::{convert::TryInto, fmt, rc::Rc, sync::Arc}; use {itertools::Itertools, smallvec::SmallVec}; @@ -856,20 +856,17 @@ impl<'a> ImplicitResolver<'a> { metadata: Option<&'m Metadata>, typ: &RcType, ) -> Option> { - let has_implicit_attribute = - |metadata: &Metadata| metadata.get_attribute("implicit").is_some(); - let mut is_implicit = metadata.map(&has_implicit_attribute).unwrap_or(false); - - if !is_implicit { - // Look at the type without any implicit arguments - let mut iter = types::implicit_arg_iter(typ.remove_forall()); - for _ in iter.by_ref() {} - is_implicit = iter - .typ - .remove_forall() - .applied_alias() - .map_or(false, |alias| alias.is_implicit()); - } + // Look at the type without any implicit arguments + let mut iter = types::implicit_arg_iter(typ.remove_forall()); + for _ in iter.by_ref() {} + let is_implicit = iter + .typ + .remove_forall() + .applied_alias() + .map_or(false, |alias| alias.is_implicit()) + || metadata + .and_then(|metadata: &Metadata| metadata.get_attribute("implicit")) + .is_some(); if is_implicit { Some(metadata.and_then(|m| m.definition.as_ref())) diff --git a/check/src/typecheck.rs b/check/src/typecheck.rs index fa71a3a220..fed212e28c 100644 --- a/check/src/typecheck.rs +++ b/check/src/typecheck.rs @@ -2123,6 +2123,8 @@ impl<'a> Typecheck<'a> { let mut alias = types::translate_alias(&bind.alias.value, |typ| self.translate_ast_type(typ)); + alias.is_implicit = bind.metadata.get_attribute("implicit").is_some(); + let replacement = self.create_unifiable_signature_with( // alias.unresolved_type() is a dummy in this context alias @@ -2144,16 +2146,7 @@ impl<'a> Typecheck<'a> { let arc_alias_group = Alias::group( resolved_aliases .iter() - .zip( - bindings - .iter() - .map(|bind| bind.metadata.get_attribute("implicit").is_some()), - ) - .map(|(a, is_implicit)| { - let mut alias_data = types::translate_alias(&a, |t| self.translate_rc_type(t)); - alias_data.is_implicit = is_implicit; - alias_data - }) + .map(|a| types::translate_alias(&a, |t| self.translate_rc_type(t))) .collect(), ); let alias_group = self.subs.alias_group(resolved_aliases); diff --git a/check/tests/implicits.rs b/check/tests/implicits.rs index fa16d50c85..edba3eb27b 100644 --- a/check/tests/implicits.rs +++ b/check/tests/implicits.rs @@ -212,7 +212,7 @@ f (Test ()) "#; let result = support::typecheck(text); - let test = support::alias_variant("Test", &[], &[("Test", &[Type::unit()])]); + let test = support::alias_variant_implicit("Test", &[], &[("Test", &[Type::unit()])], true); assert_eq!(result, Ok(test)); } diff --git a/check/tests/support/mod.rs b/check/tests/support/mod.rs index 09c8c0679b..d594424359 100644 --- a/check/tests/support/mod.rs +++ b/check/tests/support/mod.rs @@ -295,13 +295,18 @@ where #[allow(dead_code)] pub fn alias(s: &str, args: &[&str], typ: ArcType) -> ArcType { + alias_implicit(s, args, typ, false) +} + +pub fn alias_implicit(s: &str, args: &[&str], typ: ArcType, is_implicit: bool) -> ArcType { assert!(s.len() != 0); - Type::alias( + Type::alias_implicit( intern(s), args.iter() .map(|id| Generic::new(intern(id), Kind::typ())) .collect(), typ, + is_implicit, ) } @@ -311,12 +316,21 @@ pub fn variant(arg: &str, types: &[ArcType]) -> Field { } pub fn alias_variant(s: &str, params: &[&str], args: &[(&str, &[ArcType])]) -> ArcType { + alias_variant_implicit(s, params, args, false) +} + +pub fn alias_variant_implicit( + s: &str, + params: &[&str], + args: &[(&str, &[ArcType])], + is_implicit: bool, +) -> ArcType { let variants = Type::variant( args.iter() .map(|(arg, types)| variant(arg, types)) .collect(), ); - alias(s, params, variants) + alias_implicit(s, params, variants, is_implicit) } /// Replace the variable at the `rest` part of a record for easier equality checks