de-alias when diffing with a non-alias

When one of the types in a comparison is an alias, elm does not de-alias it.
That is really annoying if e.g. the alias is of a record and you used an invalid field: the field suggestion error does not kick in
This commit is contained in:
Folkert 2020-04-11 23:51:51 +02:00
parent 2811f978a4
commit d15bd07bf4
5 changed files with 33 additions and 12 deletions

View file

@ -524,6 +524,9 @@ pub fn constrain_expr(
constraints.push(ast_con); constraints.push(ast_con);
for (index, when_branch) in branches.iter().enumerate() { for (index, when_branch) in branches.iter().enumerate() {
let pattern_region =
Region::across_all(when_branch.patterns.iter().map(|v| &v.region));
let branch_con = constrain_when_branch( let branch_con = constrain_when_branch(
env, env,
when_branch.value.region, when_branch.value.region,
@ -533,12 +536,14 @@ pub fn constrain_expr(
index: Index::zero_based(index), index: Index::zero_based(index),
}, },
cond_type.clone(), cond_type.clone(),
Region::across_all(when_branch.patterns.iter().map(|v| &v.region)), pattern_region,
), ),
FromAnnotation( FromAnnotation(
name.clone(), name.clone(),
*arity, *arity,
TypedWhenBranch(Index::zero_based(index)), TypedWhenBranch {
index: Index::zero_based(index),
},
typ.clone(), typ.clone(),
), ),
); );
@ -552,6 +557,8 @@ pub fn constrain_expr(
let mut branch_cons = Vec::with_capacity(branches.len()); let mut branch_cons = Vec::with_capacity(branches.len());
for (index, when_branch) in branches.iter().enumerate() { for (index, when_branch) in branches.iter().enumerate() {
let pattern_region =
Region::across_all(when_branch.patterns.iter().map(|v| &v.region));
let branch_con = constrain_when_branch( let branch_con = constrain_when_branch(
env, env,
region, region,
@ -561,7 +568,7 @@ pub fn constrain_expr(
index: Index::zero_based(index), index: Index::zero_based(index),
}, },
cond_type.clone(), cond_type.clone(),
Region::across_all(when_branch.patterns.iter().map(|v| &v.region)), pattern_region,
), ),
ForReason( ForReason(
Reason::WhenBranch { Reason::WhenBranch {

View file

@ -1085,6 +1085,9 @@ pub fn constrain_expr(
)); ));
for (index, when_branch) in branches.iter().enumerate() { for (index, when_branch) in branches.iter().enumerate() {
let pattern_region =
Region::across_all(when_branch.patterns.iter().map(|v| &v.region));
let branch_con = constrain_when_branch( let branch_con = constrain_when_branch(
var_store, var_store,
var_usage, var_usage,
@ -1097,12 +1100,14 @@ pub fn constrain_expr(
index: Index::zero_based(index), index: Index::zero_based(index),
}, },
cond_type.clone(), cond_type.clone(),
region, pattern_region,
), ),
Expected::FromAnnotation( Expected::FromAnnotation(
name.clone(), name.clone(),
*arity, *arity,
TypedWhenBranch(Index::zero_based(index)), TypedWhenBranch {
index: Index::zero_based(index),
},
typ.clone(), typ.clone(),
), ),
); );
@ -1120,6 +1125,8 @@ pub fn constrain_expr(
let mut branch_cons = Vec::with_capacity(branches.len()); let mut branch_cons = Vec::with_capacity(branches.len());
for (index, when_branch) in branches.iter().enumerate() { for (index, when_branch) in branches.iter().enumerate() {
let pattern_region =
Region::across_all(when_branch.patterns.iter().map(|v| &v.region));
let branch_con = constrain_when_branch( let branch_con = constrain_when_branch(
var_store, var_store,
var_usage, var_usage,
@ -1132,7 +1139,7 @@ pub fn constrain_expr(
index: Index::zero_based(index), index: Index::zero_based(index),
}, },
cond_type.clone(), cond_type.clone(),
region, pattern_region,
), ),
Expected::ForReason( Expected::ForReason(
Reason::WhenBranch { Reason::WhenBranch {

View file

@ -462,7 +462,7 @@ impl<'a> RocDocAllocator<'a> {
self.intersperse(docs, self.line()) self.intersperse(docs, self.line())
} }
/// live vcat, but adds a double line break between elements. Visually this means an empty line /// like vcat, but adds a double line break between elements. Visually this means an empty line
/// between elements. /// between elements.
pub fn stack<A, I>(&'a self, docs: I) -> DocBuilder<'a, Self, A> pub fn stack<A, I>(&'a self, docs: I) -> DocBuilder<'a, Self, A>
where where

View file

@ -170,7 +170,7 @@ fn to_expr_report<'b>(
alloc.keyword("if"), alloc.keyword("if"),
alloc.text(" expression:"), alloc.text(" expression:"),
]), ]),
TypedWhenBranch(index) => alloc.concat(vec![ TypedWhenBranch { index } => alloc.concat(vec![
alloc.string(index.ordinal()), alloc.string(index.ordinal()),
alloc.reflow(" branch of this "), alloc.reflow(" branch of this "),
alloc.keyword("when"), alloc.keyword("when"),
@ -185,7 +185,7 @@ fn to_expr_report<'b>(
let it_is = match annotation_source { let it_is = match annotation_source {
TypedIfBranch { index, .. } => format!("The {} branch is", index.ordinal()), TypedIfBranch { index, .. } => format!("The {} branch is", index.ordinal()),
TypedWhenBranch(index) => format!("The {} branch is", index.ordinal()), TypedWhenBranch { index, .. } => format!("The {} branch is", index.ordinal()),
TypedBody => "The body is".into(), TypedBody => "The body is".into(),
}; };
@ -1319,6 +1319,15 @@ fn to_diff<'b>(
} }
} }
(Alias(symbol, _, actual), other) if !symbol.module_id().is_builtin() => {
// when diffing an alias with a non-alias, de-alias
to_diff(alloc, parens, *actual, other)
}
(other, Alias(symbol, _, actual)) if !symbol.module_id().is_builtin() => {
// when diffing an alias with a non-alias, de-alias
to_diff(alloc, parens, other, *actual)
}
(Record(fields1, ext1), Record(fields2, ext2)) => { (Record(fields1, ext1), Record(fields2, ext2)) => {
diff_record(alloc, fields1, ext1, fields2, ext2) diff_record(alloc, fields1, ext1, fields2, ext2)
} }

View file

@ -605,7 +605,7 @@ pub enum PReason {
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum AnnotationSource { pub enum AnnotationSource {
TypedIfBranch { index: Index, num_branches: usize }, TypedIfBranch { index: Index, num_branches: usize },
TypedWhenBranch(Index), TypedWhenBranch { index: Index },
TypedBody, TypedBody,
} }
@ -619,8 +619,6 @@ pub enum Reason {
name: Option<Symbol>, name: Option<Symbol>,
arity: u8, arity: u8,
}, },
// BinOpArg(BinOp, ArgSide),
// BinOpRet(BinOp),
FloatLiteral, FloatLiteral,
IntLiteral, IntLiteral,
NumLiteral, NumLiteral,