From e476b1e0b8d2660d163360adbb0e6d21b04af95c Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Sat, 16 Dec 2017 00:08:12 +0100 Subject: [PATCH] fix(check): Don't panic if a type is undefined in a variant --- base/src/lib.rs | 2 ++ base/src/macros.rs | 1 - base/src/resolve.rs | 4 +-- base/src/types/mod.rs | 74 +++++++++++++++++++++++-------------------- check/tests/fail.rs | 13 ++++++++ 5 files changed, 55 insertions(+), 39 deletions(-) diff --git a/base/src/lib.rs b/base/src/lib.rs index 2a28392a1b..9dc5645eec 100644 --- a/base/src/lib.rs +++ b/base/src/lib.rs @@ -5,6 +5,8 @@ #[macro_use] extern crate collect_mac; extern crate itertools; +#[macro_use] +extern crate log; extern crate pretty; #[macro_use] extern crate quick_error; diff --git a/base/src/macros.rs b/base/src/macros.rs index 220ebd423a..5aee43f795 100644 --- a/base/src/macros.rs +++ b/base/src/macros.rs @@ -1,4 +1,3 @@ - #[macro_export] macro_rules! ice { () => ({ diff --git a/base/src/resolve.rs b/base/src/resolve.rs index 59cc76a018..7bd4c30c75 100644 --- a/base/src/resolve.rs +++ b/base/src/resolve.rs @@ -37,9 +37,7 @@ where Ok(Some(alias)) if !canonical(alias) => alias .typ() .apply_args(&typ.unapplied_args()) - .map(|typ| { - Cow::Owned(canonical_alias(env, &typ, canonical).into_owned()) - }) + .map(|typ| Cow::Owned(canonical_alias(env, &typ, canonical).into_owned())) .unwrap_or(Cow::Borrowed(typ)), _ => Cow::Borrowed(typ), } diff --git a/base/src/types/mod.rs b/base/src/types/mod.rs index e0a0aa02d1..2aba543105 100644 --- a/base/src/types/mod.rs +++ b/base/src/types/mod.rs @@ -411,14 +411,18 @@ where Type::Ident(ref id) => { // Replace `Ident` with the alias it resolves to so that a `TypeEnv` is not // needed to resolve the type later on - let index = self.group - .iter() - .position(|alias| alias.name == *id) - .expect("ICE: Alias group were not able to resolve an identifier"); - Some(T::from(Type::Alias(AliasRef { - index: index, - group: self.group.clone(), - }))) + let replacement = self.group.iter().position(|alias| alias.name == *id).map( + |index| { + T::from(Type::Alias(AliasRef { + index: index, + group: self.group.clone(), + })) + }, + ); + if replacement.is_none() { + info!("Alias group were not able to resolve an identifier"); + } + replacement } _ => None, } @@ -1885,15 +1889,15 @@ where } f.walk(rest); } - Type::Hole | - Type::Opaque | - Type::Builtin(_) | - Type::Variable(_) | - Type::Generic(_) | - Type::Skolem(_) | - Type::Ident(_) | - Type::Alias(_) | - Type::EmptyRow => (), + Type::Hole + | Type::Opaque + | Type::Builtin(_) + | Type::Variable(_) + | Type::Generic(_) + | Type::Skolem(_) + | Type::Ident(_) + | Type::Alias(_) + | Type::EmptyRow => (), } } @@ -1922,15 +1926,15 @@ where } f.walk_mut(rest); } - Type::Hole | - Type::Opaque | - Type::Builtin(_) | - Type::Variable(_) | - Type::Generic(_) | - Type::Skolem(_) | - Type::Ident(_) | - Type::Alias(_) | - Type::EmptyRow => (), + Type::Hole + | Type::Opaque + | Type::Builtin(_) + | Type::Variable(_) + | Type::Generic(_) + | Type::Skolem(_) + | Type::Ident(_) + | Type::Alias(_) + | Type::EmptyRow => (), } } @@ -2077,15 +2081,15 @@ where Type::extend_row(types.clone(), fields, rest) }) } - Type::Hole | - Type::Opaque | - Type::Builtin(_) | - Type::Variable(_) | - Type::Skolem(_) | - Type::Generic(_) | - Type::Ident(_) | - Type::Alias(_) | - Type::EmptyRow => None, + Type::Hole + | Type::Opaque + | Type::Builtin(_) + | Type::Variable(_) + | Type::Skolem(_) + | Type::Generic(_) + | Type::Ident(_) + | Type::Alias(_) + | Type::EmptyRow => None, } } diff --git a/check/tests/fail.rs b/check/tests/fail.rs index bb0311c4c3..4c145913ba 100644 --- a/check/tests/fail.rs +++ b/check/tests/fail.rs @@ -551,3 +551,16 @@ do x = 1 assert_unify_err!(result, TypeMismatch(..)); } + +#[test] +fn undefined_type_in_variant() { + let _ = ::env_logger::init(); + + let text = r#" +type Test = | Test In +2 +"#; + let result = support::typecheck(text); + + assert_err!(result, UndefinedType(..)); +}