Skip to content

Commit e8ea38e

Browse files
committed
Further cleanup in resolve
`try_define` is not used in build_reduced_graph anymore Collection of field names for error reporting is optimized Some comments added
1 parent d19c16a commit e8ea38e

File tree

3 files changed

+54
-76
lines changed

3 files changed

+54
-76
lines changed

src/librustc_metadata/decoder.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,8 @@ impl<'a, 'tcx> CrateMetadata {
699699
}
700700
}
701701
Def::Variant(def_id) => {
702+
// Braced variants, unlike structs, generate unusable names in
703+
// value namespace, they are reserved for possible future use.
702704
let vkind = self.get_variant_kind(child_index).unwrap();
703705
let ctor_def = Def::VariantCtor(def_id, vkind.ctor_kind());
704706
callback(def::Export { def: ctor_def, name: name });

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 46 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ use std::rc::Rc;
3131

3232
use syntax::ast::Name;
3333
use syntax::attr;
34-
use syntax::parse::token;
3534

3635
use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind};
3736
use syntax::ast::{Mutability, StmtKind, TraitItem, TraitItemKind};
@@ -77,6 +76,12 @@ impl<'b> Resolver<'b> {
7776
})
7877
}
7978

79+
fn insert_field_names(&mut self, def_id: DefId, field_names: Vec<Name>) {
80+
if !field_names.is_empty() {
81+
self.field_names.insert(def_id, field_names);
82+
}
83+
}
84+
8085
/// Constructs the reduced graph for one item.
8186
fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
8287
let parent = self.current_module;
@@ -301,28 +306,26 @@ impl<'b> Resolver<'b> {
301306
self.define(parent, name, ValueNS, (ctor_def, sp, vis));
302307
}
303308

304-
// Record the def ID and fields of this struct.
305-
let field_names = struct_def.fields().iter().enumerate().map(|(index, field)| {
309+
// Record field names for error reporting.
310+
let field_names = struct_def.fields().iter().filter_map(|field| {
306311
self.resolve_visibility(&field.vis);
307312
field.ident.map(|ident| ident.name)
308-
.unwrap_or_else(|| token::intern(&index.to_string()))
309313
}).collect();
310314
let item_def_id = self.definitions.local_def_id(item.id);
311-
self.structs.insert(item_def_id, field_names);
315+
self.insert_field_names(item_def_id, field_names);
312316
}
313317

314318
ItemKind::Union(ref vdata, _) => {
315319
let def = Def::Union(self.definitions.local_def_id(item.id));
316320
self.define(parent, name, TypeNS, (def, sp, vis));
317321

318-
// Record the def ID and fields of this union.
319-
let field_names = vdata.fields().iter().enumerate().map(|(index, field)| {
322+
// Record field names for error reporting.
323+
let field_names = vdata.fields().iter().filter_map(|field| {
320324
self.resolve_visibility(&field.vis);
321325
field.ident.map(|ident| ident.name)
322-
.unwrap_or_else(|| token::intern(&index.to_string()))
323326
}).collect();
324327
let item_def_id = self.definitions.local_def_id(item.id);
325-
self.structs.insert(item_def_id, field_names);
328+
self.insert_field_names(item_def_id, field_names);
326329
}
327330

328331
ItemKind::DefaultImpl(..) | ItemKind::Impl(..) => {}
@@ -347,18 +350,17 @@ impl<'b> Resolver<'b> {
347350
parent: Module<'b>,
348351
vis: ty::Visibility) {
349352
let name = variant.node.name.name;
350-
let ctor_kind = CtorKind::from_vdata(&variant.node.data);
351-
if variant.node.data.is_struct() {
352-
// Not adding fields for variants as they are not accessed with a self receiver
353-
let variant_def_id = self.definitions.local_def_id(variant.node.data.id());
354-
self.structs.insert(variant_def_id, Vec::new());
355-
}
353+
let def_id = self.definitions.local_def_id(variant.node.data.id());
356354

357-
// All variants are defined in both type and value namespaces as future-proofing.
358-
let def = Def::Variant(self.definitions.local_def_id(variant.node.data.id()));
359-
let ctor_def = Def::VariantCtor(self.definitions.local_def_id(variant.node.data.id()),
360-
ctor_kind);
355+
// Define a name in the type namespace.
356+
let def = Def::Variant(def_id);
361357
self.define(parent, name, TypeNS, (def, variant.span, vis));
358+
359+
// Define a constructor name in the value namespace.
360+
// Braced variants, unlike structs, generate unusable names in
361+
// value namespace, they are reserved for possible future use.
362+
let ctor_kind = CtorKind::from_vdata(&variant.node.data);
363+
let ctor_def = Def::VariantCtor(def_id, ctor_kind);
362364
self.define(parent, name, ValueNS, (ctor_def, variant.span, vis));
363365
}
364366

@@ -407,79 +409,55 @@ impl<'b> Resolver<'b> {
407409
};
408410

409411
match def {
410-
Def::Mod(_) | Def::Enum(..) => {
411-
debug!("(building reduced graph for external crate) building module {} {:?}",
412-
name, vis);
412+
Def::Mod(..) | Def::Enum(..) => {
413413
let module = self.new_module(parent, ModuleKind::Def(def, name), false);
414-
let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
414+
self.define(parent, name, TypeNS, (module, DUMMY_SP, vis));
415415
}
416416
Def::Variant(..) => {
417-
debug!("(building reduced graph for external crate) building variant {}", name);
418-
// All variants are defined in both type and value namespaces as future-proofing.
419-
let vkind = self.session.cstore.variant_kind(def_id).unwrap();
420-
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
421-
if vkind == ty::VariantKind::Struct {
422-
// Not adding fields for variants as they are not accessed with a self receiver
423-
self.structs.insert(def_id, Vec::new());
424-
}
417+
self.define(parent, name, TypeNS, (def, DUMMY_SP, vis));
425418
}
426419
Def::VariantCtor(..) => {
427-
let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
420+
self.define(parent, name, ValueNS, (def, DUMMY_SP, vis));
428421
}
429422
Def::Fn(..) |
430423
Def::Static(..) |
431424
Def::Const(..) |
432425
Def::AssociatedConst(..) |
433426
Def::Method(..) => {
434-
debug!("(building reduced graph for external crate) building value (fn/static) {}",
435-
name);
436-
let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
427+
self.define(parent, name, ValueNS, (def, DUMMY_SP, vis));
437428
}
438-
Def::Trait(_) => {
439-
debug!("(building reduced graph for external crate) building type {}", name);
440-
441-
// If this is a trait, add all the trait item names to the trait
442-
// info.
429+
Def::Trait(..) => {
430+
let module = self.new_module(parent, ModuleKind::Def(def, name), false);
431+
self.define(parent, name, TypeNS, (module, DUMMY_SP, vis));
443432

433+
// If this is a trait, add all the trait item names to the trait info.
444434
let trait_item_def_ids = self.session.cstore.impl_or_trait_items(def_id);
445-
for &trait_item_def in &trait_item_def_ids {
446-
let trait_item_name =
447-
self.session.cstore.def_key(trait_item_def)
448-
.disambiguated_data.data.get_opt_name()
449-
.expect("opt_item_name returned None for trait");
450-
451-
debug!("(building reduced graph for external crate) ... adding trait item \
452-
'{}'",
453-
trait_item_name);
454-
435+
for trait_item_def_id in trait_item_def_ids {
436+
let trait_item_name = self.session.cstore.def_key(trait_item_def_id)
437+
.disambiguated_data.data.get_opt_name()
438+
.expect("opt_item_name returned None for trait");
455439
self.trait_item_map.insert((trait_item_name, def_id), false);
456440
}
457-
458-
let module = self.new_module(parent, ModuleKind::Def(def, name), false);
459-
let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
460441
}
461442
Def::TyAlias(..) | Def::AssociatedTy(..) => {
462-
debug!("(building reduced graph for external crate) building type {}", name);
463-
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
443+
self.define(parent, name, TypeNS, (def, DUMMY_SP, vis));
464444
}
465445
Def::Struct(..) => {
466-
debug!("(building reduced graph for external crate) building type and value for {}",
467-
name);
468-
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
446+
self.define(parent, name, TypeNS, (def, DUMMY_SP, vis));
469447

470-
// Record the def ID and fields of this struct.
471-
let fields = self.session.cstore.struct_field_names(def_id);
472-
self.structs.insert(def_id, fields);
448+
// Record field names for error reporting.
449+
let field_names = self.session.cstore.struct_field_names(def_id);
450+
self.insert_field_names(def_id, field_names);
473451
}
474452
Def::StructCtor(..) => {
475-
let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
453+
self.define(parent, name, ValueNS, (def, DUMMY_SP, vis));
476454
}
477-
Def::Union(_) => {
478-
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
455+
Def::Union(..) => {
456+
self.define(parent, name, TypeNS, (def, DUMMY_SP, vis));
479457

480-
// Record the def ID and fields of this union.
481-
let fields = self.session.cstore.struct_field_names(def_id);
482-
self.structs.insert(def_id, fields);
458+
// Record field names for error reporting.
459+
let field_names = self.session.cstore.struct_field_names(def_id);
460+
self.insert_field_names(def_id, field_names);
483461
}
484462
Def::Local(..) |
485463
Def::PrimTy(..) |
@@ -488,7 +466,7 @@ impl<'b> Resolver<'b> {
488466
Def::Label(..) |
489467
Def::SelfTy(..) |
490468
Def::Err => {
491-
bug!("didn't expect `{:?}`", def);
469+
bug!("unexpected definition: {:?}", def);
492470
}
493471
}
494472
}

src/librustc_resolve/lib.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,9 @@ pub struct Resolver<'a> {
10061006

10071007
trait_item_map: FnvHashMap<(Name, DefId), bool /* is static method? */>,
10081008

1009-
structs: FnvHashMap<DefId, Vec<Name>>,
1009+
// Names of fields of an item `DefId` accessible with dot syntax.
1010+
// Used for hints during error reporting.
1011+
field_names: FnvHashMap<DefId, Vec<Name>>,
10101012

10111013
// All imports known to succeed or fail.
10121014
determined_imports: Vec<&'a ImportDirective<'a>>,
@@ -1218,7 +1220,7 @@ impl<'a> Resolver<'a> {
12181220
prelude: None,
12191221

12201222
trait_item_map: FnvHashMap(),
1221-
structs: FnvHashMap(),
1223+
field_names: FnvHashMap(),
12221224

12231225
determined_imports: Vec::new(),
12241226
indeterminate_imports: Vec::new(),
@@ -2779,8 +2781,8 @@ impl<'a> Resolver<'a> {
27792781
match resolution.base_def {
27802782
Def::Enum(did) | Def::TyAlias(did) | Def::Union(did) |
27812783
Def::Struct(did) | Def::Variant(did) if resolution.depth == 0 => {
2782-
if let Some(fields) = self.structs.get(&did) {
2783-
if fields.iter().any(|&field_name| name == field_name) {
2784+
if let Some(field_names) = self.field_names.get(&did) {
2785+
if field_names.iter().any(|&field_name| name == field_name) {
27842786
return Field;
27852787
}
27862788
}
@@ -2852,7 +2854,6 @@ impl<'a> Resolver<'a> {
28522854
_ => false,
28532855
};
28542856
if is_struct_variant {
2855-
let _ = self.structs.contains_key(&path_res.base_def.def_id());
28562857
let path_name = path_names_to_string(path, 0);
28572858

28582859
let mut err = resolve_struct_error(self,
@@ -2885,9 +2886,6 @@ impl<'a> Resolver<'a> {
28852886
}
28862887
} else {
28872888
// Be helpful if the name refers to a struct
2888-
// (The pattern matching def_tys where the id is in self.structs
2889-
// matches on regular structs while excluding tuple- and enum-like
2890-
// structs, which wouldn't result in this error.)
28912889
let path_name = path_names_to_string(path, 0);
28922890
let type_res = self.with_no_errors(|this| {
28932891
this.resolve_path(expr.id, path, 0, TypeNS)

0 commit comments

Comments
 (0)