Skip to content

Commit fd065a8

Browse files
authored
Auto merge of #36814 - petrochenkov:def, r=eddyb
Refactoring/bugfixing around definitions for struct/variant constructors d917c36 separates definitions for struct/variant constructors living in value namespace from struct/variant type definitions. adfb378 fixes cross-crate resolution of reexports reexporting half-items, like struct constructors without struct type or types without constructor. Such reexports can appear due to glob shadowing. Resolution now is not affected by the order in which items and reexports are decoded from metadata (cc #31337 (comment)). `try_define` is not used during building reduced graph anymore. 500 lines of this PR are tests for this exotic situation, the remaining line diff count is actually negative! :) c695d0c (and partially aabf132) moves most of pattern resolution checks from typeck to resolve (except those checking for associated items), uses the same wording for pattern resolution error messages from both typeck and resolve and makes the messages more precise. 11e3524 fixes seemingly incorrectly set `NON_ZERO_SIZED` attributes for struct/variant ctors in const eval. 4586fea eliminates `ty::VariantKind` in favor of `def::CtorKind`. The logic is that variant kinds are irrelevant for types, they make sense only when we deal with constructor functions/constants. Despite that `VariantDefData` still keeps a copy of `CtorKind`, but it's used only for various kinds of pretty-printing (and for storing in metadata). aabf132 is mostly a cleanup of various impossible or improperly used definitions, and other small definition cleanups. cc @jseyfried r? @eddyb
2 parents 1a41928 + bc0eabd commit fd065a8

Some content is hidden

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

70 files changed

+1031
-613
lines changed

Diff for: src/librustc/hir/def.rs

+60-25
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,46 @@ use util::nodemap::NodeMap;
1313
use syntax::ast;
1414
use hir;
1515

16+
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
17+
pub enum CtorKind {
18+
// Constructor function automatically created by a tuple struct/variant.
19+
Fn,
20+
// Constructor constant automatically created by a unit struct/variant.
21+
Const,
22+
// Unusable name in value namespace created by a struct variant.
23+
Fictive,
24+
}
25+
1626
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1727
pub enum Def {
18-
Fn(DefId),
19-
SelfTy(Option<DefId> /* trait */, Option<DefId> /* impl */),
28+
// Type namespace
2029
Mod(DefId),
21-
Static(DefId, bool /* is_mutbl */),
22-
Const(DefId),
23-
AssociatedConst(DefId),
24-
Local(DefId),
25-
Variant(DefId),
30+
Struct(DefId), // DefId refers to NodeId of the struct itself
31+
Union(DefId),
2632
Enum(DefId),
33+
Variant(DefId),
34+
Trait(DefId),
2735
TyAlias(DefId),
2836
AssociatedTy(DefId),
29-
Trait(DefId),
3037
PrimTy(hir::PrimTy),
3138
TyParam(DefId),
32-
Upvar(DefId, // def id of closed over local
33-
usize, // index in the freevars list of the closure
34-
ast::NodeId), // expr node that creates the closure
39+
SelfTy(Option<DefId> /* trait */, Option<DefId> /* impl */),
3540

36-
// If Def::Struct lives in type namespace it denotes a struct item and its DefId refers
37-
// to NodeId of the struct itself.
38-
// If Def::Struct lives in value namespace (e.g. tuple struct, unit struct expressions)
39-
// it denotes a constructor and its DefId refers to NodeId of the struct's constructor.
40-
Struct(DefId),
41-
Union(DefId),
42-
Label(ast::NodeId),
41+
// Value namespace
42+
Fn(DefId),
43+
Const(DefId),
44+
Static(DefId, bool /* is_mutbl */),
45+
StructCtor(DefId, CtorKind), // DefId refers to NodeId of the struct's constructor
46+
VariantCtor(DefId, CtorKind),
4347
Method(DefId),
48+
AssociatedConst(DefId),
49+
Local(DefId),
50+
Upvar(DefId, // def id of closed over local
51+
usize, // index in the freevars list of the closure
52+
ast::NodeId), // expr node that creates the closure
53+
Label(ast::NodeId),
54+
55+
// Both namespaces
4456
Err,
4557
}
4658

@@ -93,18 +105,35 @@ pub type ExportMap = NodeMap<Vec<Export>>;
93105

94106
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
95107
pub struct Export {
96-
pub name: ast::Name, // The name of the target.
97-
pub def_id: DefId, // The definition of the target.
108+
pub name: ast::Name, // The name of the target.
109+
pub def: Def, // The definition of the target.
110+
}
111+
112+
impl CtorKind {
113+
pub fn from_ast(vdata: &ast::VariantData) -> CtorKind {
114+
match *vdata {
115+
ast::VariantData::Tuple(..) => CtorKind::Fn,
116+
ast::VariantData::Unit(..) => CtorKind::Const,
117+
ast::VariantData::Struct(..) => CtorKind::Fictive,
118+
}
119+
}
120+
pub fn from_hir(vdata: &hir::VariantData) -> CtorKind {
121+
match *vdata {
122+
hir::VariantData::Tuple(..) => CtorKind::Fn,
123+
hir::VariantData::Unit(..) => CtorKind::Const,
124+
hir::VariantData::Struct(..) => CtorKind::Fictive,
125+
}
126+
}
98127
}
99128

100129
impl Def {
101130
pub fn def_id(&self) -> DefId {
102131
match *self {
103132
Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) |
104-
Def::Variant(id) | Def::Enum(id) | Def::TyAlias(id) | Def::AssociatedTy(id) |
105-
Def::TyParam(id) | Def::Struct(id) | Def::Union(id) | Def::Trait(id) |
106-
Def::Method(id) | Def::Const(id) | Def::AssociatedConst(id) |
107-
Def::Local(id) | Def::Upvar(id, ..) => {
133+
Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) | Def::TyAlias(id) |
134+
Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) |
135+
Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
136+
Def::AssociatedConst(id) | Def::Local(id) | Def::Upvar(id, ..) => {
108137
id
109138
}
110139

@@ -123,10 +152,16 @@ impl Def {
123152
Def::Mod(..) => "module",
124153
Def::Static(..) => "static",
125154
Def::Variant(..) => "variant",
155+
Def::VariantCtor(.., CtorKind::Fn) => "tuple variant",
156+
Def::VariantCtor(.., CtorKind::Const) => "unit variant",
157+
Def::VariantCtor(.., CtorKind::Fictive) => "struct variant",
126158
Def::Enum(..) => "enum",
127-
Def::TyAlias(..) => "type",
159+
Def::TyAlias(..) => "type alias",
128160
Def::AssociatedTy(..) => "associated type",
129161
Def::Struct(..) => "struct",
162+
Def::StructCtor(.., CtorKind::Fn) => "tuple struct",
163+
Def::StructCtor(.., CtorKind::Const) => "unit struct",
164+
Def::StructCtor(.., CtorKind::Fictive) => bug!("impossible struct constructor"),
130165
Def::Union(..) => "union",
131166
Def::Trait(..) => "trait",
132167
Def::Method(..) => "method",

Diff for: src/librustc/hir/lowering.rs

+19-5
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ use hir;
4444
use hir::map::Definitions;
4545
use hir::map::definitions::DefPathData;
4646
use hir::def_id::{DefIndex, DefId};
47-
use hir::def::{Def, PathResolution};
47+
use hir::def::{Def, CtorKind, PathResolution};
4848
use session::Session;
49+
use lint;
4950

5051
use std::collections::BTreeMap;
5152
use std::iter;
@@ -855,10 +856,23 @@ impl<'a> LoweringContext<'a> {
855856
})
856857
}
857858
PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)),
858-
PatKind::TupleStruct(ref pth, ref pats, ddpos) => {
859-
hir::PatKind::TupleStruct(self.lower_path(pth),
860-
pats.iter().map(|x| self.lower_pat(x)).collect(),
861-
ddpos)
859+
PatKind::TupleStruct(ref path, ref pats, ddpos) => {
860+
match self.resolver.get_resolution(p.id).map(|d| d.base_def) {
861+
Some(def @ Def::StructCtor(_, CtorKind::Const)) |
862+
Some(def @ Def::VariantCtor(_, CtorKind::Const)) => {
863+
// Temporarily lower `UnitVariant(..)` into `UnitVariant`
864+
// for backward compatibility.
865+
let msg = format!("expected tuple struct/variant, found {} `{}`",
866+
def.kind_name(), path);
867+
self.sess.add_lint(
868+
lint::builtin::MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
869+
p.id, p.span, msg
870+
);
871+
hir::PatKind::Path(None, self.lower_path(path))
872+
}
873+
_ => hir::PatKind::TupleStruct(self.lower_path(path),
874+
pats.iter().map(|x| self.lower_pat(x)).collect(), ddpos)
875+
}
862876
}
863877
PatKind::Path(ref opt_qself, ref path) => {
864878
let opt_qself = opt_qself.as_ref().map(|qself| {

Diff for: src/librustc/hir/pat_util.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
5858
PatKind::Path(..) |
5959
PatKind::Struct(..) => {
6060
match dm.get(&pat.id).map(|d| d.full_def()) {
61-
Some(Def::Variant(..)) => true,
61+
Some(Def::Variant(..)) | Some(Def::VariantCtor(..)) => true,
6262
_ => false
6363
}
6464
}
@@ -173,10 +173,9 @@ pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<DefId> {
173173
PatKind::TupleStruct(..) |
174174
PatKind::Path(..) |
175175
PatKind::Struct(..) => {
176-
match dm.get(&p.id) {
177-
Some(&PathResolution { base_def: Def::Variant(id), .. }) => {
178-
variants.push(id);
179-
}
176+
match dm.get(&p.id).map(|d| d.full_def()) {
177+
Some(Def::Variant(id)) |
178+
Some(Def::VariantCtor(id, ..)) => variants.push(id),
180179
_ => ()
181180
}
182181
}

Diff for: src/librustc/middle/cstore.rs

-5
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,6 @@ pub trait CrateStore<'tcx> {
201201
-> Option<DefIndex>;
202202
fn def_key(&self, def: DefId) -> hir_map::DefKey;
203203
fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath>;
204-
fn variant_kind(&self, def_id: DefId) -> Option<ty::VariantKind>;
205-
fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>;
206204
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
207205
fn item_children(&self, did: DefId) -> Vec<def::Export>;
208206

@@ -378,9 +376,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
378376
fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath> {
379377
bug!("relative_def_path")
380378
}
381-
fn variant_kind(&self, def_id: DefId) -> Option<ty::VariantKind> { bug!("variant_kind") }
382-
fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>
383-
{ bug!("struct_ctor_def_id") }
384379
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") }
385380
fn item_children(&self, did: DefId) -> Vec<def::Export> { bug!("item_children") }
386381

Diff for: src/librustc/middle/dead.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
106106
self.check_def_id(def.def_id());
107107
}
108108
_ if self.ignore_non_const_paths => (),
109-
Def::PrimTy(_) => (),
110-
Def::SelfTy(..) => (),
111-
Def::Variant(variant_id) => {
109+
Def::PrimTy(..) | Def::SelfTy(..) => (),
110+
Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => {
112111
if let Some(enum_id) = self.tcx.parent_def_id(variant_id) {
113112
self.check_def_id(enum_id);
114113
}

Diff for: src/librustc/middle/expr_use_visitor.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
10031003
// the leaves of the pattern tree structure.
10041004
return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| {
10051005
match tcx.expect_def_or_none(pat.id) {
1006-
Some(Def::Variant(variant_did)) => {
1006+
Some(Def::Variant(variant_did)) |
1007+
Some(Def::VariantCtor(variant_did, ..)) => {
10071008
let enum_did = tcx.parent_def_id(variant_did).unwrap();
10081009
let downcast_cmt = if tcx.lookup_adt_def(enum_did).is_univariant() {
10091010
cmt_pat
@@ -1015,12 +1016,14 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
10151016
debug!("variant downcast_cmt={:?} pat={:?}", downcast_cmt, pat);
10161017
delegate.matched_pat(pat, downcast_cmt, match_mode);
10171018
}
1018-
Some(Def::Struct(..)) | Some(Def::Union(..)) |
1019+
Some(Def::Struct(..)) | Some(Def::StructCtor(..)) | Some(Def::Union(..)) |
10191020
Some(Def::TyAlias(..)) | Some(Def::AssociatedTy(..)) => {
10201021
debug!("struct cmt_pat={:?} pat={:?}", cmt_pat, pat);
10211022
delegate.matched_pat(pat, cmt_pat, match_mode);
10221023
}
1023-
_ => {}
1024+
None | Some(Def::Local(..)) |
1025+
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => {}
1026+
def => bug!("unexpected definition: {:?}", def)
10241027
}
10251028
}));
10261029
}

Diff for: src/librustc/middle/mem_categorization.rs

+7-15
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ use hir::def_id::DefId;
7474
use hir::map as ast_map;
7575
use infer::InferCtxt;
7676
use middle::const_qualif::ConstQualif;
77-
use hir::def::Def;
77+
use hir::def::{Def, CtorKind};
7878
use ty::adjustment;
7979
use ty::{self, Ty, TyCtxt};
8080

@@ -524,20 +524,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
524524
id, expr_ty, def);
525525

526526
match def {
527-
Def::Struct(..) | Def::Union(..) | Def::Variant(..) | Def::Const(..) |
527+
Def::StructCtor(..) | Def::VariantCtor(..) | Def::Const(..) |
528528
Def::AssociatedConst(..) | Def::Fn(..) | Def::Method(..) => {
529529
Ok(self.cat_rvalue_node(id, span, expr_ty))
530530
}
531531

532-
Def::Mod(_) |
533-
Def::Trait(_) | Def::Enum(..) | Def::TyAlias(..) | Def::PrimTy(_) |
534-
Def::TyParam(..) |
535-
Def::Label(_) | Def::SelfTy(..) |
536-
Def::AssociatedTy(..) => {
537-
span_bug!(span, "Unexpected definition in \
538-
memory categorization: {:?}", def);
539-
}
540-
541532
Def::Static(_, mutbl) => {
542533
Ok(Rc::new(cmt_ {
543534
id:id,
@@ -598,7 +589,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
598589
}))
599590
}
600591

601-
Def::Err => bug!("Def::Err in memory categorization")
592+
def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def)
602593
}
603594
}
604595

@@ -1077,7 +1068,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
10771068
// alone) because PatKind::Struct can also refer to variants.
10781069
let cmt = match self.tcx().expect_def_or_none(pat.id) {
10791070
Some(Def::Err) => return Err(()),
1080-
Some(Def::Variant(variant_did)) => {
1071+
Some(Def::Variant(variant_did)) |
1072+
Some(Def::VariantCtor(variant_did, ..)) => {
10811073
// univariant enums do not need downcasts
10821074
let enum_did = self.tcx().parent_def_id(variant_did).unwrap();
10831075
if !self.tcx().lookup_adt_def(enum_did).is_univariant() {
@@ -1092,11 +1084,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
10921084
match pat.node {
10931085
PatKind::TupleStruct(_, ref subpats, ddpos) => {
10941086
let expected_len = match self.tcx().expect_def(pat.id) {
1095-
Def::Variant(def_id) => {
1087+
Def::VariantCtor(def_id, CtorKind::Fn) => {
10961088
let enum_def = self.tcx().parent_def_id(def_id).unwrap();
10971089
self.tcx().lookup_adt_def(enum_def).variant_with_id(def_id).fields.len()
10981090
}
1099-
Def::Struct(..) => {
1091+
Def::StructCtor(_, CtorKind::Fn) => {
11001092
match self.pat_ty(&pat)?.sty {
11011093
ty::TyAdt(adt_def, _) => {
11021094
adt_def.struct_variant().fields.len()

Diff for: src/librustc/middle/stability.rs

+3-12
Original file line numberDiff line numberDiff line change
@@ -617,12 +617,8 @@ pub fn check_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
617617
&Option<DeprecationEntry>)) {
618618
// Paths in import prefixes may have no resolution.
619619
match tcx.expect_def_or_none(id) {
620-
Some(Def::PrimTy(..)) => {}
621-
Some(Def::SelfTy(..)) => {}
622-
Some(def) => {
623-
maybe_do_stability_check(tcx, def.def_id(), path.span, cb);
624-
}
625-
None => {}
620+
None | Some(Def::PrimTy(..)) | Some(Def::SelfTy(..)) => {}
621+
Some(def) => maybe_do_stability_check(tcx, def.def_id(), path.span, cb)
626622
}
627623
}
628624

@@ -631,12 +627,7 @@ pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
631627
cb: &mut FnMut(DefId, Span,
632628
&Option<&Stability>,
633629
&Option<DeprecationEntry>)) {
634-
match tcx.expect_def(item.node.id) {
635-
Def::PrimTy(..) => {}
636-
def => {
637-
maybe_do_stability_check(tcx, def.def_id(), item.span, cb);
638-
}
639-
}
630+
maybe_do_stability_check(tcx, tcx.expect_def(item.node.id).def_id(), item.span, cb);
640631
}
641632

642633
pub fn check_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &hir::Pat,

Diff for: src/librustc/mir/repr.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
1515
use rustc_data_structures::control_flow_graph::dominators::{Dominators, dominators};
1616
use rustc_data_structures::control_flow_graph::{GraphPredecessors, GraphSuccessors};
1717
use rustc_data_structures::control_flow_graph::ControlFlowGraph;
18+
use hir::def::CtorKind;
1819
use hir::def_id::DefId;
1920
use ty::subst::Substs;
2021
use ty::{self, AdtDef, ClosureSubsts, Region, Ty};
@@ -1140,10 +1141,10 @@ impl<'tcx> Debug for Rvalue<'tcx> {
11401141
ppaux::parameterized(fmt, substs, variant_def.did,
11411142
ppaux::Ns::Value, &[])?;
11421143

1143-
match variant_def.kind {
1144-
ty::VariantKind::Unit => Ok(()),
1145-
ty::VariantKind::Tuple => fmt_tuple(fmt, lvs),
1146-
ty::VariantKind::Struct => {
1144+
match variant_def.ctor_kind {
1145+
CtorKind::Const => Ok(()),
1146+
CtorKind::Fn => fmt_tuple(fmt, lvs),
1147+
CtorKind::Fictive => {
11471148
let mut struct_fmt = fmt.debug_struct("");
11481149
for (field, lv) in variant_def.fields.iter().zip(lvs) {
11491150
struct_fmt.field(&field.name.as_str(), lv);

0 commit comments

Comments
 (0)