Skip to content

Commit eb32440

Browse files
committed
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.
1 parent 4d4c7be commit eb32440

File tree

1 file changed

+13
-19
lines changed

1 file changed

+13
-19
lines changed

src/librustc_resolve/lib.rs

+13-19
Original file line numberDiff line numberDiff line change
@@ -2180,7 +2180,8 @@ impl<'a> Resolver<'a> {
21802180
// because that breaks the assumptions later
21812181
// passes make about or-patterns.)
21822182
let renamed = mtwt::resolve(ident.node);
2183-
let def = match bindings.get(&renamed).cloned() {
2183+
let mut def = Def::Local(self.definitions.local_def_id(pat_id), pat_id);
2184+
match bindings.get(&renamed).cloned() {
21842185
Some(id) if id == outer_pat_id => {
21852186
// `Variant(a, a)`, error
21862187
resolve_error(
@@ -2189,7 +2190,6 @@ impl<'a> Resolver<'a> {
21892190
ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
21902191
&ident.node.name.as_str())
21912192
);
2192-
Def::Err
21932193
}
21942194
Some(..) if pat_src == PatternSource::FnParam => {
21952195
// `fn f(a: u8, a: u8)`, error
@@ -2199,29 +2199,24 @@ impl<'a> Resolver<'a> {
21992199
ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
22002200
&ident.node.name.as_str())
22012201
);
2202-
Def::Err
22032202
}
22042203
Some(..) if pat_src == PatternSource::Match => {
22052204
// `Variant1(a) | Variant2(a)`, ok
22062205
// Reuse definition from the first `a`.
2207-
self.value_ribs.last_mut().unwrap().bindings[&renamed]
2206+
def = self.value_ribs.last_mut().unwrap().bindings[&renamed];
22082207
}
22092208
Some(..) => {
22102209
span_bug!(ident.span, "two bindings with the same name from \
22112210
unexpected pattern source {:?}", pat_src);
22122211
}
22132212
None => {
2214-
// A completely fresh binding, add to the lists.
2215-
// FIXME: Later stages are not ready to deal with `Def::Err` here yet, so
2216-
// define `Invalid` bindings as `Def::Local`, just don't add them to the lists.
2217-
let def = Def::Local(self.definitions.local_def_id(pat_id), pat_id);
2213+
// A completely fresh binding, add to the lists if it's valid.
22182214
if ident.node.name != keywords::Invalid.name() {
22192215
bindings.insert(renamed, outer_pat_id);
22202216
self.value_ribs.last_mut().unwrap().bindings.insert(renamed, def);
22212217
}
2222-
def
22232218
}
2224-
};
2219+
}
22252220

22262221
PathResolution::new(def)
22272222
}
@@ -2287,15 +2282,16 @@ impl<'a> Resolver<'a> {
22872282
PatKind::Ident(bmode, ref ident, ref opt_pat) => {
22882283
// First try to resolve the identifier as some existing
22892284
// entity, then fall back to a fresh binding.
2290-
let local_def = self.resolve_identifier(ident.node, ValueNS, true);
2291-
let resolution = if let Some(LocalDef { def, .. }) = local_def {
2285+
let resolution = self.resolve_identifier(ident.node, ValueNS, true)
2286+
.map(|local_def| PathResolution::new(local_def.def))
2287+
.and_then(|resolution| {
22922288
let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
22932289
bmode != BindingMode::ByValue(Mutability::Immutable);
22942290
match def {
22952291
Def::Struct(..) | Def::Variant(..) |
22962292
Def::Const(..) | Def::AssociatedConst(..) if !always_binding => {
22972293
// A constant, unit variant, etc pattern.
2298-
PathResolution::new(def)
2294+
Some(resolution)
22992295
}
23002296
Def::Struct(..) | Def::Variant(..) |
23012297
Def::Const(..) | Def::AssociatedConst(..) | Def::Static(..) => {
@@ -2307,23 +2303,21 @@ impl<'a> Resolver<'a> {
23072303
ResolutionError::BindingShadowsSomethingUnacceptable(
23082304
pat_src.descr(), kind_name, ident.node.name)
23092305
);
2310-
err_path_resolution()
2306+
None
23112307
}
23122308
Def::Local(..) | Def::Upvar(..) | Def::Fn(..) => {
23132309
// These entities are explicitly allowed
23142310
// to be shadowed by fresh bindings.
2315-
self.fresh_binding(ident, pat.id, outer_pat_id,
2316-
pat_src, bindings)
2311+
None
23172312
}
23182313
def => {
23192314
span_bug!(ident.span, "unexpected definition for an \
23202315
identifier in pattern {:?}", def);
23212316
}
23222317
}
2323-
} else {
2324-
// Fall back to a fresh binding.
2318+
}).unwrap_or_else(|| {
23252319
self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
2326-
};
2320+
});
23272321

23282322
self.record_def(pat.id, resolution);
23292323
}

0 commit comments

Comments
 (0)