Do not generate Def::Err in bindings
Instead of Def::Err erroneous bindings can get usual definitions that doesn't require special cases later on and have less chances to generate ICE.
This commit is contained in:
parent
4d4c7be19e
commit
eb32440d45
|
@ -2180,7 +2180,8 @@ impl<'a> Resolver<'a> {
|
|||
// because that breaks the assumptions later
|
||||
// passes make about or-patterns.)
|
||||
let renamed = mtwt::resolve(ident.node);
|
||||
let def = match bindings.get(&renamed).cloned() {
|
||||
let mut def = Def::Local(self.definitions.local_def_id(pat_id), pat_id);
|
||||
match bindings.get(&renamed).cloned() {
|
||||
Some(id) if id == outer_pat_id => {
|
||||
// `Variant(a, a)`, error
|
||||
resolve_error(
|
||||
|
@ -2189,7 +2190,6 @@ impl<'a> Resolver<'a> {
|
|||
ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
|
||||
&ident.node.name.as_str())
|
||||
);
|
||||
Def::Err
|
||||
}
|
||||
Some(..) if pat_src == PatternSource::FnParam => {
|
||||
// `fn f(a: u8, a: u8)`, error
|
||||
|
@ -2199,29 +2199,24 @@ impl<'a> Resolver<'a> {
|
|||
ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
|
||||
&ident.node.name.as_str())
|
||||
);
|
||||
Def::Err
|
||||
}
|
||||
Some(..) if pat_src == PatternSource::Match => {
|
||||
// `Variant1(a) | Variant2(a)`, ok
|
||||
// Reuse definition from the first `a`.
|
||||
self.value_ribs.last_mut().unwrap().bindings[&renamed]
|
||||
def = self.value_ribs.last_mut().unwrap().bindings[&renamed];
|
||||
}
|
||||
Some(..) => {
|
||||
span_bug!(ident.span, "two bindings with the same name from \
|
||||
unexpected pattern source {:?}", pat_src);
|
||||
}
|
||||
None => {
|
||||
// A completely fresh binding, add to the lists.
|
||||
// FIXME: Later stages are not ready to deal with `Def::Err` here yet, so
|
||||
// define `Invalid` bindings as `Def::Local`, just don't add them to the lists.
|
||||
let def = Def::Local(self.definitions.local_def_id(pat_id), pat_id);
|
||||
// A completely fresh binding, add to the lists if it's valid.
|
||||
if ident.node.name != keywords::Invalid.name() {
|
||||
bindings.insert(renamed, outer_pat_id);
|
||||
self.value_ribs.last_mut().unwrap().bindings.insert(renamed, def);
|
||||
}
|
||||
def
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
PathResolution::new(def)
|
||||
}
|
||||
|
@ -2287,15 +2282,16 @@ impl<'a> Resolver<'a> {
|
|||
PatKind::Ident(bmode, ref ident, ref opt_pat) => {
|
||||
// First try to resolve the identifier as some existing
|
||||
// entity, then fall back to a fresh binding.
|
||||
let local_def = self.resolve_identifier(ident.node, ValueNS, true);
|
||||
let resolution = if let Some(LocalDef { def, .. }) = local_def {
|
||||
let resolution = self.resolve_identifier(ident.node, ValueNS, true)
|
||||
.map(|local_def| PathResolution::new(local_def.def))
|
||||
.and_then(|resolution| {
|
||||
let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
|
||||
bmode != BindingMode::ByValue(Mutability::Immutable);
|
||||
match def {
|
||||
Def::Struct(..) | Def::Variant(..) |
|
||||
Def::Const(..) | Def::AssociatedConst(..) if !always_binding => {
|
||||
// A constant, unit variant, etc pattern.
|
||||
PathResolution::new(def)
|
||||
Some(resolution)
|
||||
}
|
||||
Def::Struct(..) | Def::Variant(..) |
|
||||
Def::Const(..) | Def::AssociatedConst(..) | Def::Static(..) => {
|
||||
|
@ -2307,23 +2303,21 @@ impl<'a> Resolver<'a> {
|
|||
ResolutionError::BindingShadowsSomethingUnacceptable(
|
||||
pat_src.descr(), kind_name, ident.node.name)
|
||||
);
|
||||
err_path_resolution()
|
||||
None
|
||||
}
|
||||
Def::Local(..) | Def::Upvar(..) | Def::Fn(..) => {
|
||||
// These entities are explicitly allowed
|
||||
// to be shadowed by fresh bindings.
|
||||
self.fresh_binding(ident, pat.id, outer_pat_id,
|
||||
pat_src, bindings)
|
||||
None
|
||||
}
|
||||
def => {
|
||||
span_bug!(ident.span, "unexpected definition for an \
|
||||
identifier in pattern {:?}", def);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Fall back to a fresh binding.
|
||||
}).unwrap_or_else(|| {
|
||||
self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
|
||||
};
|
||||
});
|
||||
|
||||
self.record_def(pat.id, resolution);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue