rustc: combine partial_def_map and last_private_map into def_map.
This commit is contained in:
parent
06f362aeb3
commit
5a6a9ed792
38 changed files with 442 additions and 447 deletions
|
@ -406,7 +406,7 @@ struct ImproperCTypesVisitor<'a, 'tcx: 'a> {
|
||||||
|
|
||||||
impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||||
fn check_def(&mut self, sp: Span, id: ast::NodeId) {
|
fn check_def(&mut self, sp: Span, id: ast::NodeId) {
|
||||||
match self.cx.tcx.def_map.borrow()[id].clone() {
|
match self.cx.tcx.def_map.borrow()[id].full_def() {
|
||||||
def::DefPrimTy(ast::TyInt(ast::TyIs(_))) => {
|
def::DefPrimTy(ast::TyInt(ast::TyIs(_))) => {
|
||||||
self.cx.span_lint(IMPROPER_CTYPES, sp,
|
self.cx.span_lint(IMPROPER_CTYPES, sp,
|
||||||
"found rust type `isize` in foreign module, while \
|
"found rust type `isize` in foreign module, while \
|
||||||
|
@ -1000,7 +1000,8 @@ impl LintPass for NonSnakeCase {
|
||||||
|
|
||||||
fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
|
fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
|
||||||
if let &ast::PatIdent(_, ref path1, _) = &p.node {
|
if let &ast::PatIdent(_, ref path1, _) = &p.node {
|
||||||
if let Some(&def::DefLocal(_)) = cx.tcx.def_map.borrow().get(&p.id) {
|
let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
|
||||||
|
if let Some(def::DefLocal(_)) = def {
|
||||||
self.check_snake_case(cx, "variable", path1.node, p.span);
|
self.check_snake_case(cx, "variable", path1.node, p.span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1065,8 +1066,8 @@ impl LintPass for NonUpperCaseGlobals {
|
||||||
|
|
||||||
fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
|
fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
|
||||||
// Lint for constants that look like binding identifiers (#7526)
|
// Lint for constants that look like binding identifiers (#7526)
|
||||||
match (&p.node, cx.tcx.def_map.borrow().get(&p.id)) {
|
match (&p.node, cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def())) {
|
||||||
(&ast::PatIdent(_, ref path1, _), Some(&def::DefConst(..))) => {
|
(&ast::PatIdent(_, ref path1, _), Some(def::DefConst(..))) => {
|
||||||
NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
|
NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
|
||||||
path1.node, p.span);
|
path1.node, p.span);
|
||||||
}
|
}
|
||||||
|
@ -1226,10 +1227,13 @@ impl LintPass for NonShorthandFieldPatterns {
|
||||||
fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) {
|
fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) {
|
||||||
let def_map = cx.tcx.def_map.borrow();
|
let def_map = cx.tcx.def_map.borrow();
|
||||||
if let ast::PatStruct(_, ref v, _) = pat.node {
|
if let ast::PatStruct(_, ref v, _) = pat.node {
|
||||||
for fieldpat in v.iter()
|
let field_pats = v.iter()
|
||||||
.filter(|fieldpat| !fieldpat.node.is_shorthand)
|
.filter(|fieldpat| !fieldpat.node.is_shorthand)
|
||||||
.filter(|fieldpat| def_map.get(&fieldpat.node.pat.id)
|
.filter(|fieldpat| {
|
||||||
== Some(&def::DefLocal(fieldpat.node.pat.id))) {
|
let def = def_map.get(&fieldpat.node.pat.id).map(|d| d.full_def());
|
||||||
|
def == Some(def::DefLocal(fieldpat.node.pat.id))
|
||||||
|
});
|
||||||
|
for fieldpat in field_pats {
|
||||||
if let ast::PatIdent(_, ident, None) = fieldpat.node.pat.node {
|
if let ast::PatIdent(_, ident, None) = fieldpat.node.pat.node {
|
||||||
if ident.node.as_str() == fieldpat.node.ident.as_str() {
|
if ident.node.as_str() == fieldpat.node.ident.as_str() {
|
||||||
cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span,
|
cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span,
|
||||||
|
@ -1908,10 +1912,7 @@ impl LintPass for UnconditionalRecursion {
|
||||||
_: ast::Ident,
|
_: ast::Ident,
|
||||||
id: ast::NodeId) -> bool {
|
id: ast::NodeId) -> bool {
|
||||||
tcx.def_map.borrow().get(&id)
|
tcx.def_map.borrow().get(&id)
|
||||||
.map_or(false, |def| {
|
.map_or(false, |def| def.def_id() == ast_util::local_def(fn_id))
|
||||||
let did = def.def_id();
|
|
||||||
ast_util::is_local(did) && did.node == fn_id
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the method call `id` refers to method `method_id`
|
// check if the method call `id` refers to method `method_id`
|
||||||
|
|
|
@ -1870,9 +1870,7 @@ struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
|
||||||
impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> {
|
impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> {
|
||||||
fn visit_item(&mut self, item: &ast::Item) {
|
fn visit_item(&mut self, item: &ast::Item) {
|
||||||
if let ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node {
|
if let ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node {
|
||||||
let def_map = &self.ecx.tcx.def_map;
|
let def_id = self.ecx.tcx.def_map.borrow()[trait_ref.ref_id].def_id();
|
||||||
let trait_def = def_map.borrow()[trait_ref.ref_id].clone();
|
|
||||||
let def_id = trait_def.def_id();
|
|
||||||
|
|
||||||
// Load eagerly if this is an implementation of the Drop trait
|
// Load eagerly if this is an implementation of the Drop trait
|
||||||
// or if the trait is not defined in this crate.
|
// or if the trait is not defined in this crate.
|
||||||
|
|
|
@ -65,7 +65,7 @@ pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
|
||||||
tcx.sess.span_bug(ast_ty.span,
|
tcx.sess.span_bug(ast_ty.span,
|
||||||
&format!("unbound path {}", path.repr(tcx)))
|
&format!("unbound path {}", path.repr(tcx)))
|
||||||
}
|
}
|
||||||
Some(&d) => d
|
Some(d) => d.full_def()
|
||||||
};
|
};
|
||||||
if let def::DefPrimTy(nty) = def {
|
if let def::DefPrimTy(nty) = def {
|
||||||
Some(prim_ty_to_ty(tcx, &path.segments[], nty))
|
Some(prim_ty_to_ty(tcx, &path.segments[], nty))
|
||||||
|
|
|
@ -25,6 +25,7 @@ use metadata::tydecode::{RegionParameter, ClosureSource};
|
||||||
use metadata::tyencode;
|
use metadata::tyencode;
|
||||||
use middle::check_const::ConstQualif;
|
use middle::check_const::ConstQualif;
|
||||||
use middle::mem_categorization::Typer;
|
use middle::mem_categorization::Typer;
|
||||||
|
use middle::privacy::{AllPublic, LastMod};
|
||||||
use middle::subst;
|
use middle::subst;
|
||||||
use middle::subst::VecPerParamSpace;
|
use middle::subst::VecPerParamSpace;
|
||||||
use middle::ty::{self, Ty, MethodCall, MethodCallee, MethodOrigin};
|
use middle::ty::{self, Ty, MethodCall, MethodCallee, MethodOrigin};
|
||||||
|
@ -1148,10 +1149,10 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
||||||
|
|
||||||
debug!("Encoding side tables for id {}", id);
|
debug!("Encoding side tables for id {}", id);
|
||||||
|
|
||||||
if let Some(def) = tcx.def_map.borrow().get(&id) {
|
if let Some(def) = tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
|
||||||
rbml_w.tag(c::tag_table_def, |rbml_w| {
|
rbml_w.tag(c::tag_table_def, |rbml_w| {
|
||||||
rbml_w.id(id);
|
rbml_w.id(id);
|
||||||
rbml_w.tag(c::tag_table_val, |rbml_w| (*def).encode(rbml_w).unwrap());
|
rbml_w.tag(c::tag_table_val, |rbml_w| def.encode(rbml_w).unwrap());
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1851,7 +1852,12 @@ fn decode_side_tables(dcx: &DecodeContext,
|
||||||
match value {
|
match value {
|
||||||
c::tag_table_def => {
|
c::tag_table_def => {
|
||||||
let def = decode_def(dcx, val_doc);
|
let def = decode_def(dcx, val_doc);
|
||||||
dcx.tcx.def_map.borrow_mut().insert(id, def);
|
dcx.tcx.def_map.borrow_mut().insert(id, def::PathResolution {
|
||||||
|
base_def: def,
|
||||||
|
// This doesn't matter cross-crate.
|
||||||
|
last_private: LastMod(AllPublic),
|
||||||
|
depth: 0
|
||||||
|
});
|
||||||
}
|
}
|
||||||
c::tag_table_node_type => {
|
c::tag_table_node_type => {
|
||||||
let ty = val_dsr.read_ty(dcx);
|
let ty = val_dsr.read_ty(dcx);
|
||||||
|
|
|
@ -610,32 +610,24 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
||||||
fn find_scope(&self,
|
fn find_scope(&self,
|
||||||
expr: &ast::Expr,
|
expr: &ast::Expr,
|
||||||
label: Option<ast::Ident>) -> LoopScope {
|
label: Option<ast::Ident>) -> LoopScope {
|
||||||
match label {
|
if label.is_none() {
|
||||||
None => {
|
return *self.loop_scopes.last().unwrap();
|
||||||
return *self.loop_scopes.last().unwrap();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Some(_) => {
|
match self.tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()) {
|
||||||
match self.tcx.def_map.borrow().get(&expr.id) {
|
Some(def::DefLabel(loop_id)) => {
|
||||||
Some(&def::DefLabel(loop_id)) => {
|
for l in &self.loop_scopes {
|
||||||
for l in &self.loop_scopes {
|
if l.loop_id == loop_id {
|
||||||
if l.loop_id == loop_id {
|
return *l;
|
||||||
return *l;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.tcx.sess.span_bug(
|
|
||||||
expr.span,
|
|
||||||
&format!("no loop scope for id {}",
|
|
||||||
loop_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
r => {
|
|
||||||
self.tcx.sess.span_bug(
|
|
||||||
expr.span,
|
|
||||||
&format!("bad entry `{:?}` in def_map for label",
|
|
||||||
r));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.tcx.sess.span_bug(expr.span,
|
||||||
|
&format!("no loop scope for id {}", loop_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
r => {
|
||||||
|
self.tcx.sess.span_bug(expr.span,
|
||||||
|
&format!("bad entry `{:?}` in def_map for label", r));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -440,7 +440,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
||||||
let def = v.tcx.def_map.borrow().get(&e.id).cloned();
|
let def = v.tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
|
||||||
match def {
|
match def {
|
||||||
Some(def::DefVariant(_, _, _)) => {
|
Some(def::DefVariant(_, _, _)) => {
|
||||||
// Count the discriminator or function pointer.
|
// Count the discriminator or function pointer.
|
||||||
|
@ -499,7 +499,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
||||||
_ => break
|
_ => break
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let def = v.tcx.def_map.borrow().get(&callee.id).cloned();
|
let def = v.tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def());
|
||||||
match def {
|
match def {
|
||||||
Some(def::DefStruct(..)) => {}
|
Some(def::DefStruct(..)) => {}
|
||||||
Some(def::DefVariant(..)) => {
|
Some(def::DefVariant(..)) => {
|
||||||
|
|
|
@ -242,7 +242,7 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
|
||||||
ast::PatIdent(ast::BindByValue(ast::MutImmutable), ident, None) => {
|
ast::PatIdent(ast::BindByValue(ast::MutImmutable), ident, None) => {
|
||||||
let pat_ty = ty::pat_ty(cx.tcx, p);
|
let pat_ty = ty::pat_ty(cx.tcx, p);
|
||||||
if let ty::ty_enum(def_id, _) = pat_ty.sty {
|
if let ty::ty_enum(def_id, _) = pat_ty.sty {
|
||||||
let def = cx.tcx.def_map.borrow().get(&p.id).cloned();
|
let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
|
||||||
if let Some(DefLocal(_)) = def {
|
if let Some(DefLocal(_)) = def {
|
||||||
if ty::enum_variants(cx.tcx, def_id).iter().any(|variant|
|
if ty::enum_variants(cx.tcx, def_id).iter().any(|variant|
|
||||||
token::get_name(variant.name) == token::get_name(ident.node.name)
|
token::get_name(variant.name) == token::get_name(ident.node.name)
|
||||||
|
@ -434,7 +434,7 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
|
||||||
fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
|
fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
|
||||||
return match pat.node {
|
return match pat.node {
|
||||||
ast::PatIdent(..) | ast::PatEnum(..) => {
|
ast::PatIdent(..) | ast::PatEnum(..) => {
|
||||||
let def = self.tcx.def_map.borrow().get(&pat.id).cloned();
|
let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
|
||||||
match def {
|
match def {
|
||||||
Some(DefConst(did)) => match lookup_const_by_id(self.tcx, did) {
|
Some(DefConst(did)) => match lookup_const_by_id(self.tcx, did) {
|
||||||
Some(const_expr) => {
|
Some(const_expr) => {
|
||||||
|
@ -733,28 +733,28 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
|
||||||
let pat = raw_pat(p);
|
let pat = raw_pat(p);
|
||||||
match pat.node {
|
match pat.node {
|
||||||
ast::PatIdent(..) =>
|
ast::PatIdent(..) =>
|
||||||
match cx.tcx.def_map.borrow().get(&pat.id) {
|
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
|
||||||
Some(&DefConst(..)) =>
|
Some(DefConst(..)) =>
|
||||||
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
|
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
|
||||||
been rewritten"),
|
been rewritten"),
|
||||||
Some(&DefStruct(_)) => vec!(Single),
|
Some(DefStruct(_)) => vec!(Single),
|
||||||
Some(&DefVariant(_, id, _)) => vec!(Variant(id)),
|
Some(DefVariant(_, id, _)) => vec!(Variant(id)),
|
||||||
_ => vec!()
|
_ => vec!()
|
||||||
},
|
},
|
||||||
ast::PatEnum(..) =>
|
ast::PatEnum(..) =>
|
||||||
match cx.tcx.def_map.borrow().get(&pat.id) {
|
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
|
||||||
Some(&DefConst(..)) =>
|
Some(DefConst(..)) =>
|
||||||
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
|
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
|
||||||
been rewritten"),
|
been rewritten"),
|
||||||
Some(&DefVariant(_, id, _)) => vec!(Variant(id)),
|
Some(DefVariant(_, id, _)) => vec!(Variant(id)),
|
||||||
_ => vec!(Single)
|
_ => vec!(Single)
|
||||||
},
|
},
|
||||||
ast::PatStruct(..) =>
|
ast::PatStruct(..) =>
|
||||||
match cx.tcx.def_map.borrow().get(&pat.id) {
|
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
|
||||||
Some(&DefConst(..)) =>
|
Some(DefConst(..)) =>
|
||||||
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
|
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
|
||||||
been rewritten"),
|
been rewritten"),
|
||||||
Some(&DefVariant(_, id, _)) => vec!(Variant(id)),
|
Some(DefVariant(_, id, _)) => vec!(Variant(id)),
|
||||||
_ => vec!(Single)
|
_ => vec!(Single)
|
||||||
},
|
},
|
||||||
ast::PatLit(ref expr) =>
|
ast::PatLit(ref expr) =>
|
||||||
|
@ -847,7 +847,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
|
||||||
Some(repeat(DUMMY_WILD_PAT).take(arity).collect()),
|
Some(repeat(DUMMY_WILD_PAT).take(arity).collect()),
|
||||||
|
|
||||||
ast::PatIdent(_, _, _) => {
|
ast::PatIdent(_, _, _) => {
|
||||||
let opt_def = cx.tcx.def_map.borrow().get(&pat_id).cloned();
|
let opt_def = cx.tcx.def_map.borrow().get(&pat_id).map(|d| d.full_def());
|
||||||
match opt_def {
|
match opt_def {
|
||||||
Some(DefConst(..)) =>
|
Some(DefConst(..)) =>
|
||||||
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
|
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
|
||||||
|
@ -862,7 +862,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::PatEnum(_, ref args) => {
|
ast::PatEnum(_, ref args) => {
|
||||||
let def = cx.tcx.def_map.borrow()[pat_id].clone();
|
let def = cx.tcx.def_map.borrow()[pat_id].full_def();
|
||||||
match def {
|
match def {
|
||||||
DefConst(..) =>
|
DefConst(..) =>
|
||||||
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
|
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
|
||||||
|
@ -880,7 +880,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
|
||||||
|
|
||||||
ast::PatStruct(_, ref pattern_fields, _) => {
|
ast::PatStruct(_, ref pattern_fields, _) => {
|
||||||
// Is this a struct or an enum variant?
|
// Is this a struct or an enum variant?
|
||||||
let def = cx.tcx.def_map.borrow()[pat_id].clone();
|
let def = cx.tcx.def_map.borrow()[pat_id].full_def();
|
||||||
let class_id = match def {
|
let class_id = match def {
|
||||||
DefConst(..) =>
|
DefConst(..) =>
|
||||||
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
|
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
|
||||||
|
|
|
@ -94,9 +94,9 @@ impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> {
|
||||||
fn visit_expr(&mut self, e: &ast::Expr) {
|
fn visit_expr(&mut self, e: &ast::Expr) {
|
||||||
match e.node {
|
match e.node {
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
||||||
match self.def_map.borrow().get(&e.id) {
|
match self.def_map.borrow().get(&e.id).map(|d| d.full_def()) {
|
||||||
Some(&DefStatic(def_id, _)) |
|
Some(DefStatic(def_id, _)) |
|
||||||
Some(&DefConst(def_id)) if
|
Some(DefConst(def_id)) if
|
||||||
ast_util::is_local(def_id) => {
|
ast_util::is_local(def_id) => {
|
||||||
match self.ast_map.get(def_id.node) {
|
match self.ast_map.get(def_id.node) {
|
||||||
ast_map::NodeItem(item) =>
|
ast_map::NodeItem(item) =>
|
||||||
|
|
|
@ -31,7 +31,7 @@ use std::{i8, i16, i32, i64};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
fn lookup_const<'a>(tcx: &'a ty::ctxt, e: &Expr) -> Option<&'a Expr> {
|
fn lookup_const<'a>(tcx: &'a ty::ctxt, e: &Expr) -> Option<&'a Expr> {
|
||||||
let opt_def = tcx.def_map.borrow().get(&e.id).cloned();
|
let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
|
||||||
match opt_def {
|
match opt_def {
|
||||||
Some(def::DefConst(def_id)) => {
|
Some(def::DefConst(def_id)) => {
|
||||||
lookup_const_by_id(tcx, def_id)
|
lookup_const_by_id(tcx, def_id)
|
||||||
|
@ -148,11 +148,11 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
|
||||||
ast::PatTup(exprs.iter().map(|expr| const_expr_to_pat(tcx, &**expr, span)).collect()),
|
ast::PatTup(exprs.iter().map(|expr| const_expr_to_pat(tcx, &**expr, span)).collect()),
|
||||||
|
|
||||||
ast::ExprCall(ref callee, ref args) => {
|
ast::ExprCall(ref callee, ref args) => {
|
||||||
let def = tcx.def_map.borrow()[callee.id].clone();
|
let def = tcx.def_map.borrow()[callee.id];
|
||||||
if let Vacant(entry) = tcx.def_map.borrow_mut().entry(expr.id) {
|
if let Vacant(entry) = tcx.def_map.borrow_mut().entry(expr.id) {
|
||||||
entry.insert(def);
|
entry.insert(def);
|
||||||
}
|
}
|
||||||
let path = match def {
|
let path = match def.full_def() {
|
||||||
def::DefStruct(def_id) => def_to_path(tcx, def_id),
|
def::DefStruct(def_id) => def_to_path(tcx, def_id),
|
||||||
def::DefVariant(_, variant_did, _) => def_to_path(tcx, variant_did),
|
def::DefVariant(_, variant_did, _) => def_to_path(tcx, variant_did),
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
|
@ -179,7 +179,7 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprPath(ref path) => {
|
ast::ExprPath(ref path) => {
|
||||||
let opt_def = tcx.def_map.borrow().get(&expr.id).cloned();
|
let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def());
|
||||||
match opt_def {
|
match opt_def {
|
||||||
Some(def::DefStruct(..)) =>
|
Some(def::DefStruct(..)) =>
|
||||||
ast::PatStruct(path.clone(), vec![], false),
|
ast::PatStruct(path.clone(), vec![], false),
|
||||||
|
@ -389,7 +389,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||||
cast_const(val, ety)
|
cast_const(val, ety)
|
||||||
}
|
}
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
||||||
let opt_def = tcx.def_map.borrow().get(&e.id).cloned();
|
let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
|
||||||
let (const_expr, const_ty) = match opt_def {
|
let (const_expr, const_ty) = match opt_def {
|
||||||
Some(def::DefConst(def_id)) => {
|
Some(def::DefConst(def_id)) => {
|
||||||
if ast_util::is_local(def_id) {
|
if ast_util::is_local(def_id) {
|
||||||
|
|
|
@ -71,13 +71,13 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) {
|
fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) {
|
||||||
self.tcx.def_map.borrow().get(id).map(|def| {
|
self.tcx.def_map.borrow().get(id).map(|def| {
|
||||||
match def {
|
match def.full_def() {
|
||||||
&def::DefConst(_) => {
|
def::DefConst(_) => {
|
||||||
self.check_def_id(def.def_id())
|
self.check_def_id(def.def_id())
|
||||||
}
|
}
|
||||||
_ if self.ignore_non_const_paths => (),
|
_ if self.ignore_non_const_paths => (),
|
||||||
&def::DefPrimTy(_) => (),
|
def::DefPrimTy(_) => (),
|
||||||
&def::DefVariant(enum_id, variant_id, _) => {
|
def::DefVariant(enum_id, variant_id, _) => {
|
||||||
self.check_def_id(enum_id);
|
self.check_def_id(enum_id);
|
||||||
self.check_def_id(variant_id);
|
self.check_def_id(variant_id);
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
fn handle_field_pattern_match(&mut self, lhs: &ast::Pat,
|
fn handle_field_pattern_match(&mut self, lhs: &ast::Pat,
|
||||||
pats: &[codemap::Spanned<ast::FieldPat>]) {
|
pats: &[codemap::Spanned<ast::FieldPat>]) {
|
||||||
let id = match (*self.tcx.def_map.borrow())[lhs.id] {
|
let id = match self.tcx.def_map.borrow()[lhs.id].full_def() {
|
||||||
def::DefVariant(_, id, _) => id,
|
def::DefVariant(_, id, _) => id,
|
||||||
_ => {
|
_ => {
|
||||||
match ty::ty_to_def_id(ty::node_id_to_type(self.tcx,
|
match ty::ty_to_def_id(ty::node_id_to_type(self.tcx,
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
pub use self::Def::*;
|
pub use self::Def::*;
|
||||||
pub use self::MethodProvenance::*;
|
pub use self::MethodProvenance::*;
|
||||||
|
|
||||||
|
use middle::privacy::LastPrivate;
|
||||||
use middle::subst::ParamSpace;
|
use middle::subst::ParamSpace;
|
||||||
use util::nodemap::NodeMap;
|
use util::nodemap::NodeMap;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
@ -51,24 +52,43 @@ pub enum Def {
|
||||||
DefMethod(ast::DefId /* method */, MethodProvenance),
|
DefMethod(ast::DefId /* method */, MethodProvenance),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The result of resolving the prefix of a path to a type:
|
/// The result of resolving a path.
|
||||||
|
/// Before type checking completes, `depth` represents the number of
|
||||||
|
/// trailing segments which are yet unresolved. Afterwards, if there
|
||||||
|
/// were no errors, all paths should be fully resolved, with `depth`
|
||||||
|
/// set to `0` and `base_def` representing the final resolution.
|
||||||
///
|
///
|
||||||
/// module::Type::AssocA::AssocB::AssocC::MethodOrAssocType
|
/// module::Type::AssocX::AssocY::MethodOrAssocType
|
||||||
/// ^~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~
|
/// ^~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/// base_type extra_associated_types
|
/// base_def depth = 3
|
||||||
///
|
///
|
||||||
/// <T as Trait>::AssocA::AssocB::AssocC::MethodOrAssocType
|
/// <T as Trait>::AssocX::AssocY::MethodOrAssocType
|
||||||
/// ^~~~~~~~~~~~~~ ^~~~~~~~~~~~~~
|
/// ^~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/// base_type extra_associated_types
|
/// base_def depth = 2
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
#[derive(Copy, Debug)]
|
||||||
pub struct PartialDef {
|
pub struct PathResolution {
|
||||||
pub base_type: Def,
|
pub base_def: Def,
|
||||||
pub extra_associated_types: u32,
|
pub last_private: LastPrivate,
|
||||||
|
pub depth: usize
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PathResolution {
|
||||||
|
/// Get the definition, if fully resolved, otherwise panic.
|
||||||
|
pub fn full_def(&self) -> Def {
|
||||||
|
if self.depth != 0 {
|
||||||
|
panic!("path not fully resolved: {:?}", self);
|
||||||
|
}
|
||||||
|
self.base_def
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the DefId, if fully resolved, otherwise panic.
|
||||||
|
pub fn def_id(&self) -> ast::DefId {
|
||||||
|
self.full_def().def_id()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Definition mapping
|
// Definition mapping
|
||||||
pub type DefMap = RefCell<NodeMap<Def>>;
|
pub type DefMap = RefCell<NodeMap<PathResolution>>;
|
||||||
pub type PartialDefMap = RefCell<NodeMap<PartialDef>>;
|
|
||||||
// This is the replacement export map. It maps a module to all of the exports
|
// This is the replacement export map. It maps a module to all of the exports
|
||||||
// within.
|
// within.
|
||||||
pub type ExportMap = NodeMap<Vec<Export>>;
|
pub type ExportMap = NodeMap<Vec<Export>>;
|
||||||
|
@ -119,7 +139,7 @@ impl Def {
|
||||||
local_def(id)
|
local_def(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
DefPrimTy(_) => panic!()
|
DefPrimTy(_) => panic!("attempted .def_id() on DefPrimTy")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1017,7 +1017,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
|
||||||
|
|
||||||
// Each match binding is effectively an assignment to the
|
// Each match binding is effectively an assignment to the
|
||||||
// binding being produced.
|
// binding being produced.
|
||||||
let def = def_map.borrow()[pat.id].clone();
|
let def = def_map.borrow()[pat.id].full_def();
|
||||||
match mc.cat_def(pat.id, pat.span, pat_ty, def) {
|
match mc.cat_def(pat.id, pat.span, pat_ty, def) {
|
||||||
Ok(binding_cmt) => {
|
Ok(binding_cmt) => {
|
||||||
delegate.mutate(pat.id, pat.span, binding_cmt, Init);
|
delegate.mutate(pat.id, pat.span, binding_cmt, Init);
|
||||||
|
@ -1097,13 +1097,13 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
|
||||||
|
|
||||||
match pat.node {
|
match pat.node {
|
||||||
ast::PatEnum(_, _) | ast::PatIdent(_, _, None) | ast::PatStruct(..) => {
|
ast::PatEnum(_, _) | ast::PatIdent(_, _, None) | ast::PatStruct(..) => {
|
||||||
match def_map.get(&pat.id) {
|
match def_map.get(&pat.id).map(|d| d.full_def()) {
|
||||||
None => {
|
None => {
|
||||||
// no definition found: pat is not a
|
// no definition found: pat is not a
|
||||||
// struct or enum pattern.
|
// struct or enum pattern.
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(&def::DefVariant(enum_did, variant_did, _is_struct)) => {
|
Some(def::DefVariant(enum_did, variant_did, _is_struct)) => {
|
||||||
let downcast_cmt =
|
let downcast_cmt =
|
||||||
if ty::enum_is_univariant(tcx, enum_did) {
|
if ty::enum_is_univariant(tcx, enum_did) {
|
||||||
cmt_pat
|
cmt_pat
|
||||||
|
@ -1119,7 +1119,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
|
||||||
delegate.matched_pat(pat, downcast_cmt, match_mode);
|
delegate.matched_pat(pat, downcast_cmt, match_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(&def::DefStruct(..)) | Some(&def::DefTy(_, false)) => {
|
Some(def::DefStruct(..)) | Some(def::DefTy(_, false)) => {
|
||||||
// A struct (in either the value or type
|
// A struct (in either the value or type
|
||||||
// namespace; we encounter the former on
|
// namespace; we encounter the former on
|
||||||
// e.g. patterns for unit structs).
|
// e.g. patterns for unit structs).
|
||||||
|
@ -1131,14 +1131,14 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
|
||||||
delegate.matched_pat(pat, cmt_pat, match_mode);
|
delegate.matched_pat(pat, cmt_pat, match_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(&def::DefConst(..)) |
|
Some(def::DefConst(..)) |
|
||||||
Some(&def::DefLocal(..)) => {
|
Some(def::DefLocal(..)) => {
|
||||||
// This is a leaf (i.e. identifier binding
|
// This is a leaf (i.e. identifier binding
|
||||||
// or constant value to match); thus no
|
// or constant value to match); thus no
|
||||||
// `matched_pat` call.
|
// `matched_pat` call.
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(def @ &def::DefTy(_, true)) => {
|
Some(def @ def::DefTy(_, true)) => {
|
||||||
// An enum's type -- should never be in a
|
// An enum's type -- should never be in a
|
||||||
// pattern.
|
// pattern.
|
||||||
|
|
||||||
|
|
|
@ -1242,7 +1242,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
||||||
"unbound path {}",
|
"unbound path {}",
|
||||||
pprust::path_to_string(path)))
|
pprust::path_to_string(path)))
|
||||||
}
|
}
|
||||||
Some(&d) => d
|
Some(d) => d.full_def()
|
||||||
};
|
};
|
||||||
match a_def {
|
match a_def {
|
||||||
def::DefTy(did, _) | def::DefStruct(did) => {
|
def::DefTy(did, _) | def::DefStruct(did) => {
|
||||||
|
|
|
@ -446,7 +446,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
|
||||||
match expr.node {
|
match expr.node {
|
||||||
// live nodes required for uses or definitions of variables:
|
// live nodes required for uses or definitions of variables:
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
||||||
let def = ir.tcx.def_map.borrow()[expr.id].clone();
|
let def = ir.tcx.def_map.borrow()[expr.id].full_def();
|
||||||
debug!("expr {}: path that leads to {:?}", expr.id, def);
|
debug!("expr {}: path that leads to {:?}", expr.id, def);
|
||||||
if let DefLocal(..) = def {
|
if let DefLocal(..) = def {
|
||||||
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
||||||
|
@ -705,8 +705,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
// Refers to a labeled loop. Use the results of resolve
|
// Refers to a labeled loop. Use the results of resolve
|
||||||
// to find with one
|
// to find with one
|
||||||
match self.ir.tcx.def_map.borrow().get(&id) {
|
match self.ir.tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
|
||||||
Some(&DefLabel(loop_id)) => loop_id,
|
Some(DefLabel(loop_id)) => loop_id,
|
||||||
_ => self.ir.tcx.sess.span_bug(sp, "label on break/loop \
|
_ => self.ir.tcx.sess.span_bug(sp, "label on break/loop \
|
||||||
doesn't refer to a loop")
|
doesn't refer to a loop")
|
||||||
}
|
}
|
||||||
|
@ -1300,7 +1300,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
|
|
||||||
fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
|
fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
|
||||||
-> LiveNode {
|
-> LiveNode {
|
||||||
match self.ir.tcx.def_map.borrow()[expr.id].clone() {
|
match self.ir.tcx.def_map.borrow()[expr.id].full_def() {
|
||||||
DefLocal(nid) => {
|
DefLocal(nid) => {
|
||||||
let ln = self.live_node(expr.id, expr.span);
|
let ln = self.live_node(expr.id, expr.span);
|
||||||
if acc != 0 {
|
if acc != 0 {
|
||||||
|
@ -1562,7 +1562,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
fn check_lvalue(&mut self, expr: &Expr) {
|
fn check_lvalue(&mut self, expr: &Expr) {
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
||||||
if let DefLocal(nid) = self.ir.tcx.def_map.borrow()[expr.id].clone() {
|
if let DefLocal(nid) = self.ir.tcx.def_map.borrow()[expr.id].full_def() {
|
||||||
// Assignment to an immutable variable or argument: only legal
|
// Assignment to an immutable variable or argument: only legal
|
||||||
// if there is no later assignment. If this local is actually
|
// if there is no later assignment. If this local is actually
|
||||||
// mutable, then check for a reassignment to flag the mutability
|
// mutable, then check for a reassignment to flag the mutability
|
||||||
|
|
|
@ -530,7 +530,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
||||||
let def = (*self.tcx().def_map.borrow())[expr.id];
|
let def = self.tcx().def_map.borrow()[expr.id].full_def();
|
||||||
self.cat_def(expr.id, expr.span, expr_ty, def)
|
self.cat_def(expr.id, expr.span, expr_ty, def)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1199,14 +1199,13 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||||
|
|
||||||
(*op)(self, cmt.clone(), pat);
|
(*op)(self, cmt.clone(), pat);
|
||||||
|
|
||||||
let def_map = self.tcx().def_map.borrow();
|
let opt_def = self.tcx().def_map.borrow().get(&pat.id).map(|d| d.full_def());
|
||||||
let opt_def = def_map.get(&pat.id);
|
|
||||||
|
|
||||||
// Note: This goes up here (rather than within the PatEnum arm
|
// Note: This goes up here (rather than within the PatEnum arm
|
||||||
// alone) because struct patterns can refer to struct types or
|
// alone) because struct patterns can refer to struct types or
|
||||||
// to struct variants within enums.
|
// to struct variants within enums.
|
||||||
let cmt = match opt_def {
|
let cmt = match opt_def {
|
||||||
Some(&def::DefVariant(enum_did, variant_did, _))
|
Some(def::DefVariant(enum_did, variant_did, _))
|
||||||
// univariant enums do not need downcasts
|
// univariant enums do not need downcasts
|
||||||
if !ty::enum_is_univariant(self.tcx(), enum_did) => {
|
if !ty::enum_is_univariant(self.tcx(), enum_did) => {
|
||||||
self.cat_downcast(pat, cmt.clone(), cmt.ty, variant_did)
|
self.cat_downcast(pat, cmt.clone(), cmt.ty, variant_did)
|
||||||
|
@ -1224,7 +1223,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||||
}
|
}
|
||||||
ast::PatEnum(_, Some(ref subpats)) => {
|
ast::PatEnum(_, Some(ref subpats)) => {
|
||||||
match opt_def {
|
match opt_def {
|
||||||
Some(&def::DefVariant(..)) => {
|
Some(def::DefVariant(..)) => {
|
||||||
// variant(x, y, z)
|
// variant(x, y, z)
|
||||||
for (i, subpat) in subpats.iter().enumerate() {
|
for (i, subpat) in subpats.iter().enumerate() {
|
||||||
let subpat_ty = try!(self.pat_ty(&**subpat)); // see (*2)
|
let subpat_ty = try!(self.pat_ty(&**subpat)); // see (*2)
|
||||||
|
@ -1237,7 +1236,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||||
try!(self.cat_pattern_(subcmt, &**subpat, op));
|
try!(self.cat_pattern_(subcmt, &**subpat, op));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(&def::DefStruct(..)) => {
|
Some(def::DefStruct(..)) => {
|
||||||
for (i, subpat) in subpats.iter().enumerate() {
|
for (i, subpat) in subpats.iter().enumerate() {
|
||||||
let subpat_ty = try!(self.pat_ty(&**subpat)); // see (*2)
|
let subpat_ty = try!(self.pat_ty(&**subpat)); // see (*2)
|
||||||
let cmt_field =
|
let cmt_field =
|
||||||
|
@ -1247,7 +1246,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||||
try!(self.cat_pattern_(cmt_field, &**subpat, op));
|
try!(self.cat_pattern_(cmt_field, &**subpat, op));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(&def::DefConst(..)) => {
|
Some(def::DefConst(..)) => {
|
||||||
for subpat in subpats {
|
for subpat in subpats {
|
||||||
try!(self.cat_pattern_(cmt.clone(), &**subpat, op));
|
try!(self.cat_pattern_(cmt.clone(), &**subpat, op));
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,8 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &ast::Pat) -> bool {
|
||||||
ast::PatEnum(_, _) |
|
ast::PatEnum(_, _) |
|
||||||
ast::PatIdent(_, _, None) |
|
ast::PatIdent(_, _, None) |
|
||||||
ast::PatStruct(..) => {
|
ast::PatStruct(..) => {
|
||||||
match dm.borrow().get(&pat.id) {
|
match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
|
||||||
Some(&DefVariant(..)) => true,
|
Some(DefVariant(..)) => true,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,8 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &ast::Pat) -> bool {
|
||||||
ast::PatEnum(_, _) |
|
ast::PatEnum(_, _) |
|
||||||
ast::PatIdent(_, _, None) |
|
ast::PatIdent(_, _, None) |
|
||||||
ast::PatStruct(..) => {
|
ast::PatStruct(..) => {
|
||||||
match dm.borrow().get(&pat.id) {
|
match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
|
||||||
Some(&DefVariant(..)) | Some(&DefStruct(..)) => true,
|
Some(DefVariant(..)) | Some(DefStruct(..)) => true,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,8 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &ast::Pat) -> bool {
|
||||||
pub fn pat_is_const(dm: &DefMap, pat: &ast::Pat) -> bool {
|
pub fn pat_is_const(dm: &DefMap, pat: &ast::Pat) -> bool {
|
||||||
match pat.node {
|
match pat.node {
|
||||||
ast::PatIdent(_, _, None) | ast::PatEnum(..) => {
|
ast::PatIdent(_, _, None) | ast::PatEnum(..) => {
|
||||||
match dm.borrow().get(&pat.id) {
|
match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
|
||||||
Some(&DefConst(..)) => true,
|
Some(DefConst(..)) => true,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub use self::PrivateDep::*;
|
||||||
pub use self::ImportUse::*;
|
pub use self::ImportUse::*;
|
||||||
pub use self::LastPrivate::*;
|
pub use self::LastPrivate::*;
|
||||||
|
|
||||||
use util::nodemap::{DefIdSet, NodeMap, NodeSet};
|
use util::nodemap::{DefIdSet, NodeSet};
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
|
||||||
|
@ -32,9 +32,6 @@ pub type ExternalExports = DefIdSet;
|
||||||
/// reexporting a public struct doesn't inline the doc).
|
/// reexporting a public struct doesn't inline the doc).
|
||||||
pub type PublicItems = NodeSet;
|
pub type PublicItems = NodeSet;
|
||||||
|
|
||||||
// FIXME: dox
|
|
||||||
pub type LastPrivateMap = NodeMap<LastPrivate>;
|
|
||||||
|
|
||||||
#[derive(Copy, Debug)]
|
#[derive(Copy, Debug)]
|
||||||
pub enum LastPrivate {
|
pub enum LastPrivate {
|
||||||
LastMod(PrivateDep),
|
LastMod(PrivateDep),
|
||||||
|
|
|
@ -96,7 +96,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
||||||
let def = match self.tcx.def_map.borrow().get(&expr.id) {
|
let def = match self.tcx.def_map.borrow().get(&expr.id) {
|
||||||
Some(&def) => def,
|
Some(d) => d.full_def(),
|
||||||
None => {
|
None => {
|
||||||
self.tcx.sess.span_bug(expr.span,
|
self.tcx.sess.span_bug(expr.span,
|
||||||
"def ID not in def map?!")
|
"def ID not in def map?!")
|
||||||
|
|
|
@ -168,8 +168,8 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
||||||
ast::TyPath(ref path) => {
|
ast::TyPath(ref path) => {
|
||||||
// if this path references a trait, then this will resolve to
|
// if this path references a trait, then this will resolve to
|
||||||
// a trait ref, which introduces a binding scope.
|
// a trait ref, which introduces a binding scope.
|
||||||
match self.def_map.borrow().get(&ty.id) {
|
match self.def_map.borrow().get(&ty.id).map(|d| (d.base_def, d.depth)) {
|
||||||
Some(&def::DefTrait(..)) => {
|
Some((def::DefTrait(..), 0)) => {
|
||||||
self.with(LateScope(&Vec::new(), self.scope), |_, this| {
|
self.with(LateScope(&Vec::new(), self.scope), |_, this| {
|
||||||
this.visit_path(path, ty.id);
|
this.visit_path(path, ty.id);
|
||||||
});
|
});
|
||||||
|
|
|
@ -393,12 +393,14 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
|
||||||
|
|
||||||
pub fn check_path(tcx: &ty::ctxt, path: &ast::Path, id: ast::NodeId,
|
pub fn check_path(tcx: &ty::ctxt, path: &ast::Path, id: ast::NodeId,
|
||||||
cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) {
|
cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) {
|
||||||
let did = match tcx.def_map.borrow().get(&id) {
|
match tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
|
||||||
Some(&def::DefPrimTy(..)) => return,
|
Some(def::DefPrimTy(..)) => {}
|
||||||
Some(def) => def.def_id(),
|
Some(def) => {
|
||||||
None => return
|
maybe_do_stability_check(tcx, def.def_id(), path.span, cb);
|
||||||
};
|
}
|
||||||
maybe_do_stability_check(tcx, did, path.span, cb)
|
None => {}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_do_stability_check(tcx: &ty::ctxt, id: ast::DefId, span: Span,
|
fn maybe_do_stability_check(tcx: &ty::ctxt, id: ast::DefId, span: Span,
|
||||||
|
|
|
@ -46,12 +46,11 @@ use metadata::csearch;
|
||||||
use middle;
|
use middle;
|
||||||
use middle::check_const;
|
use middle::check_const;
|
||||||
use middle::const_eval;
|
use middle::const_eval;
|
||||||
use middle::def::{self, DefMap, ExportMap, PartialDefMap};
|
use middle::def::{self, DefMap, ExportMap};
|
||||||
use middle::dependency_format;
|
use middle::dependency_format;
|
||||||
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem};
|
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem};
|
||||||
use middle::lang_items::{FnOnceTraitLangItem, TyDescStructLangItem};
|
use middle::lang_items::{FnOnceTraitLangItem, TyDescStructLangItem};
|
||||||
use middle::mem_categorization as mc;
|
use middle::mem_categorization as mc;
|
||||||
use middle::privacy::LastPrivateMap;
|
|
||||||
use middle::region;
|
use middle::region;
|
||||||
use middle::resolve_lifetime;
|
use middle::resolve_lifetime;
|
||||||
use middle::infer;
|
use middle::infer;
|
||||||
|
@ -683,8 +682,6 @@ pub struct ctxt<'tcx> {
|
||||||
|
|
||||||
pub sess: Session,
|
pub sess: Session,
|
||||||
pub def_map: DefMap,
|
pub def_map: DefMap,
|
||||||
pub partial_def_map: PartialDefMap,
|
|
||||||
pub last_private_map: RefCell<LastPrivateMap>,
|
|
||||||
|
|
||||||
pub named_region_map: resolve_lifetime::NamedRegionMap,
|
pub named_region_map: resolve_lifetime::NamedRegionMap,
|
||||||
|
|
||||||
|
@ -2427,8 +2424,6 @@ impl<'tcx> CommonTypes<'tcx> {
|
||||||
pub fn mk_ctxt<'tcx>(s: Session,
|
pub fn mk_ctxt<'tcx>(s: Session,
|
||||||
arenas: &'tcx CtxtArenas<'tcx>,
|
arenas: &'tcx CtxtArenas<'tcx>,
|
||||||
def_map: DefMap,
|
def_map: DefMap,
|
||||||
partial_def_map: PartialDefMap,
|
|
||||||
last_private_map: LastPrivateMap,
|
|
||||||
named_region_map: resolve_lifetime::NamedRegionMap,
|
named_region_map: resolve_lifetime::NamedRegionMap,
|
||||||
map: ast_map::Map<'tcx>,
|
map: ast_map::Map<'tcx>,
|
||||||
freevars: RefCell<FreevarMap>,
|
freevars: RefCell<FreevarMap>,
|
||||||
|
@ -2451,8 +2446,6 @@ pub fn mk_ctxt<'tcx>(s: Session,
|
||||||
variance_computed: Cell::new(false),
|
variance_computed: Cell::new(false),
|
||||||
sess: s,
|
sess: s,
|
||||||
def_map: def_map,
|
def_map: def_map,
|
||||||
partial_def_map: partial_def_map,
|
|
||||||
last_private_map: RefCell::new(last_private_map),
|
|
||||||
region_maps: region_maps,
|
region_maps: region_maps,
|
||||||
node_types: RefCell::new(FnvHashMap()),
|
node_types: RefCell::new(FnvHashMap()),
|
||||||
item_substs: RefCell::new(NodeMap()),
|
item_substs: RefCell::new(NodeMap()),
|
||||||
|
@ -4509,7 +4502,7 @@ pub fn unsize_ty<'tcx>(cx: &ctxt<'tcx>,
|
||||||
|
|
||||||
pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def {
|
pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def {
|
||||||
match tcx.def_map.borrow().get(&expr.id) {
|
match tcx.def_map.borrow().get(&expr.id) {
|
||||||
Some(&def) => def,
|
Some(def) => def.full_def(),
|
||||||
None => {
|
None => {
|
||||||
tcx.sess.span_bug(expr.span, &format!(
|
tcx.sess.span_bug(expr.span, &format!(
|
||||||
"no def-map entry for expr {}", expr.id));
|
"no def-map entry for expr {}", expr.id));
|
||||||
|
@ -4692,11 +4685,10 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
|
||||||
|
|
||||||
ast::ExprBox(Some(ref place), _) => {
|
ast::ExprBox(Some(ref place), _) => {
|
||||||
// Special case `Box<T>` for now:
|
// Special case `Box<T>` for now:
|
||||||
let definition = match tcx.def_map.borrow().get(&place.id) {
|
let def_id = match tcx.def_map.borrow().get(&place.id) {
|
||||||
Some(&def) => def,
|
Some(def) => def.def_id(),
|
||||||
None => panic!("no def for place"),
|
None => panic!("no def for place"),
|
||||||
};
|
};
|
||||||
let def_id = definition.def_id();
|
|
||||||
if tcx.lang_items.exchange_heap() == Some(def_id) {
|
if tcx.lang_items.exchange_heap() == Some(def_id) {
|
||||||
RvalueDatumExpr
|
RvalueDatumExpr
|
||||||
} else {
|
} else {
|
||||||
|
@ -5144,10 +5136,7 @@ pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trait_ref_to_def_id(tcx: &ctxt, tr: &ast::TraitRef) -> ast::DefId {
|
pub fn trait_ref_to_def_id(tcx: &ctxt, tr: &ast::TraitRef) -> ast::DefId {
|
||||||
let def = *tcx.def_map.borrow()
|
tcx.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id()
|
||||||
.get(&tr.ref_id)
|
|
||||||
.expect("no def-map entry for trait");
|
|
||||||
def.def_id()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_add_builtin_trait(
|
pub fn try_add_builtin_trait(
|
||||||
|
|
|
@ -567,12 +567,10 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
|
||||||
|
|
||||||
let resolve::CrateMap {
|
let resolve::CrateMap {
|
||||||
def_map,
|
def_map,
|
||||||
partial_def_map,
|
|
||||||
freevars,
|
freevars,
|
||||||
export_map,
|
export_map,
|
||||||
trait_map,
|
trait_map,
|
||||||
external_exports,
|
external_exports,
|
||||||
last_private_map,
|
|
||||||
glob_map,
|
glob_map,
|
||||||
} =
|
} =
|
||||||
time(time_passes, "resolution", (),
|
time(time_passes, "resolution", (),
|
||||||
|
@ -608,8 +606,6 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
|
||||||
let ty_cx = ty::mk_ctxt(sess,
|
let ty_cx = ty::mk_ctxt(sess,
|
||||||
arenas,
|
arenas,
|
||||||
def_map,
|
def_map,
|
||||||
partial_def_map,
|
|
||||||
last_private_map,
|
|
||||||
named_region_map,
|
named_region_map,
|
||||||
ast_map,
|
ast_map,
|
||||||
freevars,
|
freevars,
|
||||||
|
|
|
@ -259,7 +259,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
||||||
ast::ItemImpl(_, _, _, _, ref ty, ref impl_items) => {
|
ast::ItemImpl(_, _, _, _, ref ty, ref impl_items) => {
|
||||||
let public_ty = match ty.node {
|
let public_ty = match ty.node {
|
||||||
ast::TyPath(_) => {
|
ast::TyPath(_) => {
|
||||||
match self.tcx.def_map.borrow()[ty.id].clone() {
|
match self.tcx.def_map.borrow()[ty.id].full_def() {
|
||||||
def::DefPrimTy(..) => true,
|
def::DefPrimTy(..) => true,
|
||||||
def => {
|
def => {
|
||||||
let did = def.def_id();
|
let did = def.def_id();
|
||||||
|
@ -326,7 +326,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
ast::ItemTy(ref ty, _) if public_first => {
|
ast::ItemTy(ref ty, _) if public_first => {
|
||||||
if let ast::TyPath(_) = ty.node {
|
if let ast::TyPath(_) = ty.node {
|
||||||
match self.tcx.def_map.borrow()[ty.id].clone() {
|
match self.tcx.def_map.borrow()[ty.id].full_def() {
|
||||||
def::DefPrimTy(..) | def::DefTyParam(..) => {},
|
def::DefPrimTy(..) | def::DefTyParam(..) => {},
|
||||||
def => {
|
def => {
|
||||||
let did = def.def_id();
|
let did = def.def_id();
|
||||||
|
@ -630,7 +630,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
||||||
ast::TyPath(_) => {}
|
ast::TyPath(_) => {}
|
||||||
_ => return Some((err_span, err_msg, None)),
|
_ => return Some((err_span, err_msg, None)),
|
||||||
};
|
};
|
||||||
let def = self.tcx.def_map.borrow()[ty.id].clone();
|
let def = self.tcx.def_map.borrow()[ty.id].full_def();
|
||||||
let did = def.def_id();
|
let did = def.def_id();
|
||||||
assert!(is_local(did));
|
assert!(is_local(did));
|
||||||
match self.tcx.map.get(did.node) {
|
match self.tcx.map.get(did.node) {
|
||||||
|
@ -716,19 +716,19 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
||||||
// Checks that a path is in scope.
|
// Checks that a path is in scope.
|
||||||
fn check_path(&mut self, span: Span, path_id: ast::NodeId, last: ast::Ident) {
|
fn check_path(&mut self, span: Span, path_id: ast::NodeId, last: ast::Ident) {
|
||||||
debug!("privacy - path {}", self.nodestr(path_id));
|
debug!("privacy - path {}", self.nodestr(path_id));
|
||||||
let orig_def = self.tcx.def_map.borrow()[path_id].clone();
|
let path_res = self.tcx.def_map.borrow()[path_id];
|
||||||
let ck = |tyname: &str| {
|
let ck = |tyname: &str| {
|
||||||
let ck_public = |def: ast::DefId| {
|
let ck_public = |def: ast::DefId| {
|
||||||
debug!("privacy - ck_public {:?}", def);
|
debug!("privacy - ck_public {:?}", def);
|
||||||
let name = token::get_ident(last);
|
let name = token::get_ident(last);
|
||||||
let origdid = orig_def.def_id();
|
let origdid = path_res.def_id();
|
||||||
self.ensure_public(span,
|
self.ensure_public(span,
|
||||||
def,
|
def,
|
||||||
Some(origdid),
|
Some(origdid),
|
||||||
&format!("{} `{}`", tyname, name))
|
&format!("{} `{}`", tyname, name))
|
||||||
};
|
};
|
||||||
|
|
||||||
match self.tcx.last_private_map.borrow()[path_id] {
|
match path_res.last_private {
|
||||||
LastMod(AllPublic) => {},
|
LastMod(AllPublic) => {},
|
||||||
LastMod(DependsOn(def)) => {
|
LastMod(DependsOn(def)) => {
|
||||||
self.report_error(ck_public(def));
|
self.report_error(ck_public(def));
|
||||||
|
@ -792,7 +792,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
||||||
// def map is not. Therefore the names we work out below will not always
|
// def map is not. Therefore the names we work out below will not always
|
||||||
// be accurate and we can get slightly wonky error messages (but type
|
// be accurate and we can get slightly wonky error messages (but type
|
||||||
// checking is always correct).
|
// checking is always correct).
|
||||||
match self.tcx.def_map.borrow()[path_id].clone() {
|
match path_res.full_def() {
|
||||||
def::DefFn(..) => ck("function"),
|
def::DefFn(..) => ck("function"),
|
||||||
def::DefStatic(..) => ck("static"),
|
def::DefStatic(..) => ck("static"),
|
||||||
def::DefConst(..) => ck("const"),
|
def::DefConst(..) => ck("const"),
|
||||||
|
@ -889,7 +889,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::ty_enum(_, _) => {
|
ty::ty_enum(_, _) => {
|
||||||
match self.tcx.def_map.borrow()[expr.id].clone() {
|
match self.tcx.def_map.borrow()[expr.id].full_def() {
|
||||||
def::DefVariant(_, variant_id, _) => {
|
def::DefVariant(_, variant_id, _) => {
|
||||||
for field in fields {
|
for field in fields {
|
||||||
self.check_field(expr.span, variant_id,
|
self.check_field(expr.span, variant_id,
|
||||||
|
@ -922,8 +922,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
||||||
with private fields");
|
with private fields");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match self.tcx.def_map.borrow().get(&expr.id) {
|
match self.tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()) {
|
||||||
Some(&def::DefStruct(did)) => {
|
Some(def::DefStruct(did)) => {
|
||||||
guard(if is_local(did) {
|
guard(if is_local(did) {
|
||||||
local_def(self.tcx.map.get_parent(did.node))
|
local_def(self.tcx.map.get_parent(did.node))
|
||||||
} else {
|
} else {
|
||||||
|
@ -962,8 +962,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::ty_enum(_, _) => {
|
ty::ty_enum(_, _) => {
|
||||||
match self.tcx.def_map.borrow().get(&pattern.id) {
|
match self.tcx.def_map.borrow().get(&pattern.id).map(|d| d.full_def()) {
|
||||||
Some(&def::DefVariant(_, variant_id, _)) => {
|
Some(def::DefVariant(_, variant_id, _)) => {
|
||||||
for field in fields {
|
for field in fields {
|
||||||
self.check_field(pattern.span, variant_id,
|
self.check_field(pattern.span, variant_id,
|
||||||
NamedField(field.node.ident.name));
|
NamedField(field.node.ident.name));
|
||||||
|
@ -1214,7 +1214,7 @@ struct CheckTypeForPrivatenessVisitor<'a, 'b: 'a, 'tcx: 'b> {
|
||||||
|
|
||||||
impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
|
impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||||
fn path_is_private_type(&self, path_id: ast::NodeId) -> bool {
|
fn path_is_private_type(&self, path_id: ast::NodeId) -> bool {
|
||||||
let did = match self.tcx.def_map.borrow().get(&path_id).cloned() {
|
let did = match self.tcx.def_map.borrow().get(&path_id).map(|d| d.full_def()) {
|
||||||
// `int` etc. (None doesn't seem to occur.)
|
// `int` etc. (None doesn't seem to occur.)
|
||||||
None | Some(def::DefPrimTy(..)) => return false,
|
None | Some(def::DefPrimTy(..)) => return false,
|
||||||
Some(def) => def.def_id()
|
Some(def) => def.def_id()
|
||||||
|
|
|
@ -68,17 +68,17 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
|
||||||
"unused import".to_string());
|
"unused import".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
let (v_priv, t_priv) = match self.last_private.get(&id) {
|
let mut def_map = self.def_map.borrow_mut();
|
||||||
Some(&LastImport {
|
let path_res = if let Some(r) = def_map.get_mut(&id) {
|
||||||
value_priv: v,
|
r
|
||||||
value_used: _,
|
} else {
|
||||||
type_priv: t,
|
return;
|
||||||
type_used: _
|
};
|
||||||
}) => (v, t),
|
let (v_priv, t_priv) = match path_res.last_private {
|
||||||
Some(_) => {
|
LastImport { value_priv, type_priv, .. } => (value_priv, type_priv),
|
||||||
|
_ => {
|
||||||
panic!("we should only have LastImport for `use` directives")
|
panic!("we should only have LastImport for `use` directives")
|
||||||
}
|
}
|
||||||
_ => return,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
|
let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
|
||||||
|
@ -100,10 +100,12 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
self.last_private.insert(id, LastImport{value_priv: v_priv,
|
path_res.last_private = LastImport {
|
||||||
value_used: v_used,
|
value_priv: v_priv,
|
||||||
type_priv: t_priv,
|
value_used: v_used,
|
||||||
type_used: t_used});
|
type_priv: t_priv,
|
||||||
|
type_used: t_used
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -934,13 +934,11 @@ struct Resolver<'a, 'tcx:'a> {
|
||||||
primitive_type_table: PrimitiveTypeTable,
|
primitive_type_table: PrimitiveTypeTable,
|
||||||
|
|
||||||
def_map: DefMap,
|
def_map: DefMap,
|
||||||
partial_def_map: PartialDefMap,
|
|
||||||
freevars: RefCell<FreevarMap>,
|
freevars: RefCell<FreevarMap>,
|
||||||
freevars_seen: RefCell<NodeMap<NodeSet>>,
|
freevars_seen: RefCell<NodeMap<NodeSet>>,
|
||||||
export_map: ExportMap,
|
export_map: ExportMap,
|
||||||
trait_map: TraitMap,
|
trait_map: TraitMap,
|
||||||
external_exports: ExternalExports,
|
external_exports: ExternalExports,
|
||||||
last_private: LastPrivateMap,
|
|
||||||
|
|
||||||
// Whether or not to print error messages. Can be set to true
|
// Whether or not to print error messages. Can be set to true
|
||||||
// when getting additional info for error message suggestions,
|
// when getting additional info for error message suggestions,
|
||||||
|
@ -1008,7 +1006,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
primitive_type_table: PrimitiveTypeTable::new(),
|
primitive_type_table: PrimitiveTypeTable::new(),
|
||||||
|
|
||||||
def_map: RefCell::new(NodeMap()),
|
def_map: RefCell::new(NodeMap()),
|
||||||
partial_def_map: RefCell::new(NodeMap()),
|
|
||||||
freevars: RefCell::new(NodeMap()),
|
freevars: RefCell::new(NodeMap()),
|
||||||
freevars_seen: RefCell::new(NodeMap()),
|
freevars_seen: RefCell::new(NodeMap()),
|
||||||
export_map: NodeMap(),
|
export_map: NodeMap(),
|
||||||
|
@ -1016,7 +1013,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
used_imports: HashSet::new(),
|
used_imports: HashSet::new(),
|
||||||
used_crates: HashSet::new(),
|
used_crates: HashSet::new(),
|
||||||
external_exports: DefIdSet(),
|
external_exports: DefIdSet(),
|
||||||
last_private: NodeMap(),
|
|
||||||
|
|
||||||
emit_errors: true,
|
emit_errors: true,
|
||||||
make_glob_map: make_glob_map == MakeGlobMap::Yes,
|
make_glob_map: make_glob_map == MakeGlobMap::Yes,
|
||||||
|
@ -1574,31 +1570,36 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
// record what this import resolves to for later uses in documentation,
|
// record what this import resolves to for later uses in documentation,
|
||||||
// this may resolve to either a value or a type, but for documentation
|
// this may resolve to either a value or a type, but for documentation
|
||||||
// purposes it's good enough to just favor one over the other.
|
// purposes it's good enough to just favor one over the other.
|
||||||
let value_private = match import_resolution.value_target {
|
let value_def_and_priv = import_resolution.value_target.as_ref().map(|target| {
|
||||||
Some(ref target) => {
|
let def = target.bindings.def_for_namespace(ValueNS).unwrap();
|
||||||
let def = target.bindings.def_for_namespace(ValueNS).unwrap();
|
(def, if value_used_public { lp } else { DependsOn(def.def_id()) })
|
||||||
self.def_map.borrow_mut().insert(directive.id, def);
|
});
|
||||||
let did = def.def_id();
|
let type_def_and_priv = import_resolution.type_target.as_ref().map(|target| {
|
||||||
if value_used_public {Some(lp)} else {Some(DependsOn(did))}
|
let def = target.bindings.def_for_namespace(TypeNS).unwrap();
|
||||||
},
|
(def, if type_used_public { lp } else { DependsOn(def.def_id()) })
|
||||||
// AllPublic here and below is a dummy value, it should never be used because
|
});
|
||||||
// _exists is false.
|
|
||||||
None => None,
|
let import_lp = LastImport {
|
||||||
};
|
value_priv: value_def_and_priv.map(|(_, p)| p),
|
||||||
let type_private = match import_resolution.type_target {
|
value_used: Used,
|
||||||
Some(ref target) => {
|
type_priv: type_def_and_priv.map(|(_, p)| p),
|
||||||
let def = target.bindings.def_for_namespace(TypeNS).unwrap();
|
type_used: Used
|
||||||
self.def_map.borrow_mut().insert(directive.id, def);
|
|
||||||
let did = def.def_id();
|
|
||||||
if type_used_public {Some(lp)} else {Some(DependsOn(did))}
|
|
||||||
},
|
|
||||||
None => None,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.last_private.insert(directive.id, LastImport{value_priv: value_private,
|
if let Some((def, _)) = value_def_and_priv {
|
||||||
value_used: Used,
|
self.def_map.borrow_mut().insert(directive.id, PathResolution {
|
||||||
type_priv: type_private,
|
base_def: def,
|
||||||
type_used: Used});
|
last_private: import_lp,
|
||||||
|
depth: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if let Some((def, _)) = type_def_and_priv {
|
||||||
|
self.def_map.borrow_mut().insert(directive.id, PathResolution {
|
||||||
|
base_def: def,
|
||||||
|
last_private: import_lp,
|
||||||
|
depth: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
debug!("(resolving single import) successfully resolved import");
|
debug!("(resolving single import) successfully resolved import");
|
||||||
return Success(());
|
return Success(());
|
||||||
|
@ -1716,12 +1717,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the destination of this import
|
// Record the destination of this import
|
||||||
match containing_module.def_id.get() {
|
if let Some(did) = containing_module.def_id.get() {
|
||||||
Some(did) => {
|
self.def_map.borrow_mut().insert(id, PathResolution {
|
||||||
self.def_map.borrow_mut().insert(id, DefMod(did));
|
base_def: DefMod(did),
|
||||||
self.last_private.insert(id, lp);
|
last_private: lp,
|
||||||
}
|
depth: 0
|
||||||
None => {}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("(resolving glob import) successfully resolved import");
|
debug!("(resolving glob import) successfully resolved import");
|
||||||
|
@ -2846,8 +2847,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
ItemUse(ref view_path) => {
|
ItemUse(ref view_path) => {
|
||||||
// check for imports shadowing primitive types
|
// check for imports shadowing primitive types
|
||||||
if let ast::ViewPathSimple(ident, _) = view_path.node {
|
if let ast::ViewPathSimple(ident, _) = view_path.node {
|
||||||
match self.def_map.borrow().get(&item.id) {
|
match self.def_map.borrow().get(&item.id).map(|d| d.full_def()) {
|
||||||
Some(&DefTy(..)) | Some(&DefStruct(..)) | Some(&DefTrait(..)) | None => {
|
Some(DefTy(..)) | Some(DefStruct(..)) | Some(DefTrait(..)) | None => {
|
||||||
self.check_if_primitive_type_name(ident.name, item.span);
|
self.check_if_primitive_type_name(ident.name, item.span);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -2959,30 +2960,28 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
trait_path: &Path,
|
trait_path: &Path,
|
||||||
path_depth: usize)
|
path_depth: usize)
|
||||||
-> Result<(Def, LastPrivate, usize), ()> {
|
-> Result<PathResolution, ()> {
|
||||||
match self.resolve_path(id, trait_path, path_depth, TypeNS, true) {
|
if let Some(path_res) = self.resolve_path(id, trait_path, path_depth, TypeNS, true) {
|
||||||
Some(def @ (DefTrait(_), _, _)) => {
|
if let DefTrait(_) = path_res.base_def {
|
||||||
debug!("(resolving trait) found trait def: {:?}", def);
|
debug!("(resolving trait) found trait def: {:?}", path_res);
|
||||||
Ok(def)
|
Ok(path_res)
|
||||||
}
|
} else {
|
||||||
Some((def, _, _)) => {
|
|
||||||
self.resolve_error(trait_path.span,
|
self.resolve_error(trait_path.span,
|
||||||
&format!("`{}` is not a trait",
|
&format!("`{}` is not a trait",
|
||||||
self.path_names_to_string(trait_path, path_depth)));
|
self.path_names_to_string(trait_path, path_depth)));
|
||||||
|
|
||||||
// If it's a typedef, give a note
|
// If it's a typedef, give a note
|
||||||
if let DefTy(..) = def {
|
if let DefTy(..) = path_res.base_def {
|
||||||
self.session.span_note(trait_path.span,
|
self.session.span_note(trait_path.span,
|
||||||
"`type` aliases cannot be used for traits");
|
"`type` aliases cannot be used for traits");
|
||||||
}
|
}
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
None => {
|
} else {
|
||||||
let msg = format!("use of undeclared trait name `{}`",
|
let msg = format!("use of undeclared trait name `{}`",
|
||||||
self.path_names_to_string(trait_path, path_depth));
|
self.path_names_to_string(trait_path, path_depth));
|
||||||
self.resolve_error(trait_path.span, &msg[]);
|
self.resolve_error(trait_path.span, &msg[]);
|
||||||
Err(())
|
Err(())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2995,14 +2994,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
&ast::WherePredicate::BoundPredicate(_) |
|
&ast::WherePredicate::BoundPredicate(_) |
|
||||||
&ast::WherePredicate::RegionPredicate(_) => {}
|
&ast::WherePredicate::RegionPredicate(_) => {}
|
||||||
&ast::WherePredicate::EqPredicate(ref eq_pred) => {
|
&ast::WherePredicate::EqPredicate(ref eq_pred) => {
|
||||||
match self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS, true) {
|
let path_res = self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS, true);
|
||||||
Some(def @ (DefTyParam(..), _, _)) => {
|
if let Some(PathResolution { base_def: DefTyParam(..), .. }) = path_res {
|
||||||
self.record_def(eq_pred.id, def);
|
self.record_def(eq_pred.id, path_res.unwrap());
|
||||||
}
|
} else {
|
||||||
_ => {
|
self.resolve_error(eq_pred.path.span, "undeclared associated type");
|
||||||
self.resolve_error(eq_pred.path.span,
|
|
||||||
"undeclared associated type");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3028,9 +3024,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
let mut new_val = None;
|
let mut new_val = None;
|
||||||
if let Some(ref trait_ref) = *opt_trait_ref {
|
if let Some(ref trait_ref) = *opt_trait_ref {
|
||||||
match self.resolve_trait_reference(trait_ref.ref_id, &trait_ref.path, 0) {
|
match self.resolve_trait_reference(trait_ref.ref_id, &trait_ref.path, 0) {
|
||||||
Ok(def) => {
|
Ok(path_res) => {
|
||||||
self.record_def(trait_ref.ref_id, def);
|
self.record_def(trait_ref.ref_id, path_res);
|
||||||
new_val = Some((def.0.def_id(), trait_ref.clone()));
|
new_val = Some((path_res.base_def.def_id(), trait_ref.clone()));
|
||||||
}
|
}
|
||||||
Err(_) => { /* error was already reported */ }
|
Err(_) => { /* error was already reported */ }
|
||||||
}
|
}
|
||||||
|
@ -3259,23 +3255,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
path.segments.len()
|
path.segments.len()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut result = None;
|
let mut resolution = None;
|
||||||
for depth in 0..max_assoc_types {
|
for depth in 0..max_assoc_types {
|
||||||
self.with_no_errors(|this| {
|
self.with_no_errors(|this| {
|
||||||
result = this.resolve_path(ty.id, path, depth, TypeNS, true);
|
resolution = this.resolve_path(ty.id, path, depth, TypeNS, true);
|
||||||
});
|
});
|
||||||
if result.is_some() {
|
if resolution.is_some() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some((DefMod(_), _, _)) = result {
|
if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
|
||||||
// A module is not a valid type.
|
// A module is not a valid type.
|
||||||
result = None;
|
resolution = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a path in the type namespace. Walk through scopes
|
// This is a path in the type namespace. Walk through scopes
|
||||||
// looking for it.
|
// looking for it.
|
||||||
match result {
|
match resolution {
|
||||||
Some(def) => {
|
Some(def) => {
|
||||||
// Write the result into the def map.
|
// Write the result into the def map.
|
||||||
debug!("(resolving type) writing resolution for `{}` \
|
debug!("(resolving type) writing resolution for `{}` \
|
||||||
|
@ -3338,7 +3334,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
pattern,
|
pattern,
|
||||||
binding_mode,
|
binding_mode,
|
||||||
"an enum variant");
|
"an enum variant");
|
||||||
self.record_def(pattern.id, (def, lp, 0));
|
self.record_def(pattern.id, PathResolution {
|
||||||
|
base_def: def,
|
||||||
|
last_private: lp,
|
||||||
|
depth: 0
|
||||||
|
});
|
||||||
}
|
}
|
||||||
FoundStructOrEnumVariant(..) => {
|
FoundStructOrEnumVariant(..) => {
|
||||||
self.resolve_error(
|
self.resolve_error(
|
||||||
|
@ -3357,7 +3357,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
pattern,
|
pattern,
|
||||||
binding_mode,
|
binding_mode,
|
||||||
"a constant");
|
"a constant");
|
||||||
self.record_def(pattern.id, (def, lp, 0));
|
self.record_def(pattern.id, PathResolution {
|
||||||
|
base_def: def,
|
||||||
|
last_private: lp,
|
||||||
|
depth: 0
|
||||||
|
});
|
||||||
}
|
}
|
||||||
FoundConst(..) => {
|
FoundConst(..) => {
|
||||||
self.resolve_error(pattern.span,
|
self.resolve_error(pattern.span,
|
||||||
|
@ -3374,7 +3378,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
// will be able to distinguish variants from
|
// will be able to distinguish variants from
|
||||||
// locals in patterns.
|
// locals in patterns.
|
||||||
|
|
||||||
self.record_def(pattern.id, (def, LastMod(AllPublic), 0));
|
self.record_def(pattern.id, PathResolution {
|
||||||
|
base_def: def,
|
||||||
|
last_private: LastMod(AllPublic),
|
||||||
|
depth: 0
|
||||||
|
});
|
||||||
|
|
||||||
// Add the binding to the local ribs, if it
|
// Add the binding to the local ribs, if it
|
||||||
// doesn't already exist in the bindings list. (We
|
// doesn't already exist in the bindings list. (We
|
||||||
|
@ -3417,29 +3425,28 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
|
|
||||||
PatEnum(ref path, _) => {
|
PatEnum(ref path, _) => {
|
||||||
// This must be an enum variant, struct or const.
|
// This must be an enum variant, struct or const.
|
||||||
match self.resolve_path(pat_id, path, 0, ValueNS, false) {
|
if let Some(path_res) = self.resolve_path(pat_id, path, 0, ValueNS, false) {
|
||||||
Some(def @ (DefVariant(..), _, _)) |
|
match path_res.base_def {
|
||||||
Some(def @ (DefStruct(..), _, _)) |
|
DefVariant(..) | DefStruct(..) | DefConst(..) => {
|
||||||
Some(def @ (DefConst(..), _, _)) => {
|
self.record_def(pattern.id, path_res);
|
||||||
self.record_def(pattern.id, def);
|
}
|
||||||
}
|
DefStatic(..) => {
|
||||||
Some((DefStatic(..), _, _)) => {
|
self.resolve_error(path.span,
|
||||||
self.resolve_error(path.span,
|
"static variables cannot be \
|
||||||
"static variables cannot be \
|
referenced in a pattern, \
|
||||||
referenced in a pattern, \
|
use a `const` instead");
|
||||||
use a `const` instead");
|
}
|
||||||
}
|
_ => {
|
||||||
Some(_) => {
|
self.resolve_error(path.span,
|
||||||
self.resolve_error(path.span,
|
&format!("`{}` is not an enum variant, struct or const",
|
||||||
&format!("`{}` is not an enum variant, struct or const",
|
token::get_ident(
|
||||||
token::get_ident(
|
path.segments.last().unwrap().identifier)));
|
||||||
path.segments.last().unwrap().identifier)));
|
}
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.resolve_error(path.span,
|
|
||||||
&format!("unresolved enum variant, struct or const `{}`",
|
|
||||||
token::get_ident(path.segments.last().unwrap().identifier)));
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
self.resolve_error(path.span,
|
||||||
|
&format!("unresolved enum variant, struct or const `{}`",
|
||||||
|
token::get_ident(path.segments.last().unwrap().identifier)));
|
||||||
}
|
}
|
||||||
visit::walk_path(self, path);
|
visit::walk_path(self, path);
|
||||||
}
|
}
|
||||||
|
@ -3535,18 +3542,26 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
|
|
||||||
/// If `check_ribs` is true, checks the local definitions first; i.e.
|
/// If `check_ribs` is true, checks the local definitions first; i.e.
|
||||||
/// doesn't skip straight to the containing module.
|
/// doesn't skip straight to the containing module.
|
||||||
|
/// Skips `path_depth` trailing segments, which is also reflected in the
|
||||||
|
/// returned value. See `middle::def::PathResolution` for more info.
|
||||||
fn resolve_path(&mut self,
|
fn resolve_path(&mut self,
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
path_depth: usize,
|
path_depth: usize,
|
||||||
namespace: Namespace,
|
namespace: Namespace,
|
||||||
check_ribs: bool) -> Option<(Def, LastPrivate, usize)> {
|
check_ribs: bool) -> Option<PathResolution> {
|
||||||
let span = path.span;
|
let span = path.span;
|
||||||
let segments = &path.segments[..path.segments.len()-path_depth];
|
let segments = &path.segments[..path.segments.len()-path_depth];
|
||||||
|
|
||||||
|
let mk_res = |(def, lp)| PathResolution {
|
||||||
|
base_def: def,
|
||||||
|
last_private: lp,
|
||||||
|
depth: path_depth
|
||||||
|
};
|
||||||
|
|
||||||
if path.global {
|
if path.global {
|
||||||
let def = self.resolve_crate_relative_path(span, segments, namespace);
|
let def = self.resolve_crate_relative_path(span, segments, namespace);
|
||||||
return def.map(|(def, lp)| (def, lp, path_depth));
|
return def.map(mk_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to find a path to an item in a module.
|
// Try to find a path to an item in a module.
|
||||||
|
@ -3568,9 +3583,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
def.map(|(def, lp)| (def, lp, path_depth))
|
def.map(mk_res)
|
||||||
} else {
|
} else {
|
||||||
unqualified_def.map(|(def, lp)| (def, lp, path_depth))
|
unqualified_def.map(mk_res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3957,10 +3972,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
|
|
||||||
if allowed == Everything {
|
if allowed == Everything {
|
||||||
// Look for a field with the same name in the current self_type.
|
// Look for a field with the same name in the current self_type.
|
||||||
match self.def_map.borrow().get(&node_id) {
|
match self.def_map.borrow().get(&node_id).map(|d| d.full_def()) {
|
||||||
Some(&DefTy(did, _))
|
Some(DefTy(did, _)) |
|
||||||
| Some(&DefStruct(did))
|
Some(DefStruct(did)) |
|
||||||
| Some(&DefVariant(_, did, _)) => match self.structs.get(&did) {
|
Some(DefVariant(_, did, _)) => match self.structs.get(&did) {
|
||||||
None => {}
|
None => {}
|
||||||
Some(fields) => {
|
Some(fields) => {
|
||||||
if fields.iter().any(|&field_name| name == field_name) {
|
if fields.iter().any(|&field_name| name == field_name) {
|
||||||
|
@ -4060,27 +4075,27 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
path.segments.len()
|
path.segments.len()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut result = self.with_no_errors(|this| {
|
let mut resolution = self.with_no_errors(|this| {
|
||||||
this.resolve_path(expr.id, path, 0, ValueNS, true)
|
this.resolve_path(expr.id, path, 0, ValueNS, true)
|
||||||
});
|
});
|
||||||
for depth in 1..max_assoc_types {
|
for depth in 1..max_assoc_types {
|
||||||
if result.is_some() {
|
if resolution.is_some() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
self.with_no_errors(|this| {
|
self.with_no_errors(|this| {
|
||||||
result = this.resolve_path(expr.id, path, depth, TypeNS, true);
|
resolution = this.resolve_path(expr.id, path, depth, TypeNS, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some((DefMod(_), _, _)) = result {
|
if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
|
||||||
// A module is not a valid type or value.
|
// A module is not a valid type or value.
|
||||||
result = None;
|
resolution = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a local path in the value namespace. Walk through
|
// This is a local path in the value namespace. Walk through
|
||||||
// scopes looking for it.
|
// scopes looking for it.
|
||||||
match result {
|
if let Some(path_res) = resolution {
|
||||||
// Check if struct variant
|
// Check if struct variant
|
||||||
Some((DefVariant(_, _, true), _, 0)) => {
|
if let DefVariant(_, _, true) = path_res.base_def {
|
||||||
let path_name = self.path_names_to_string(path, 0);
|
let path_name = self.path_names_to_string(path, 0);
|
||||||
self.resolve_error(expr.span,
|
self.resolve_error(expr.span,
|
||||||
&format!("`{}` is a struct variant name, but \
|
&format!("`{}` is a struct variant name, but \
|
||||||
|
@ -4092,95 +4107,93 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
&format!("Did you mean to write: \
|
&format!("Did you mean to write: \
|
||||||
`{} {{ /* fields */ }}`?",
|
`{} {{ /* fields */ }}`?",
|
||||||
path_name));
|
path_name));
|
||||||
}
|
} else {
|
||||||
Some(def) => {
|
|
||||||
// Write the result into the def map.
|
// Write the result into the def map.
|
||||||
debug!("(resolving expr) resolved `{}`",
|
debug!("(resolving expr) resolved `{}`",
|
||||||
self.path_names_to_string(path, 0));
|
self.path_names_to_string(path, 0));
|
||||||
|
|
||||||
// Partial resolutions will need the set of traits in scope,
|
// Partial resolutions will need the set of traits in scope,
|
||||||
// so they can be completed during typeck.
|
// so they can be completed during typeck.
|
||||||
if def.2 != 0 {
|
if path_res.depth != 0 {
|
||||||
let method_name = path.segments.last().unwrap().identifier.name;
|
let method_name = path.segments.last().unwrap().identifier.name;
|
||||||
let traits = self.search_for_traits_containing_method(method_name);
|
let traits = self.search_for_traits_containing_method(method_name);
|
||||||
self.trait_map.insert(expr.id, traits);
|
self.trait_map.insert(expr.id, traits);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.record_def(expr.id, def);
|
self.record_def(expr.id, path_res);
|
||||||
}
|
}
|
||||||
None => {
|
} else {
|
||||||
// Be helpful if the name refers to a struct
|
// Be helpful if the name refers to a struct
|
||||||
// (The pattern matching def_tys where the id is in self.structs
|
// (The pattern matching def_tys where the id is in self.structs
|
||||||
// matches on regular structs while excluding tuple- and enum-like
|
// matches on regular structs while excluding tuple- and enum-like
|
||||||
// structs, which wouldn't result in this error.)
|
// structs, which wouldn't result in this error.)
|
||||||
let path_name = self.path_names_to_string(path, 0);
|
let path_name = self.path_names_to_string(path, 0);
|
||||||
match self.with_no_errors(|this|
|
let type_res = self.with_no_errors(|this| {
|
||||||
this.resolve_path(expr.id, path, 0, TypeNS, false)) {
|
this.resolve_path(expr.id, path, 0, TypeNS, false)
|
||||||
Some((DefTy(struct_id, _), _, 0))
|
});
|
||||||
if self.structs.contains_key(&struct_id) => {
|
match type_res.map(|r| r.base_def) {
|
||||||
self.resolve_error(expr.span,
|
Some(DefTy(struct_id, _))
|
||||||
&format!("`{}` is a structure name, but \
|
if self.structs.contains_key(&struct_id) => {
|
||||||
this expression \
|
self.resolve_error(expr.span,
|
||||||
uses it like a function name",
|
&format!("`{}` is a structure name, but \
|
||||||
path_name));
|
this expression \
|
||||||
|
uses it like a function name",
|
||||||
|
path_name));
|
||||||
|
|
||||||
self.session.span_help(expr.span,
|
self.session.span_help(expr.span,
|
||||||
&format!("Did you mean to write: \
|
&format!("Did you mean to write: \
|
||||||
`{} {{ /* fields */ }}`?",
|
`{} {{ /* fields */ }}`?",
|
||||||
path_name));
|
path_name));
|
||||||
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Keep reporting some errors even if they're ignored above.
|
// Keep reporting some errors even if they're ignored above.
|
||||||
self.resolve_path(expr.id, path, 0, ValueNS, true);
|
self.resolve_path(expr.id, path, 0, ValueNS, true);
|
||||||
|
|
||||||
let mut method_scope = false;
|
let mut method_scope = false;
|
||||||
self.value_ribs.iter().rev().all(|rib| {
|
self.value_ribs.iter().rev().all(|rib| {
|
||||||
method_scope = match rib.kind {
|
method_scope = match rib.kind {
|
||||||
MethodRibKind => true,
|
MethodRibKind => true,
|
||||||
ItemRibKind | ConstantItemRibKind => false,
|
ItemRibKind | ConstantItemRibKind => false,
|
||||||
_ => return true, // Keep advancing
|
_ => return true, // Keep advancing
|
||||||
};
|
};
|
||||||
false // Stop advancing
|
false // Stop advancing
|
||||||
});
|
});
|
||||||
|
|
||||||
if method_scope && &token::get_name(self.self_name)[..]
|
|
||||||
== path_name {
|
|
||||||
self.resolve_error(
|
|
||||||
expr.span,
|
|
||||||
"`self` is not available \
|
|
||||||
in a static method. Maybe a \
|
|
||||||
`self` argument is missing?");
|
|
||||||
} else {
|
|
||||||
let last_name = path.segments.last().unwrap().identifier.name;
|
|
||||||
let mut msg = match self.find_fallback_in_self_type(last_name) {
|
|
||||||
NoSuggestion => {
|
|
||||||
// limit search to 5 to reduce the number
|
|
||||||
// of stupid suggestions
|
|
||||||
self.find_best_match_for_name(&path_name, 5)
|
|
||||||
.map_or("".to_string(),
|
|
||||||
|x| format!("`{}`", x))
|
|
||||||
}
|
|
||||||
Field =>
|
|
||||||
format!("`self.{}`", path_name),
|
|
||||||
Method
|
|
||||||
| TraitItem =>
|
|
||||||
format!("to call `self.{}`", path_name),
|
|
||||||
TraitMethod(path_str)
|
|
||||||
| StaticMethod(path_str) =>
|
|
||||||
format!("to call `{}::{}`", path_str, path_name)
|
|
||||||
};
|
|
||||||
|
|
||||||
if msg.len() > 0 {
|
|
||||||
msg = format!(". Did you mean {}?", msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if method_scope && &token::get_name(self.self_name)[..]
|
||||||
|
== path_name {
|
||||||
self.resolve_error(
|
self.resolve_error(
|
||||||
expr.span,
|
expr.span,
|
||||||
&format!("unresolved name `{}`{}",
|
"`self` is not available \
|
||||||
path_name,
|
in a static method. Maybe a \
|
||||||
msg));
|
`self` argument is missing?");
|
||||||
|
} else {
|
||||||
|
let last_name = path.segments.last().unwrap().identifier.name;
|
||||||
|
let mut msg = match self.find_fallback_in_self_type(last_name) {
|
||||||
|
NoSuggestion => {
|
||||||
|
// limit search to 5 to reduce the number
|
||||||
|
// of stupid suggestions
|
||||||
|
self.find_best_match_for_name(&path_name, 5)
|
||||||
|
.map_or("".to_string(),
|
||||||
|
|x| format!("`{}`", x))
|
||||||
|
}
|
||||||
|
Field => format!("`self.{}`", path_name),
|
||||||
|
Method |
|
||||||
|
TraitItem =>
|
||||||
|
format!("to call `self.{}`", path_name),
|
||||||
|
TraitMethod(path_str) |
|
||||||
|
StaticMethod(path_str) =>
|
||||||
|
format!("to call `{}::{}`", path_str, path_name)
|
||||||
|
};
|
||||||
|
|
||||||
|
if msg.len() > 0 {
|
||||||
|
msg = format!(". Did you mean {}?", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.resolve_error(
|
||||||
|
expr.span,
|
||||||
|
&format!("unresolved name `{}`{}",
|
||||||
|
path_name, msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4231,7 +4244,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
Some(DlDef(def @ DefLabel(_))) => {
|
Some(DlDef(def @ DefLabel(_))) => {
|
||||||
// Since this def is a label, it is never read.
|
// Since this def is a label, it is never read.
|
||||||
self.record_def(expr.id, (def, LastMod(AllPublic), 0))
|
self.record_def(expr.id, PathResolution {
|
||||||
|
base_def: def,
|
||||||
|
last_private: LastMod(AllPublic),
|
||||||
|
depth: 0
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
self.session.span_bug(expr.span,
|
self.session.span_bug(expr.span,
|
||||||
|
@ -4349,33 +4366,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
found_traits
|
found_traits
|
||||||
}
|
}
|
||||||
|
|
||||||
fn record_def(&mut self,
|
fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
|
||||||
node_id: NodeId,
|
debug!("(recording def) recording {:?} for {}", resolution, node_id);
|
||||||
(def, lp, depth): (Def, LastPrivate, usize)) {
|
assert!(match resolution.last_private {LastImport{..} => false, _ => true},
|
||||||
debug!("(recording def) recording {:?} for {}, last private {:?}",
|
|
||||||
def, node_id, lp);
|
|
||||||
assert!(match lp {LastImport{..} => false, _ => true},
|
|
||||||
"Import should only be used for `use` directives");
|
"Import should only be used for `use` directives");
|
||||||
self.last_private.insert(node_id, lp);
|
|
||||||
|
|
||||||
if depth == 0 {
|
if let Some(prev_res) = self.def_map.borrow_mut().insert(node_id, resolution) {
|
||||||
if let Some(prev_def) = self.def_map.borrow_mut().insert(node_id, def) {
|
let span = self.ast_map.opt_span(node_id).unwrap_or(codemap::DUMMY_SP);
|
||||||
let span = self.ast_map.opt_span(node_id).unwrap_or(codemap::DUMMY_SP);
|
self.session.span_bug(span, &format!("path resolved multiple times \
|
||||||
self.session.span_bug(span, &format!("path resolved multiple times \
|
({:?} before, {:?} now)",
|
||||||
({:?} before, {:?} now)",
|
prev_res, resolution));
|
||||||
prev_def, def));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let def = PartialDef {
|
|
||||||
base_type: def,
|
|
||||||
extra_associated_types: (depth - 1) as u32
|
|
||||||
};
|
|
||||||
if let Some(prev_def) = self.partial_def_map.borrow_mut().insert(node_id, def) {
|
|
||||||
let span = self.ast_map.opt_span(node_id).unwrap_or(codemap::DUMMY_SP);
|
|
||||||
self.session.span_bug(span, &format!("path resolved multiple times \
|
|
||||||
({:?} before, {:?} now)",
|
|
||||||
prev_def, def));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4466,12 +4466,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
|
|
||||||
pub struct CrateMap {
|
pub struct CrateMap {
|
||||||
pub def_map: DefMap,
|
pub def_map: DefMap,
|
||||||
pub partial_def_map: PartialDefMap,
|
|
||||||
pub freevars: RefCell<FreevarMap>,
|
pub freevars: RefCell<FreevarMap>,
|
||||||
pub export_map: ExportMap,
|
pub export_map: ExportMap,
|
||||||
pub trait_map: TraitMap,
|
pub trait_map: TraitMap,
|
||||||
pub external_exports: ExternalExports,
|
pub external_exports: ExternalExports,
|
||||||
pub last_private_map: LastPrivateMap,
|
|
||||||
pub glob_map: Option<GlobMap>
|
pub glob_map: Option<GlobMap>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4506,12 +4504,10 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
|
||||||
|
|
||||||
CrateMap {
|
CrateMap {
|
||||||
def_map: resolver.def_map,
|
def_map: resolver.def_map,
|
||||||
partial_def_map: resolver.partial_def_map,
|
|
||||||
freevars: resolver.freevars,
|
freevars: resolver.freevars,
|
||||||
export_map: resolver.export_map,
|
export_map: resolver.export_map,
|
||||||
trait_map: resolver.trait_map,
|
trait_map: resolver.trait_map,
|
||||||
external_exports: resolver.external_exports,
|
external_exports: resolver.external_exports,
|
||||||
last_private_map: resolver.last_private,
|
|
||||||
glob_map: if resolver.make_glob_map {
|
glob_map: if resolver.make_glob_map {
|
||||||
Some(resolver.glob_map)
|
Some(resolver.glob_map)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -218,7 +218,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||||
self.sess.bug(&format!("def_map has no key for {} in lookup_type_ref",
|
self.sess.bug(&format!("def_map has no key for {} in lookup_type_ref",
|
||||||
ref_id));
|
ref_id));
|
||||||
}
|
}
|
||||||
let def = (*self.analysis.ty_cx.def_map.borrow())[ref_id];
|
let def = self.analysis.ty_cx.def_map.borrow()[ref_id].full_def();
|
||||||
match def {
|
match def {
|
||||||
def::DefPrimTy(_) => None,
|
def::DefPrimTy(_) => None,
|
||||||
_ => Some(def.def_id()),
|
_ => Some(def.def_id()),
|
||||||
|
@ -231,7 +231,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||||
self.sess.span_bug(span, &format!("def_map has no key for {} in lookup_def_kind",
|
self.sess.span_bug(span, &format!("def_map has no key for {} in lookup_def_kind",
|
||||||
ref_id));
|
ref_id));
|
||||||
}
|
}
|
||||||
let def = (*def_map)[ref_id];
|
let def = def_map[ref_id].full_def();
|
||||||
match def {
|
match def {
|
||||||
def::DefMod(_) |
|
def::DefMod(_) |
|
||||||
def::DefForeignMod(_) => Some(recorder::ModRef),
|
def::DefForeignMod(_) => Some(recorder::ModRef),
|
||||||
|
@ -792,9 +792,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||||
self.sess.span_bug(span,
|
self.sess.span_bug(span,
|
||||||
&format!("def_map has no key for {} in visit_expr", id));
|
&format!("def_map has no key for {} in visit_expr", id));
|
||||||
}
|
}
|
||||||
let def = &(*def_map)[id];
|
let def = def_map[id].full_def();
|
||||||
let sub_span = self.span.span_for_last_ident(span);
|
let sub_span = self.span.span_for_last_ident(span);
|
||||||
match *def {
|
match def {
|
||||||
def::DefUpvar(..) |
|
def::DefUpvar(..) |
|
||||||
def::DefLocal(..) |
|
def::DefLocal(..) |
|
||||||
def::DefStatic(..) |
|
def::DefStatic(..) |
|
||||||
|
@ -866,10 +866,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||||
&format!("Unexpected def kind while looking \
|
&format!("Unexpected def kind while looking \
|
||||||
up path in `{}`: `{:?}`",
|
up path in `{}`: `{:?}`",
|
||||||
self.span.snippet(span),
|
self.span.snippet(span),
|
||||||
*def)),
|
def)),
|
||||||
}
|
}
|
||||||
// modules or types in the path prefix
|
// modules or types in the path prefix
|
||||||
match *def {
|
match def {
|
||||||
def::DefMethod(did, _) => {
|
def::DefMethod(did, _) => {
|
||||||
let ti = ty::impl_or_trait_item(&self.analysis.ty_cx, did);
|
let ti = ty::impl_or_trait_item(&self.analysis.ty_cx, did);
|
||||||
if let ty::MethodTraitItem(m) = ti {
|
if let ty::MethodTraitItem(m) = ti {
|
||||||
|
@ -1456,8 +1456,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
||||||
&format!("def_map has no key for {} in visit_arm",
|
&format!("def_map has no key for {} in visit_arm",
|
||||||
id));
|
id));
|
||||||
}
|
}
|
||||||
let def = &(*def_map)[id];
|
let def = def_map[id].full_def();
|
||||||
match *def {
|
match def {
|
||||||
def::DefLocal(id) => {
|
def::DefLocal(id) => {
|
||||||
let value = if *immut {
|
let value = if *immut {
|
||||||
self.span.snippet(p.span).to_string()
|
self.span.snippet(p.span).to_string()
|
||||||
|
@ -1480,7 +1480,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
||||||
def::DefStatic(_, _) => {}
|
def::DefStatic(_, _) => {}
|
||||||
def::DefConst(..) => {}
|
def::DefConst(..) => {}
|
||||||
_ => error!("unexpected definition kind when processing collected paths: {:?}",
|
_ => error!("unexpected definition kind when processing collected paths: {:?}",
|
||||||
*def)
|
def)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for &(id, ref path, ref_kind) in &paths_to_process {
|
for &(id, ref path, ref_kind) in &paths_to_process {
|
||||||
|
|
|
@ -598,7 +598,7 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
}
|
}
|
||||||
ast::PatIdent(..) | ast::PatEnum(..) | ast::PatStruct(..) => {
|
ast::PatIdent(..) | ast::PatEnum(..) | ast::PatStruct(..) => {
|
||||||
// This is either an enum variant or a variable binding.
|
// This is either an enum variant or a variable binding.
|
||||||
let opt_def = tcx.def_map.borrow().get(&cur.id).cloned();
|
let opt_def = tcx.def_map.borrow().get(&cur.id).map(|d| d.full_def());
|
||||||
match opt_def {
|
match opt_def {
|
||||||
Some(def::DefVariant(enum_id, var_id, _)) => {
|
Some(def::DefVariant(enum_id, var_id, _)) => {
|
||||||
let variant = ty::enum_variant_with_id(tcx, enum_id, var_id);
|
let variant = ty::enum_variant_with_id(tcx, enum_id, var_id);
|
||||||
|
@ -725,14 +725,14 @@ fn any_irrefutable_adt_pat(tcx: &ty::ctxt, m: &[Match], col: uint) -> bool {
|
||||||
match pat.node {
|
match pat.node {
|
||||||
ast::PatTup(_) => true,
|
ast::PatTup(_) => true,
|
||||||
ast::PatStruct(..) => {
|
ast::PatStruct(..) => {
|
||||||
match tcx.def_map.borrow().get(&pat.id) {
|
match tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
|
||||||
Some(&def::DefVariant(..)) => false,
|
Some(def::DefVariant(..)) => false,
|
||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::PatEnum(..) | ast::PatIdent(_, _, None) => {
|
ast::PatEnum(..) | ast::PatIdent(_, _, None) => {
|
||||||
match tcx.def_map.borrow().get(&pat.id) {
|
match tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
|
||||||
Some(&def::DefStruct(..)) => true,
|
Some(def::DefStruct(..)) => true,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1282,15 +1282,15 @@ fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool
|
||||||
_ => return false
|
_ => return false
|
||||||
},
|
},
|
||||||
ast::ExprField(ref base, field) => {
|
ast::ExprField(ref base, field) => {
|
||||||
let vid = match bcx.tcx().def_map.borrow().get(&base.id) {
|
let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) {
|
||||||
Some(&def::DefLocal(vid)) | Some(&def::DefUpvar(vid, _)) => vid,
|
Some(def::DefLocal(vid)) | Some(def::DefUpvar(vid, _)) => vid,
|
||||||
_ => return false
|
_ => return false
|
||||||
};
|
};
|
||||||
(vid, Some(mc::NamedField(field.node.name)))
|
(vid, Some(mc::NamedField(field.node.name)))
|
||||||
},
|
},
|
||||||
ast::ExprTupField(ref base, field) => {
|
ast::ExprTupField(ref base, field) => {
|
||||||
let vid = match bcx.tcx().def_map.borrow().get(&base.id) {
|
let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) {
|
||||||
Some(&def::DefLocal(vid)) | Some(&def::DefUpvar(vid, _)) => vid,
|
Some(def::DefLocal(vid)) | Some(def::DefUpvar(vid, _)) => vid,
|
||||||
_ => return false
|
_ => return false
|
||||||
};
|
};
|
||||||
(vid, Some(mc::PositionalField(field.node)))
|
(vid, Some(mc::PositionalField(field.node)))
|
||||||
|
@ -1689,7 +1689,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::PatEnum(_, ref sub_pats) => {
|
ast::PatEnum(_, ref sub_pats) => {
|
||||||
let opt_def = bcx.tcx().def_map.borrow().get(&pat.id).cloned();
|
let opt_def = bcx.tcx().def_map.borrow().get(&pat.id).map(|d| d.full_def());
|
||||||
match opt_def {
|
match opt_def {
|
||||||
Some(def::DefVariant(enum_id, var_id, _)) => {
|
Some(def::DefVariant(enum_id, var_id, _)) => {
|
||||||
let repr = adt::represent_node(bcx, pat.id);
|
let repr = adt::represent_node(bcx, pat.id);
|
||||||
|
|
|
@ -603,7 +603,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
|
||||||
|
|
||||||
pub fn def(&self, nid: ast::NodeId) -> def::Def {
|
pub fn def(&self, nid: ast::NodeId) -> def::Def {
|
||||||
match self.tcx().def_map.borrow().get(&nid) {
|
match self.tcx().def_map.borrow().get(&nid) {
|
||||||
Some(v) => v.clone(),
|
Some(v) => v.full_def(),
|
||||||
None => {
|
None => {
|
||||||
self.tcx().sess.bug(&format!(
|
self.tcx().sess.bug(&format!(
|
||||||
"no def associated with node id {}", nid));
|
"no def associated with node id {}", nid));
|
||||||
|
|
|
@ -194,7 +194,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
// Special-case constants to cache a common global for all uses.
|
// Special-case constants to cache a common global for all uses.
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ast::ExprPath(_) => {
|
ast::ExprPath(_) => {
|
||||||
let def = ccx.tcx().def_map.borrow()[expr.id];
|
let def = ccx.tcx().def_map.borrow()[expr.id].full_def();
|
||||||
match def {
|
match def {
|
||||||
def::DefConst(def_id) => {
|
def::DefConst(def_id) => {
|
||||||
if !ccx.tcx().adjustments.borrow().contains_key(&expr.id) {
|
if !ccx.tcx().adjustments.borrow().contains_key(&expr.id) {
|
||||||
|
@ -582,7 +582,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
_ => break,
|
_ => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let opt_def = cx.tcx().def_map.borrow().get(&cur.id).cloned();
|
let opt_def = cx.tcx().def_map.borrow().get(&cur.id).map(|d| d.full_def());
|
||||||
if let Some(def::DefStatic(def_id, _)) = opt_def {
|
if let Some(def::DefStatic(def_id, _)) = opt_def {
|
||||||
return get_static_val(cx, def_id, ety);
|
return get_static_val(cx, def_id, ety);
|
||||||
}
|
}
|
||||||
|
@ -664,7 +664,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
||||||
let def = cx.tcx().def_map.borrow()[e.id];
|
let def = cx.tcx().def_map.borrow()[e.id].full_def();
|
||||||
match def {
|
match def {
|
||||||
def::DefFn(..) | def::DefMethod(..) => {
|
def::DefFn(..) | def::DefMethod(..) => {
|
||||||
expr::trans_def_fn_unadjusted(cx, e, def, param_substs).val
|
expr::trans_def_fn_unadjusted(cx, e, def, param_substs).val
|
||||||
|
@ -701,7 +701,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprCall(ref callee, ref args) => {
|
ast::ExprCall(ref callee, ref args) => {
|
||||||
let opt_def = cx.tcx().def_map.borrow().get(&callee.id).cloned();
|
let opt_def = cx.tcx().def_map.borrow().get(&callee.id).map(|d| d.full_def());
|
||||||
let arg_vals = map_list(&args[..]);
|
let arg_vals = map_list(&args[..]);
|
||||||
match opt_def {
|
match opt_def {
|
||||||
Some(def::DefStruct(_)) => {
|
Some(def::DefStruct(_)) => {
|
||||||
|
|
|
@ -306,11 +306,10 @@ pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
let loop_id = match opt_label {
|
let loop_id = match opt_label {
|
||||||
None => fcx.top_loop_scope(),
|
None => fcx.top_loop_scope(),
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
match bcx.tcx().def_map.borrow().get(&expr.id) {
|
match bcx.tcx().def_map.borrow().get(&expr.id).map(|d| d.full_def()) {
|
||||||
Some(&def::DefLabel(loop_id)) => loop_id,
|
Some(def::DefLabel(loop_id)) => loop_id,
|
||||||
ref r => {
|
r => {
|
||||||
bcx.tcx().sess.bug(&format!("{:?} in def-map for label",
|
bcx.tcx().sess.bug(&format!("{:?} in def-map for label", r))
|
||||||
r))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1363,7 +1363,7 @@ pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>,
|
||||||
ty.repr(tcx)));
|
ty.repr(tcx)));
|
||||||
}
|
}
|
||||||
Some(node_id) => {
|
Some(node_id) => {
|
||||||
let def = tcx.def_map.borrow()[node_id].clone();
|
let def = tcx.def_map.borrow()[node_id].full_def();
|
||||||
match def {
|
match def {
|
||||||
def::DefVariant(enum_id, variant_id, _) => {
|
def::DefVariant(enum_id, variant_id, _) => {
|
||||||
let variant_info = ty::enum_variant_with_id(
|
let variant_info = ty::enum_variant_with_id(
|
||||||
|
|
|
@ -898,7 +898,7 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>,
|
||||||
|
|
||||||
match ty.node {
|
match ty.node {
|
||||||
ast::TyPath(ref path) => {
|
ast::TyPath(ref path) => {
|
||||||
let def = this.tcx().def_map.borrow().get(&ty.id).cloned();
|
let def = this.tcx().def_map.borrow().get(&ty.id).map(|d| d.full_def());
|
||||||
match def {
|
match def {
|
||||||
Some(def::DefTrait(trait_def_id)) => {
|
Some(def::DefTrait(trait_def_id)) => {
|
||||||
let mut projection_bounds = Vec::new();
|
let mut projection_bounds = Vec::new();
|
||||||
|
@ -1303,16 +1303,14 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||||
conv_ty_poly_trait_ref(this, rscope, ast_ty.span, bounds)
|
conv_ty_poly_trait_ref(this, rscope, ast_ty.span, bounds)
|
||||||
}
|
}
|
||||||
ast::TyPath(ref path) | ast::TyQPath(ast::QPath { ref path, .. }) => {
|
ast::TyPath(ref path) | ast::TyQPath(ast::QPath { ref path, .. }) => {
|
||||||
let result = if let Some(&d) = tcx.def_map.borrow().get(&ast_ty.id) {
|
let path_res = if let Some(&d) = tcx.def_map.borrow().get(&ast_ty.id) {
|
||||||
(d, 0)
|
d
|
||||||
} else if let Some(d) = tcx.partial_def_map.borrow().get(&ast_ty.id) {
|
|
||||||
(d.base_type, (d.extra_associated_types + 1) as usize)
|
|
||||||
} else {
|
} else {
|
||||||
tcx.sess.span_bug(ast_ty.span,
|
tcx.sess.span_bug(ast_ty.span,
|
||||||
&format!("unbound path {}", ast_ty.repr(tcx)))
|
&format!("unbound path {}", ast_ty.repr(tcx)))
|
||||||
};
|
};
|
||||||
let (mut def, max_depth) = result;
|
let mut def = path_res.base_def;
|
||||||
let base_ty_end = path.segments.len() - max_depth;
|
let base_ty_end = path.segments.len() - path_res.depth;
|
||||||
let opt_self_ty = if let ast::TyQPath(ref qpath) = ast_ty.node {
|
let opt_self_ty = if let ast::TyQPath(ref qpath) = ast_ty.node {
|
||||||
Some(ast_ty_to_ty(this, rscope, &*qpath.self_type))
|
Some(ast_ty_to_ty(this, rscope, &*qpath.self_type))
|
||||||
} else {
|
} else {
|
||||||
|
@ -1324,9 +1322,13 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||||
&path.segments[..base_ty_end],
|
&path.segments[..base_ty_end],
|
||||||
&path.segments[base_ty_end..]);
|
&path.segments[base_ty_end..]);
|
||||||
|
|
||||||
if max_depth != 0 && ty.sty != ty::ty_err {
|
if path_res.depth != 0 && ty.sty != ty::ty_err {
|
||||||
// Write back the new resolution.
|
// Write back the new resolution.
|
||||||
tcx.def_map.borrow_mut().insert(ast_ty.id, def);
|
tcx.def_map.borrow_mut().insert(ast_ty.id, def::PathResolution {
|
||||||
|
base_def: def,
|
||||||
|
last_private: path_res.last_private,
|
||||||
|
depth: 0
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ty
|
ty
|
||||||
|
|
|
@ -103,7 +103,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
|
||||||
demand::eqtype(fcx, pat.span, expected, lhs_ty);
|
demand::eqtype(fcx, pat.span, expected, lhs_ty);
|
||||||
}
|
}
|
||||||
ast::PatEnum(..) | ast::PatIdent(..) if pat_is_const(&tcx.def_map, pat) => {
|
ast::PatEnum(..) | ast::PatIdent(..) if pat_is_const(&tcx.def_map, pat) => {
|
||||||
let const_did = tcx.def_map.borrow()[pat.id].clone().def_id();
|
let const_did = tcx.def_map.borrow()[pat.id].def_id();
|
||||||
let const_scheme = ty::lookup_item_type(tcx, const_did);
|
let const_scheme = ty::lookup_item_type(tcx, const_did);
|
||||||
assert!(const_scheme.generics.is_empty());
|
assert!(const_scheme.generics.is_empty());
|
||||||
let const_ty = pcx.fcx.instantiate_type_scheme(pat.span,
|
let const_ty = pcx.fcx.instantiate_type_scheme(pat.span,
|
||||||
|
@ -433,7 +433,7 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat,
|
||||||
let fcx = pcx.fcx;
|
let fcx = pcx.fcx;
|
||||||
let tcx = pcx.fcx.ccx.tcx;
|
let tcx = pcx.fcx.ccx.tcx;
|
||||||
|
|
||||||
let def = tcx.def_map.borrow()[pat.id].clone();
|
let def = tcx.def_map.borrow()[pat.id].full_def();
|
||||||
let (enum_def_id, variant_def_id) = match def {
|
let (enum_def_id, variant_def_id) = match def {
|
||||||
def::DefTrait(_) => {
|
def::DefTrait(_) => {
|
||||||
let name = pprust::path_to_string(path);
|
let name = pprust::path_to_string(path);
|
||||||
|
@ -502,7 +502,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
|
||||||
let fcx = pcx.fcx;
|
let fcx = pcx.fcx;
|
||||||
let tcx = pcx.fcx.ccx.tcx;
|
let tcx = pcx.fcx.ccx.tcx;
|
||||||
|
|
||||||
let def = tcx.def_map.borrow()[pat.id].clone();
|
let def = tcx.def_map.borrow()[pat.id].full_def();
|
||||||
let enum_def = def.variant_def_ids()
|
let enum_def = def.variant_def_ids()
|
||||||
.map_or_else(|| def.def_id(), |(enum_def, _)| enum_def);
|
.map_or_else(|| def.def_id(), |(enum_def, _)| enum_def);
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,6 @@ use middle::infer;
|
||||||
use middle::mem_categorization as mc;
|
use middle::mem_categorization as mc;
|
||||||
use middle::mem_categorization::McResult;
|
use middle::mem_categorization::McResult;
|
||||||
use middle::pat_util::{self, pat_id_map};
|
use middle::pat_util::{self, pat_id_map};
|
||||||
use middle::privacy::{AllPublic, LastMod};
|
|
||||||
use middle::region::{self, CodeExtent};
|
use middle::region::{self, CodeExtent};
|
||||||
use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
|
use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
|
||||||
use middle::traits;
|
use middle::traits;
|
||||||
|
@ -3598,21 +3597,23 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helpers to avoid keeping the RefCell borrow for too long.
|
let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
|
||||||
let get_def = || tcx.def_map.borrow().get(&id).cloned();
|
d
|
||||||
let get_partial_def = || tcx.partial_def_map.borrow().get(&id).cloned();
|
} else {
|
||||||
|
tcx.sess.span_bug(expr.span,
|
||||||
|
&format!("unbound path {}", expr.repr(tcx))[])
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(def) = get_def() {
|
let mut def = path_res.base_def;
|
||||||
|
if path_res.depth == 0 {
|
||||||
let (scheme, predicates) =
|
let (scheme, predicates) =
|
||||||
type_scheme_and_predicates_for_def(fcx, expr.span, def);
|
type_scheme_and_predicates_for_def(fcx, expr.span, def);
|
||||||
instantiate_path(fcx, &path.segments,
|
instantiate_path(fcx, &path.segments,
|
||||||
scheme, &predicates,
|
scheme, &predicates,
|
||||||
None, def, expr.span, id);
|
opt_self_ty, def, expr.span, id);
|
||||||
} else if let Some(partial) = get_partial_def() {
|
} else {
|
||||||
let mut def = partial.base_type;
|
|
||||||
let ty_segments = path.segments.init();
|
let ty_segments = path.segments.init();
|
||||||
let ty_assoc_num = partial.extra_associated_types as usize;
|
let base_ty_end = path.segments.len() - path_res.depth;
|
||||||
let base_ty_end = ty_segments.len() - ty_assoc_num;
|
|
||||||
let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, expr.span,
|
let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, expr.span,
|
||||||
PathParamMode::Optional,
|
PathParamMode::Optional,
|
||||||
&mut def,
|
&mut def,
|
||||||
|
@ -3624,13 +3625,11 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
match method::resolve_ufcs(fcx, expr.span, method_name, ty, id) {
|
match method::resolve_ufcs(fcx, expr.span, method_name, ty, id) {
|
||||||
Ok((def, lp)) => {
|
Ok((def, lp)) => {
|
||||||
// Write back the new resolution.
|
// Write back the new resolution.
|
||||||
tcx.def_map.borrow_mut().insert(id, def);
|
tcx.def_map.borrow_mut().insert(id, def::PathResolution {
|
||||||
|
base_def: def,
|
||||||
if let LastMod(AllPublic) = lp {
|
last_private: path_res.last_private.or(lp),
|
||||||
// Public method, don't change the last private entry.
|
depth: 0
|
||||||
} else {
|
});
|
||||||
tcx.last_private_map.borrow_mut().insert(id, lp);
|
|
||||||
}
|
|
||||||
|
|
||||||
let (scheme, predicates) =
|
let (scheme, predicates) =
|
||||||
type_scheme_and_predicates_for_def(fcx, expr.span, def);
|
type_scheme_and_predicates_for_def(fcx, expr.span, def);
|
||||||
|
@ -3644,9 +3643,6 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
fcx.write_error(id);
|
fcx.write_error(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
tcx.sess.span_bug(expr.span,
|
|
||||||
&format!("unbound path {}", expr.repr(tcx))[])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We always require that the type provided as the value for
|
// We always require that the type provided as the value for
|
||||||
|
@ -3882,7 +3878,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
ast::ExprStruct(ref path, ref fields, ref base_expr) => {
|
ast::ExprStruct(ref path, ref fields, ref base_expr) => {
|
||||||
// Resolve the path.
|
// Resolve the path.
|
||||||
let def = tcx.def_map.borrow().get(&id).cloned();
|
let def = tcx.def_map.borrow().get(&id).map(|d| d.full_def());
|
||||||
let struct_id = match def {
|
let struct_id = match def {
|
||||||
Some(def::DefVariant(enum_id, variant_id, true)) => {
|
Some(def::DefVariant(enum_id, variant_id, true)) => {
|
||||||
check_struct_enum_variant(fcx, id, expr.span, enum_id,
|
check_struct_enum_variant(fcx, id, expr.span, enum_id,
|
||||||
|
@ -5174,8 +5170,8 @@ pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool {
|
||||||
(block_query(b, |e| {
|
(block_query(b, |e| {
|
||||||
match e.node {
|
match e.node {
|
||||||
ast::ExprBreak(Some(_)) => {
|
ast::ExprBreak(Some(_)) => {
|
||||||
match cx.def_map.borrow().get(&e.id) {
|
match cx.def_map.borrow().get(&e.id).map(|d| d.full_def()) {
|
||||||
Some(&def::DefLabel(loop_id)) if id == loop_id => true,
|
Some(def::DefLabel(loop_id)) if id == loop_id => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,7 +165,7 @@ fn write_substs_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||||
}
|
}
|
||||||
fn lookup_def_tcx(tcx:&ty::ctxt, sp: Span, id: ast::NodeId) -> def::Def {
|
fn lookup_def_tcx(tcx:&ty::ctxt, sp: Span, id: ast::NodeId) -> def::Def {
|
||||||
match tcx.def_map.borrow().get(&id) {
|
match tcx.def_map.borrow().get(&id) {
|
||||||
Some(x) => x.clone(),
|
Some(x) => x.full_def(),
|
||||||
_ => {
|
_ => {
|
||||||
span_fatal!(tcx.sess, sp, E0242, "internal error looking up a definition")
|
span_fatal!(tcx.sess, sp, E0242, "internal error looking up a definition")
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ pub fn try_inline(cx: &DocContext, id: ast::NodeId, into: Option<ast::Ident>)
|
||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
let def = match tcx.def_map.borrow().get(&id) {
|
let def = match tcx.def_map.borrow().get(&id) {
|
||||||
Some(def) => *def,
|
Some(d) => d.full_def(),
|
||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
let did = def.def_id();
|
let did = def.def_id();
|
||||||
|
|
|
@ -2388,7 +2388,7 @@ fn resolve_type(cx: &DocContext,
|
||||||
};
|
};
|
||||||
debug!("searching for {} in defmap", id);
|
debug!("searching for {} in defmap", id);
|
||||||
let def = match tcx.def_map.borrow().get(&id) {
|
let def = match tcx.def_map.borrow().get(&id) {
|
||||||
Some(&k) => k,
|
Some(k) => k.full_def(),
|
||||||
None => panic!("unresolved id not in defmap")
|
None => panic!("unresolved id not in defmap")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2454,7 +2454,7 @@ fn resolve_use_source(cx: &DocContext, path: Path, id: ast::NodeId) -> ImportSou
|
||||||
|
|
||||||
fn resolve_def(cx: &DocContext, id: ast::NodeId) -> Option<ast::DefId> {
|
fn resolve_def(cx: &DocContext, id: ast::NodeId) -> Option<ast::DefId> {
|
||||||
cx.tcx_opt().and_then(|tcx| {
|
cx.tcx_opt().and_then(|tcx| {
|
||||||
tcx.def_map.borrow().get(&id).map(|&def| register_def(cx, def))
|
tcx.def_map.borrow().get(&id).map(|d| register_def(cx, d.full_def()))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,7 +196,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
Some(tcx) => tcx,
|
Some(tcx) => tcx,
|
||||||
None => return false
|
None => return false
|
||||||
};
|
};
|
||||||
let def = (*tcx.def_map.borrow())[id].def_id();
|
let def = tcx.def_map.borrow()[id].def_id();
|
||||||
if !ast_util::is_local(def) { return false }
|
if !ast_util::is_local(def) { return false }
|
||||||
let analysis = match self.analysis {
|
let analysis = match self.analysis {
|
||||||
Some(analysis) => analysis, None => return false
|
Some(analysis) => analysis, None => return false
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue