Skip to content

Commit 2cdd9f1

Browse files
committed
Rewrite check_pat_enum, split it into check_pat_tuple_struct and check_pat_path
Update definitions in def_map for associated types written in unqualified form (like `Self::Output`) Cleanup finish_resolving_def_to_ty/resolve_ty_and_def_ufcs Make VariantDef's available through constructor IDs
1 parent eb32440 commit 2cdd9f1

17 files changed

+230
-328
lines changed

src/librustc/hir/def.rs

-9
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,6 @@ impl Def {
137137
}
138138
}
139139

140-
pub fn variant_def_ids(&self) -> Option<(DefId, DefId)> {
141-
match *self {
142-
Def::Variant(enum_id, var_id) => {
143-
Some((enum_id, var_id))
144-
}
145-
_ => None
146-
}
147-
}
148-
149140
pub fn kind_name(&self) -> &'static str {
150141
match *self {
151142
Def::Fn(..) => "function",

src/librustc/hir/pat_util.rs

-19
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,12 @@ use hir::def::*;
1212
use hir::def_id::DefId;
1313
use hir::{self, PatKind};
1414
use ty::TyCtxt;
15-
use util::nodemap::FnvHashMap;
1615
use syntax::ast;
1716
use syntax::codemap::Spanned;
1817
use syntax_pos::{Span, DUMMY_SP};
1918

2019
use std::iter::{Enumerate, ExactSizeIterator};
2120

22-
pub type PatIdMap = FnvHashMap<ast::Name, ast::NodeId>;
23-
2421
pub struct EnumerateAndAdjust<I> {
2522
enumerate: Enumerate<I>,
2623
gap_pos: usize,
@@ -97,22 +94,6 @@ pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool {
9794
}
9895
}
9996

100-
// Same as above, except that partially-resolved defs cause `false` to be
101-
// returned instead of a panic.
102-
pub fn pat_is_resolved_const(dm: &DefMap, pat: &hir::Pat) -> bool {
103-
match pat.node {
104-
PatKind::Path(..) | PatKind::QPath(..) => {
105-
match dm.get(&pat.id)
106-
.and_then(|d| if d.depth == 0 { Some(d.base_def) }
107-
else { None } ) {
108-
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true,
109-
_ => false
110-
}
111-
}
112-
_ => false
113-
}
114-
}
115-
11697
/// Call `f` on every "binding" in a pattern, e.g., on `a` in
11798
/// `match foo() { Some(a) => (), None => () }`
11899
pub fn pat_bindings<F>(pat: &hir::Pat, mut f: F)

src/librustc/ty/context.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -591,17 +591,21 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
591591
self.global_interners.arenas.trait_defs.alloc(def)
592592
}
593593

594+
pub fn insert_adt_def(self, did: DefId, adt_def: ty::AdtDefMaster<'gcx>) {
595+
// this will need a transmute when reverse-variance is removed
596+
if let Some(prev) = self.adt_defs.borrow_mut().insert(did, adt_def) {
597+
bug!("Tried to overwrite interned AdtDef: {:?}", prev)
598+
}
599+
}
600+
594601
pub fn intern_adt_def(self,
595602
did: DefId,
596603
kind: ty::AdtKind,
597604
variants: Vec<ty::VariantDefData<'gcx, 'gcx>>)
598605
-> ty::AdtDefMaster<'gcx> {
599606
let def = ty::AdtDefData::new(self, did, kind, variants);
600607
let interned = self.global_interners.arenas.adt_defs.alloc(def);
601-
// this will need a transmute when reverse-variance is removed
602-
if let Some(prev) = self.adt_defs.borrow_mut().insert(did, interned) {
603-
bug!("Tried to overwrite interned AdtDef: {:?}", prev)
604-
}
608+
self.insert_adt_def(did, interned);
605609
interned
606610
}
607611

src/librustc/ty/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -2454,6 +2454,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
24542454
self.def_map.borrow().get(&id).map(|resolution| resolution.full_def())
24552455
}
24562456

2457+
// Returns `ty::VariantDef` if `def` refers to a struct,
2458+
// or variant or their constructors, panics otherwise.
2459+
pub fn expect_variant_def(self, def: Def) -> VariantDef<'tcx> {
2460+
match def {
2461+
Def::Variant(enum_did, did) => {
2462+
self.lookup_adt_def(enum_did).variant_with_id(did)
2463+
}
2464+
Def::Struct(did) => {
2465+
self.lookup_adt_def(did).struct_variant()
2466+
}
2467+
_ => bug!("expect_variant_def used with unexpected def {:?}", def)
2468+
}
2469+
}
2470+
24572471
pub fn def_key(self, id: DefId) -> ast_map::DefKey {
24582472
if id.is_local() {
24592473
self.map.def_key(id)

src/librustc_metadata/decoder.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -471,23 +471,29 @@ pub fn get_adt_def<'a, 'tcx>(intr: &IdentInterner,
471471

472472
let doc = cdata.lookup_item(item_id);
473473
let did = DefId { krate: cdata.cnum, index: item_id };
474+
let mut ctor_did = None;
474475
let (kind, variants) = match item_family(doc) {
475476
Enum => {
476477
(ty::AdtKind::Enum,
477478
get_enum_variants(intr, cdata, doc))
478479
}
479480
Struct(..) => {
480-
let ctor_did =
481-
reader::maybe_get_doc(doc, tag_items_data_item_struct_ctor).
482-
map_or(did, |ctor_doc| translated_def_id(cdata, ctor_doc));
481+
// Use separate constructor id for unit/tuple structs and reuse did for braced structs.
482+
ctor_did = reader::maybe_get_doc(doc, tag_items_data_item_struct_ctor).map(|ctor_doc| {
483+
translated_def_id(cdata, ctor_doc)
484+
});
483485
(ty::AdtKind::Struct,
484-
vec![get_struct_variant(intr, cdata, doc, ctor_did)])
486+
vec![get_struct_variant(intr, cdata, doc, ctor_did.unwrap_or(did))])
485487
}
486488
_ => bug!("get_adt_def called on a non-ADT {:?} - {:?}",
487489
item_family(doc), did)
488490
};
489491

490492
let adt = tcx.intern_adt_def(did, kind, variants);
493+
if let Some(ctor_did) = ctor_did {
494+
// Make adt definition available through constructor id as well.
495+
tcx.insert_adt_def(ctor_did, adt);
496+
}
491497

492498
// this needs to be done *after* the variant is interned,
493499
// to support recursive structures

src/librustc_typeck/astconv.rs

+40-40
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ use rustc_const_eval::{eval_const_expr_partial, ConstEvalErr};
5353
use rustc_const_eval::EvalHint::UncheckedExprHint;
5454
use rustc_const_eval::ErrKind::ErroneousReferencedConstant;
5555
use hir::{self, SelfKind};
56-
use hir::def::{self, Def};
56+
use hir::def::{Def, PathResolution};
5757
use hir::def_id::DefId;
5858
use hir::print as pprust;
5959
use middle::resolve_lifetime as rl;
@@ -1327,7 +1327,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
13271327
};
13281328

13291329
if self.ensure_super_predicates(span, trait_did).is_err() {
1330-
return (tcx.types.err, ty_path_def);
1330+
return (tcx.types.err, Def::Err);
13311331
}
13321332

13331333
let candidates: Vec<ty::PolyTraitRef> =
@@ -1341,7 +1341,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
13411341
&assoc_name.as_str(),
13421342
span) {
13431343
Ok(bound) => bound,
1344-
Err(ErrorReported) => return (tcx.types.err, ty_path_def),
1344+
Err(ErrorReported) => return (tcx.types.err, Def::Err),
13451345
}
13461346
}
13471347
(&ty::TyParam(_), Def::SelfTy(Some(trait_did), None)) => {
@@ -1351,7 +1351,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
13511351
assoc_name,
13521352
span) {
13531353
Ok(bound) => bound,
1354-
Err(ErrorReported) => return (tcx.types.err, ty_path_def),
1354+
Err(ErrorReported) => return (tcx.types.err, Def::Err),
13551355
}
13561356
}
13571357
(&ty::TyParam(_), Def::TyParam(_, _, param_did, param_name)) => {
@@ -1361,15 +1361,15 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
13611361
assoc_name,
13621362
span) {
13631363
Ok(bound) => bound,
1364-
Err(ErrorReported) => return (tcx.types.err, ty_path_def),
1364+
Err(ErrorReported) => return (tcx.types.err, Def::Err),
13651365
}
13661366
}
13671367
_ => {
13681368
self.report_ambiguous_associated_type(span,
13691369
&ty.to_string(),
13701370
"Trait",
13711371
&assoc_name.as_str());
1372-
return (tcx.types.err, ty_path_def);
1372+
return (tcx.types.err, Def::Err);
13731373
}
13741374
};
13751375

@@ -1574,45 +1574,46 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
15741574
}
15751575
}
15761576

1577-
// Note that both base_segments and assoc_segments may be empty, although not at
1578-
// the same time.
1577+
// Resolve possibly associated type path into a type and final definition.
1578+
// Note that both base_segments and assoc_segments may be empty, although not at same time.
15791579
pub fn finish_resolving_def_to_ty(&self,
15801580
rscope: &RegionScope,
15811581
span: Span,
15821582
param_mode: PathParamMode,
1583-
mut def: Def,
1583+
base_def: Def,
15841584
opt_self_ty: Option<Ty<'tcx>>,
15851585
base_path_ref_id: ast::NodeId,
15861586
base_segments: &[hir::PathSegment],
15871587
assoc_segments: &[hir::PathSegment])
15881588
-> (Ty<'tcx>, Def) {
1589-
debug!("finish_resolving_def_to_ty(def={:?}, \
1589+
// Convert the base type.
1590+
debug!("finish_resolving_def_to_ty(base_def={:?}, \
15901591
base_segments={:?}, \
15911592
assoc_segments={:?})",
1592-
def,
1593+
base_def,
15931594
base_segments,
15941595
assoc_segments);
1595-
let mut ty = self.base_def_to_ty(rscope,
1596-
span,
1597-
param_mode,
1598-
def,
1599-
opt_self_ty,
1600-
base_path_ref_id,
1601-
base_segments);
1602-
debug!("finish_resolving_def_to_ty: base_def_to_ty returned {:?}", ty);
1596+
let base_ty = self.base_def_to_ty(rscope,
1597+
span,
1598+
param_mode,
1599+
base_def,
1600+
opt_self_ty,
1601+
base_path_ref_id,
1602+
base_segments);
1603+
debug!("finish_resolving_def_to_ty: base_def_to_ty returned {:?}", base_ty);
1604+
16031605
// If any associated type segments remain, attempt to resolve them.
1606+
let (mut ty, mut def) = (base_ty, base_def);
16041607
for segment in assoc_segments {
16051608
debug!("finish_resolving_def_to_ty: segment={:?}", segment);
1606-
if ty.sty == ty::TyError {
1609+
// This is pretty bad (it will fail except for T::A and Self::A).
1610+
let (new_ty, new_def) = self.associated_path_def_to_ty(span, ty, def, segment);
1611+
ty = new_ty;
1612+
def = new_def;
1613+
1614+
if def == Def::Err {
16071615
break;
16081616
}
1609-
// This is pretty bad (it will fail except for T::A and Self::A).
1610-
let (a_ty, a_def) = self.associated_path_def_to_ty(span,
1611-
ty,
1612-
def,
1613-
segment);
1614-
ty = a_ty;
1615-
def = a_def;
16161617
}
16171618
(ty, def)
16181619
}
@@ -1719,23 +1720,22 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
17191720
hir::TyPath(ref maybe_qself, ref path) => {
17201721
debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
17211722
let path_res = tcx.expect_resolution(ast_ty.id);
1722-
let def = path_res.base_def;
17231723
let base_ty_end = path.segments.len() - path_res.depth;
17241724
let opt_self_ty = maybe_qself.as_ref().map(|qself| {
17251725
self.ast_ty_to_ty(rscope, &qself.ty)
17261726
});
1727-
let (ty, _def) = self.finish_resolving_def_to_ty(rscope,
1728-
ast_ty.span,
1729-
PathParamMode::Explicit,
1730-
def,
1731-
opt_self_ty,
1732-
ast_ty.id,
1733-
&path.segments[..base_ty_end],
1734-
&path.segments[base_ty_end..]);
1735-
1736-
if path_res.depth != 0 && ty.sty != ty::TyError {
1737-
// Write back the new resolution.
1738-
tcx.def_map.borrow_mut().insert(ast_ty.id, def::PathResolution::new(def));
1727+
let (ty, def) = self.finish_resolving_def_to_ty(rscope,
1728+
ast_ty.span,
1729+
PathParamMode::Explicit,
1730+
path_res.base_def,
1731+
opt_self_ty,
1732+
ast_ty.id,
1733+
&path.segments[..base_ty_end],
1734+
&path.segments[base_ty_end..]);
1735+
1736+
// Write back the new resolution.
1737+
if path_res.depth != 0 {
1738+
tcx.def_map.borrow_mut().insert(ast_ty.id, PathResolution::new(def));
17391739
}
17401740

17411741
ty

0 commit comments

Comments
 (0)