Skip to content

Commit

Permalink
perf(check): Avoid looking through metadata when checking for an impl…
Browse files Browse the repository at this point in the history
…icit type
  • Loading branch information
Marwes committed Aug 31, 2019
1 parent d69a52e commit 4a3662e
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 29 deletions.
6 changes: 5 additions & 1 deletion base/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1012,13 +1012,17 @@ where
}

pub fn alias(name: Id, args: Vec<Generic<Id>>, typ: T) -> T {
Self::alias_implicit(name, args, typ, false)
}

pub fn alias_implicit(name: Id, args: Vec<Generic<Id>>, 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,
}]),
}))
}
Expand Down
27 changes: 12 additions & 15 deletions check/src/implicits.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -856,20 +856,17 @@ impl<'a> ImplicitResolver<'a> {
metadata: Option<&'m Metadata>,
typ: &RcType,
) -> Option<Option<&'m Symbol>> {
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()))
Expand Down
13 changes: 3 additions & 10 deletions check/src/typecheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion check/tests/implicits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

Expand Down
18 changes: 16 additions & 2 deletions check/tests/support/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
}

Expand All @@ -311,12 +316,21 @@ pub fn variant(arg: &str, types: &[ArcType]) -> Field<Symbol, ArcType> {
}

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
Expand Down

0 comments on commit 4a3662e

Please sign in to comment.