Skip to content

Commit bf8caf1

Browse files
committed
Auto merge of #30320 - nrc:err-names, r=@nikomatsakis
We can now handle name resolution errors and get past type checking (if we're a bit lucky). This is the first step towards doing code completion for partial programs (we need error recovery in the parser and early access to save-analysis).
2 parents 9e63cec + 18b4fe0 commit bf8caf1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+308
-213
lines changed

src/librustc/middle/check_static_recursion.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,9 @@ pub fn check_crate<'ast>(sess: &Session,
9999
ast_map: ast_map,
100100
discriminant_map: RefCell::new(NodeMap()),
101101
};
102-
krate.visit_all_items(&mut visitor);
103-
sess.abort_if_errors();
102+
sess.abort_if_new_errors(|| {
103+
krate.visit_all_items(&mut visitor);
104+
});
104105
}
105106

106107
struct CheckItemRecursionVisitor<'a, 'ast: 'a> {

src/librustc/middle/def.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ pub enum Def {
5252
DefStruct(DefId),
5353
DefLabel(ast::NodeId),
5454
DefMethod(DefId),
55+
DefErr,
5556
}
5657

5758
/// The result of resolving a path.
@@ -124,7 +125,7 @@ impl Def {
124125
DefVariant(..) | DefTy(..) | DefAssociatedTy(..) |
125126
DefTyParam(..) | DefUse(..) | DefStruct(..) | DefTrait(..) |
126127
DefMethod(..) | DefConst(..) | DefAssociatedConst(..) |
127-
DefPrimTy(..) | DefLabel(..) | DefSelfTy(..) => {
128+
DefPrimTy(..) | DefLabel(..) | DefSelfTy(..) | DefErr => {
128129
panic!("attempted .def_id() on invalid {:?}", self)
129130
}
130131
}
@@ -142,7 +143,8 @@ impl Def {
142143

143144
DefLabel(..) |
144145
DefPrimTy(..) |
145-
DefSelfTy(..) => {
146+
DefSelfTy(..) |
147+
DefErr => {
146148
panic!("attempted .def_id() on invalid def: {:?}", self)
147149
}
148150
}

src/librustc/middle/mem_categorization.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,8 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
609609
note: NoteNone
610610
}))
611611
}
612+
613+
def::DefErr => panic!("DefErr in memory categorization")
612614
}
613615
}
614616

@@ -1196,7 +1198,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
11961198
(*op)(self, cmt.clone(), pat);
11971199

11981200
let opt_def = if let Some(path_res) = self.tcx().def_map.borrow().get(&pat.id) {
1199-
if path_res.depth != 0 {
1201+
if path_res.depth != 0 || path_res.base_def == def::DefErr {
12001202
// Since patterns can be associated constants
12011203
// which are resolved during typeck, we might have
12021204
// some unresolved patterns reaching this stage
@@ -1261,7 +1263,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
12611263
_ => {
12621264
self.tcx().sess.span_bug(
12631265
pat.span,
1264-
"enum pattern didn't resolve to enum or struct");
1266+
&format!("enum pattern didn't resolve to enum or struct {:?}", opt_def));
12651267
}
12661268
}
12671269
}

src/librustc/middle/resolve_lifetime.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,16 @@ static ROOT_SCOPE: ScopeChain<'static> = RootScope;
9595

9696
pub fn krate(sess: &Session, krate: &hir::Crate, def_map: &DefMap) -> NamedRegionMap {
9797
let mut named_region_map = NodeMap();
98-
krate.visit_all_items(&mut LifetimeContext {
99-
sess: sess,
100-
named_region_map: &mut named_region_map,
101-
scope: &ROOT_SCOPE,
102-
def_map: def_map,
103-
trait_ref_hack: false,
104-
labels_in_fn: vec![],
98+
sess.abort_if_new_errors(|| {
99+
krate.visit_all_items(&mut LifetimeContext {
100+
sess: sess,
101+
named_region_map: &mut named_region_map,
102+
scope: &ROOT_SCOPE,
103+
def_map: def_map,
104+
trait_ref_hack: false,
105+
labels_in_fn: vec![],
106+
});
105107
});
106-
sess.abort_if_errors();
107108
named_region_map
108109
}
109110

src/librustc/middle/ty/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -2100,9 +2100,8 @@ impl<'tcx> ctxt<'tcx> {
21002100
}) => {
21012101
true
21022102
}
2103-
2103+
Some(&def::PathResolution { base_def: def::DefErr, .. })=> true,
21042104
Some(..) => false,
2105-
21062105
None => self.sess.span_bug(expr.span, &format!(
21072106
"no def for path {}", expr.id))
21082107
}

src/librustc/session/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,15 @@ impl Session {
156156
_ => {}
157157
}
158158
}
159+
pub fn abort_if_new_errors<F>(&self, mut f: F)
160+
where F: FnMut()
161+
{
162+
let count = self.err_count();
163+
f();
164+
if self.err_count() > count {
165+
self.abort_if_errors();
166+
}
167+
}
159168
pub fn span_warn(&self, sp: Span, msg: &str) {
160169
if self.can_print_warnings {
161170
self.diagnostic().span_warn(sp, msg)

src/librustc_metadata/astencode.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,8 @@ impl tr for def::Def {
407407
def::DefUpvar(did1, nid1, index, nid2)
408408
}
409409
def::DefStruct(did) => def::DefStruct(did.tr(dcx)),
410-
def::DefLabel(nid) => def::DefLabel(dcx.tr_id(nid))
410+
def::DefLabel(nid) => def::DefLabel(dcx.tr_id(nid)),
411+
def::DefErr => def::DefErr,
411412
}
412413
}
413414
}

src/librustc_resolve/build_reduced_graph.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
709709
DefUse(..) |
710710
DefUpvar(..) |
711711
DefLabel(..) |
712-
DefSelfTy(..) => {
712+
DefSelfTy(..) |
713+
DefErr => {
713714
panic!("didn't expect `{:?}`", def);
714715
}
715716
}

src/librustc_resolve/lib.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
566566
Ok(def) => self.record_def(tref.trait_ref.ref_id, def),
567567
Err(_) => {
568568
// error already reported
569+
self.record_def(tref.trait_ref.ref_id, err_path_resolution())
569570
}
570571
}
571572
intravisit::walk_poly_trait_ref(self, tref, m);
@@ -2005,6 +2006,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
20052006
prefix.span,
20062007
ResolutionError::FailedToResolve(
20072008
&path_names_to_string(prefix, 0)));
2009+
self.record_def(item.id, err_path_resolution());
20082010
}
20092011
}
20102012
}
@@ -2164,6 +2166,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
21642166
resolve_error(self,
21652167
eq_pred.span,
21662168
ResolutionError::UndeclaredAssociatedType);
2169+
self.record_def(eq_pred.id, err_path_resolution());
21672170
}
21682171
}
21692172
}
@@ -2194,6 +2197,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
21942197
self.record_def(trait_ref.ref_id, path_res);
21952198
new_val = Some((path_res.base_def.def_id(), trait_ref.clone()));
21962199
new_id = Some(path_res.base_def.def_id());
2200+
} else {
2201+
self.record_def(trait_ref.ref_id, err_path_resolution());
21972202
}
21982203
intravisit::walk_trait_ref(self, trait_ref);
21992204
}
@@ -2463,6 +2468,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
24632468
self.record_def(ty.id, def);
24642469
}
24652470
None => {
2471+
self.record_def(ty.id, err_path_resolution());
2472+
24662473
// Keep reporting some errors even if they're ignored above.
24672474
self.resolve_path(ty.id, path, 0, TypeNS, true);
24682475

@@ -2545,6 +2552,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
25452552
ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(
25462553
renamed)
25472554
);
2555+
self.record_def(pattern.id, err_path_resolution());
25482556
}
25492557
FoundConst(def, lp, _) if const_ok => {
25502558
debug!("(resolving pattern) resolving `{}` to constant", renamed);
@@ -2564,6 +2572,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
25642572
ResolutionError::OnlyIrrefutablePatternsAllowedHere(def.def_id(),
25652573
name)
25662574
);
2575+
self.record_def(pattern.id, err_path_resolution());
25672576
}
25682577
BareIdentifierPatternUnresolved => {
25692578
debug!("(resolving pattern) binding `{}`", renamed);
@@ -2647,6 +2656,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
26472656
resolve_error(&self,
26482657
path.span,
26492658
ResolutionError::StaticVariableReference);
2659+
self.record_def(pattern.id, err_path_resolution());
26502660
}
26512661
_ => {
26522662
// If anything ends up here entirely resolved,
@@ -2665,6 +2675,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
26652675
.name
26662676
.as_str())
26672677
);
2678+
self.record_def(pattern.id, err_path_resolution());
26682679
} else {
26692680
let const_name = path.segments
26702681
.last()
@@ -2684,6 +2695,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
26842695
ResolutionError::UnresolvedEnumVariantStructOrConst(
26852696
&path.segments.last().unwrap().identifier.name.as_str())
26862697
);
2698+
self.record_def(pattern.id, err_path_resolution());
26872699
}
26882700
intravisit::walk_path(self, path);
26892701
}
@@ -2726,6 +2738,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
27262738
&path.segments.last().unwrap().identifier.name.as_str()
27272739
)
27282740
);
2741+
self.record_def(pattern.id, err_path_resolution());
27292742
}
27302743
}
27312744
} else {
@@ -2737,6 +2750,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
27372750
.identifier
27382751
.name
27392752
.as_str()));
2753+
self.record_def(pattern.id, err_path_resolution());
27402754
}
27412755
intravisit::walk_pat(self, pattern);
27422756
}
@@ -2754,6 +2768,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
27542768
ResolutionError::DoesNotNameAStruct(
27552769
&*path_names_to_string(path, 0))
27562770
);
2771+
self.record_def(pattern.id, err_path_resolution());
27572772
}
27582773
}
27592774
intravisit::walk_path(self, path);
@@ -3430,6 +3445,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
34303445
} else {
34313446
self.session.span_help(expr.span, &msg);
34323447
}
3448+
self.record_def(expr.id, err_path_resolution());
34333449
} else {
34343450
// Write the result into the def map.
34353451
debug!("(resolving expr) resolved `{}`",
@@ -3454,6 +3470,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
34543470
let type_res = self.with_no_errors(|this| {
34553471
this.resolve_path(expr.id, path, 0, TypeNS, false)
34563472
});
3473+
3474+
self.record_def(expr.id, err_path_resolution());
34573475
match type_res.map(|r| r.base_def) {
34583476
Some(DefTy(struct_id, _)) if self.structs.contains_key(&struct_id) => {
34593477
resolve_error(
@@ -3540,6 +3558,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
35403558
ResolutionError::DoesNotNameAStruct(
35413559
&*path_names_to_string(path, 0))
35423560
);
3561+
self.record_def(expr.id, err_path_resolution());
35433562
}
35443563
}
35453564

@@ -3562,6 +3581,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
35623581
ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
35633582
match self.search_label(label.node.name) {
35643583
None => {
3584+
self.record_def(expr.id, err_path_resolution());
35653585
resolve_error(self,
35663586
label.span,
35673587
ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
@@ -3811,6 +3831,14 @@ fn module_to_string(module: &Module) -> String {
38113831
names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
38123832
}
38133833

3834+
fn err_path_resolution() -> PathResolution {
3835+
PathResolution {
3836+
base_def: DefErr,
3837+
last_private: LastMod(AllPublic),
3838+
depth: 0,
3839+
}
3840+
}
3841+
38143842

38153843
pub struct CrateMap {
38163844
pub def_map: RefCell<DefMap>,
@@ -3836,7 +3864,6 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
38363864
let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, None);
38373865

38383866
resolver.resolve_crate(krate);
3839-
session.abort_if_errors();
38403867

38413868
check_unused::check_crate(&mut resolver, krate);
38423869

src/librustc_trans/save/dump_csv.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,8 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
276276
def::DefTyParam(..) |
277277
def::DefUse(_) |
278278
def::DefMethod(..) |
279-
def::DefPrimTy(_) => {
279+
def::DefPrimTy(_) |
280+
def::DefErr => {
280281
self.sess.span_bug(span,
281282
&format!("lookup_def_kind for unexpected item: {:?}", def));
282283
}

src/librustc_trans/trans/callee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &hir::Expr)
216216
def::DefMod(..) | def::DefForeignMod(..) | def::DefTrait(..) |
217217
def::DefTy(..) | def::DefPrimTy(..) | def::DefAssociatedTy(..) |
218218
def::DefUse(..) | def::DefLabel(..) | def::DefTyParam(..) |
219-
def::DefSelfTy(..) => {
219+
def::DefSelfTy(..) | def::DefErr => {
220220
bcx.tcx().sess.span_bug(
221221
ref_expr.span,
222222
&format!("cannot translate def {:?} \

src/librustc_typeck/astconv.rs

+6
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,9 @@ fn trait_def_id<'tcx>(this: &AstConv<'tcx>, trait_ref: &hir::TraitRef) -> DefId
719719
let path = &trait_ref.path;
720720
match ::lookup_full_def(this.tcx(), path.span, trait_ref.ref_id) {
721721
def::DefTrait(trait_def_id) => trait_def_id,
722+
def::DefErr => {
723+
this.tcx().sess.fatal("cannot continue compilation due to previous error");
724+
}
722725
_ => {
723726
span_fatal!(this.tcx().sess, path.span, E0245, "`{}` is not a trait",
724727
path);
@@ -1533,6 +1536,9 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
15331536
def::DefPrimTy(prim_ty) => {
15341537
prim_ty_to_ty(tcx, base_segments, prim_ty)
15351538
}
1539+
def::DefErr => {
1540+
return this.tcx().types.err;
1541+
}
15361542
_ => {
15371543
let id_node = tcx.map.as_local_node_id(def.def_id()).unwrap();
15381544
span_err!(tcx.sess, span, E0248,

0 commit comments

Comments
 (0)