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
|
// because that breaks the assumptions later
|
||||||
// passes make about or-patterns.)
|
// passes make about or-patterns.)
|
||||||
let renamed = mtwt::resolve(ident.node);
|
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 => {
|
Some(id) if id == outer_pat_id => {
|
||||||
// `Variant(a, a)`, error
|
// `Variant(a, a)`, error
|
||||||
resolve_error(
|
resolve_error(
|
||||||
|
@ -2189,7 +2190,6 @@ impl<'a> Resolver<'a> {
|
||||||
ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
|
ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
|
||||||
&ident.node.name.as_str())
|
&ident.node.name.as_str())
|
||||||
);
|
);
|
||||||
Def::Err
|
|
||||||
}
|
}
|
||||||
Some(..) if pat_src == PatternSource::FnParam => {
|
Some(..) if pat_src == PatternSource::FnParam => {
|
||||||
// `fn f(a: u8, a: u8)`, error
|
// `fn f(a: u8, a: u8)`, error
|
||||||
|
@ -2199,29 +2199,24 @@ impl<'a> Resolver<'a> {
|
||||||
ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
|
ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
|
||||||
&ident.node.name.as_str())
|
&ident.node.name.as_str())
|
||||||
);
|
);
|
||||||
Def::Err
|
|
||||||
}
|
}
|
||||||
Some(..) if pat_src == PatternSource::Match => {
|
Some(..) if pat_src == PatternSource::Match => {
|
||||||
// `Variant1(a) | Variant2(a)`, ok
|
// `Variant1(a) | Variant2(a)`, ok
|
||||||
// Reuse definition from the first `a`.
|
// Reuse definition from the first `a`.
|
||||||
self.value_ribs.last_mut().unwrap().bindings[&renamed]
|
def = self.value_ribs.last_mut().unwrap().bindings[&renamed];
|
||||||
}
|
}
|
||||||
Some(..) => {
|
Some(..) => {
|
||||||
span_bug!(ident.span, "two bindings with the same name from \
|
span_bug!(ident.span, "two bindings with the same name from \
|
||||||
unexpected pattern source {:?}", pat_src);
|
unexpected pattern source {:?}", pat_src);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// A completely fresh binding, add to the lists.
|
// A completely fresh binding, add to the lists if it's valid.
|
||||||
// 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);
|
|
||||||
if ident.node.name != keywords::Invalid.name() {
|
if ident.node.name != keywords::Invalid.name() {
|
||||||
bindings.insert(renamed, outer_pat_id);
|
bindings.insert(renamed, outer_pat_id);
|
||||||
self.value_ribs.last_mut().unwrap().bindings.insert(renamed, def);
|
self.value_ribs.last_mut().unwrap().bindings.insert(renamed, def);
|
||||||
}
|
}
|
||||||
def
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
PathResolution::new(def)
|
PathResolution::new(def)
|
||||||
}
|
}
|
||||||
|
@ -2287,15 +2282,16 @@ impl<'a> Resolver<'a> {
|
||||||
PatKind::Ident(bmode, ref ident, ref opt_pat) => {
|
PatKind::Ident(bmode, ref ident, ref opt_pat) => {
|
||||||
// First try to resolve the identifier as some existing
|
// First try to resolve the identifier as some existing
|
||||||
// entity, then fall back to a fresh binding.
|
// entity, then fall back to a fresh binding.
|
||||||
let local_def = self.resolve_identifier(ident.node, ValueNS, true);
|
let resolution = self.resolve_identifier(ident.node, ValueNS, true)
|
||||||
let resolution = if let Some(LocalDef { def, .. }) = local_def {
|
.map(|local_def| PathResolution::new(local_def.def))
|
||||||
|
.and_then(|resolution| {
|
||||||
let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
|
let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
|
||||||
bmode != BindingMode::ByValue(Mutability::Immutable);
|
bmode != BindingMode::ByValue(Mutability::Immutable);
|
||||||
match def {
|
match def {
|
||||||
Def::Struct(..) | Def::Variant(..) |
|
Def::Struct(..) | Def::Variant(..) |
|
||||||
Def::Const(..) | Def::AssociatedConst(..) if !always_binding => {
|
Def::Const(..) | Def::AssociatedConst(..) if !always_binding => {
|
||||||
// A constant, unit variant, etc pattern.
|
// A constant, unit variant, etc pattern.
|
||||||
PathResolution::new(def)
|
Some(resolution)
|
||||||
}
|
}
|
||||||
Def::Struct(..) | Def::Variant(..) |
|
Def::Struct(..) | Def::Variant(..) |
|
||||||
Def::Const(..) | Def::AssociatedConst(..) | Def::Static(..) => {
|
Def::Const(..) | Def::AssociatedConst(..) | Def::Static(..) => {
|
||||||
|
@ -2307,23 +2303,21 @@ impl<'a> Resolver<'a> {
|
||||||
ResolutionError::BindingShadowsSomethingUnacceptable(
|
ResolutionError::BindingShadowsSomethingUnacceptable(
|
||||||
pat_src.descr(), kind_name, ident.node.name)
|
pat_src.descr(), kind_name, ident.node.name)
|
||||||
);
|
);
|
||||||
err_path_resolution()
|
None
|
||||||
}
|
}
|
||||||
Def::Local(..) | Def::Upvar(..) | Def::Fn(..) => {
|
Def::Local(..) | Def::Upvar(..) | Def::Fn(..) => {
|
||||||
// These entities are explicitly allowed
|
// These entities are explicitly allowed
|
||||||
// to be shadowed by fresh bindings.
|
// to be shadowed by fresh bindings.
|
||||||
self.fresh_binding(ident, pat.id, outer_pat_id,
|
None
|
||||||
pat_src, bindings)
|
|
||||||
}
|
}
|
||||||
def => {
|
def => {
|
||||||
span_bug!(ident.span, "unexpected definition for an \
|
span_bug!(ident.span, "unexpected definition for an \
|
||||||
identifier in pattern {:?}", def);
|
identifier in pattern {:?}", def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}).unwrap_or_else(|| {
|
||||||
// Fall back to a fresh binding.
|
|
||||||
self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
|
self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
|
||||||
};
|
});
|
||||||
|
|
||||||
self.record_def(pat.id, resolution);
|
self.record_def(pat.id, resolution);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue