mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 15:01:51 +00:00
Auto merge of #34095 - petrochenkov:pathir2, r=jseyfried
Improvements to pattern resolution + some refactoring Continuation of https://github.com/rust-lang/rust/pull/33929 First commit is a careful rewrite of `resolve_pattern`, pattern path resolution and new binding creation logic is factored out in separate functions, some minor bugs are fixed. Also, `resolve_possibly_assoc_item` doesn't swallow modules now. Later commits are refactorings, see the comment descriptions. I intend to continue this work later with better support for `Def::Err` in patterns in post-resolve stages and cleanup of pattern resolution code in type checker. Fixes https://github.com/rust-lang/rust/issues/32086 Fixes https://github.com/rust-lang/rust/issues/34047 ([breaking-change]) Fixes https://github.com/rust-lang/rust/issues/34074 cc @jseyfried r? @eddyb
This commit is contained in:
commit
7d2f75a953
@ -574,8 +574,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
||||
return *self.loop_scopes.last().unwrap();
|
||||
}
|
||||
|
||||
match self.tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()) {
|
||||
Some(Def::Label(loop_id)) => {
|
||||
match self.tcx.expect_def(expr.id) {
|
||||
Def::Label(loop_id) => {
|
||||
for l in &self.loop_scopes {
|
||||
if l.loop_id == loop_id {
|
||||
return *l;
|
||||
|
@ -67,6 +67,10 @@ pub struct PathResolution {
|
||||
}
|
||||
|
||||
impl PathResolution {
|
||||
pub fn new(def: Def) -> PathResolution {
|
||||
PathResolution { base_def: def, depth: 0 }
|
||||
}
|
||||
|
||||
/// Get the definition, if fully resolved, otherwise panic.
|
||||
pub fn full_def(&self) -> Def {
|
||||
if self.depth != 0 {
|
||||
@ -75,17 +79,11 @@ impl PathResolution {
|
||||
self.base_def
|
||||
}
|
||||
|
||||
/// Get the DefId, if fully resolved, otherwise panic.
|
||||
pub fn def_id(&self) -> DefId {
|
||||
self.full_def().def_id()
|
||||
}
|
||||
|
||||
pub fn new(base_def: Def,
|
||||
depth: usize)
|
||||
-> PathResolution {
|
||||
PathResolution {
|
||||
base_def: base_def,
|
||||
depth: depth,
|
||||
pub fn kind_name(&self) -> &'static str {
|
||||
if self.depth != 0 {
|
||||
"associated item"
|
||||
} else {
|
||||
self.base_def.kind_name()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -161,8 +159,8 @@ impl Def {
|
||||
Def::Struct(..) => "struct",
|
||||
Def::Trait(..) => "trait",
|
||||
Def::Method(..) => "method",
|
||||
Def::Const(..) => "const",
|
||||
Def::AssociatedConst(..) => "associated const",
|
||||
Def::Const(..) => "constant",
|
||||
Def::AssociatedConst(..) => "associated constant",
|
||||
Def::TyParam(..) => "type parameter",
|
||||
Def::PrimTy(..) => "builtin type",
|
||||
Def::Local(..) => "local variable",
|
||||
|
@ -866,7 +866,7 @@ impl<'a> LoweringContext<'a> {
|
||||
PatKind::Wild => hir::PatKind::Wild,
|
||||
PatKind::Ident(ref binding_mode, pth1, ref sub) => {
|
||||
self.with_parent_def(p.id, |this| {
|
||||
match this.resolver.get_resolution(p.id).map(|d| d.full_def()) {
|
||||
match this.resolver.get_resolution(p.id).map(|d| d.base_def) {
|
||||
// `None` can occur in body-less function signatures
|
||||
None | Some(Def::Local(..)) => {
|
||||
hir::PatKind::Binding(this.lower_binding_mode(binding_mode),
|
||||
@ -1238,14 +1238,10 @@ impl<'a> LoweringContext<'a> {
|
||||
position: position,
|
||||
}
|
||||
});
|
||||
let rename = if path.segments.len() == 1 {
|
||||
// Only local variables are renamed
|
||||
match self.resolver.get_resolution(e.id).map(|d| d.full_def()) {
|
||||
Some(Def::Local(..)) | Some(Def::Upvar(..)) => true,
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
// Only local variables are renamed
|
||||
let rename = match self.resolver.get_resolution(e.id).map(|d| d.base_def) {
|
||||
Some(Def::Local(..)) | Some(Def::Upvar(..)) => true,
|
||||
_ => false,
|
||||
};
|
||||
hir::ExprPath(hir_qself, self.lower_path_full(path, rename))
|
||||
}
|
||||
|
@ -53,16 +53,6 @@ impl<T: ExactSizeIterator> EnumerateAndAdjustIterator for T {
|
||||
}
|
||||
}
|
||||
|
||||
// This is used because same-named variables in alternative patterns need to
|
||||
// use the NodeId of their namesake in the first pattern.
|
||||
pub fn pat_id_map(pat: &hir::Pat) -> PatIdMap {
|
||||
let mut map = FnvHashMap();
|
||||
pat_bindings(pat, |_bm, p_id, _s, path1| {
|
||||
map.insert(path1.node, p_id);
|
||||
});
|
||||
map
|
||||
}
|
||||
|
||||
pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
|
||||
match pat.node {
|
||||
PatKind::Lit(_) | PatKind::Range(_, _) | PatKind::QPath(..) => true,
|
||||
|
@ -1357,17 +1357,7 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
|
||||
ty_queue.push(&mut_ty.ty);
|
||||
}
|
||||
hir::TyPath(ref maybe_qself, ref path) => {
|
||||
let a_def = match self.tcx.def_map.borrow().get(&cur_ty.id) {
|
||||
None => {
|
||||
self.tcx
|
||||
.sess
|
||||
.fatal(&format!(
|
||||
"unbound path {}",
|
||||
pprust::path_to_string(path)))
|
||||
}
|
||||
Some(d) => d.full_def()
|
||||
};
|
||||
match a_def {
|
||||
match self.tcx.expect_def(cur_ty.id) {
|
||||
Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) => {
|
||||
let generics = self.tcx.lookup_item_type(did).generics;
|
||||
|
||||
|
@ -65,13 +65,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
/// to it.
|
||||
pub fn ast_ty_to_prim_ty(self, ast_ty: &ast::Ty) -> Option<Ty<'tcx>> {
|
||||
if let ast::TyPath(None, ref path) = ast_ty.node {
|
||||
let def = match self.def_map.borrow().get(&ast_ty.id) {
|
||||
None => {
|
||||
span_bug!(ast_ty.span, "unbound path {:?}", path)
|
||||
}
|
||||
Some(d) => d.full_def()
|
||||
};
|
||||
if let Def::PrimTy(nty) = def {
|
||||
if let Def::PrimTy(nty) = self.expect_def(ast_ty.id) {
|
||||
Some(self.prim_ty_to_ty(&path.segments, nty))
|
||||
} else {
|
||||
None
|
||||
|
@ -84,36 +84,35 @@ 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) {
|
||||
use ty::TypeVariants::{TyEnum, TyStruct};
|
||||
|
||||
// If `bar` is a trait item, make sure to mark Foo as alive in `Foo::bar`
|
||||
self.tcx.tables.borrow().item_substs.get(id)
|
||||
self.tcx.tables.borrow().item_substs.get(&id)
|
||||
.and_then(|substs| substs.substs.self_ty())
|
||||
.map(|ty| match ty.sty {
|
||||
TyEnum(tyid, _) | TyStruct(tyid, _) => self.check_def_id(tyid.did),
|
||||
_ => (),
|
||||
});
|
||||
|
||||
self.tcx.def_map.borrow().get(id).map(|def| {
|
||||
match def.full_def() {
|
||||
Def::Const(_) | Def::AssociatedConst(..) => {
|
||||
self.check_def_id(def.def_id());
|
||||
}
|
||||
_ if self.ignore_non_const_paths => (),
|
||||
Def::PrimTy(_) => (),
|
||||
Def::SelfTy(..) => (),
|
||||
Def::Variant(enum_id, variant_id) => {
|
||||
self.check_def_id(enum_id);
|
||||
if !self.ignore_variant_stack.contains(&variant_id) {
|
||||
self.check_def_id(variant_id);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.check_def_id(def.def_id());
|
||||
let def = self.tcx.expect_def(id);
|
||||
match def {
|
||||
Def::Const(_) | Def::AssociatedConst(..) => {
|
||||
self.check_def_id(def.def_id());
|
||||
}
|
||||
_ if self.ignore_non_const_paths => (),
|
||||
Def::PrimTy(_) => (),
|
||||
Def::SelfTy(..) => (),
|
||||
Def::Variant(enum_id, variant_id) => {
|
||||
self.check_def_id(enum_id);
|
||||
if !self.ignore_variant_stack.contains(&variant_id) {
|
||||
self.check_def_id(variant_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
_ => {
|
||||
self.check_def_id(def.def_id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn lookup_and_handle_method(&mut self, id: ast::NodeId) {
|
||||
@ -138,10 +137,10 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||
|
||||
fn handle_field_pattern_match(&mut self, lhs: &hir::Pat,
|
||||
pats: &[codemap::Spanned<hir::FieldPat>]) {
|
||||
let def = self.tcx.def_map.borrow().get(&lhs.id).unwrap().full_def();
|
||||
let pat_ty = self.tcx.node_id_to_type(lhs.id);
|
||||
let variant = match pat_ty.sty {
|
||||
ty::TyStruct(adt, _) | ty::TyEnum(adt, _) => adt.variant_of_def(def),
|
||||
let variant = match self.tcx.node_id_to_type(lhs.id).sty {
|
||||
ty::TyStruct(adt, _) | ty::TyEnum(adt, _) => {
|
||||
adt.variant_of_def(self.tcx.expect_def(lhs.id))
|
||||
}
|
||||
_ => span_bug!(lhs.span, "non-ADT in struct pattern")
|
||||
};
|
||||
for pat in pats {
|
||||
@ -272,7 +271,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
|
||||
}
|
||||
_ if pat_util::pat_is_const(&def_map.borrow(), pat) => {
|
||||
// it might be the only use of a const
|
||||
self.lookup_and_handle_definition(&pat.id)
|
||||
self.lookup_and_handle_definition(pat.id)
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
@ -283,12 +282,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) {
|
||||
self.lookup_and_handle_definition(&id);
|
||||
self.lookup_and_handle_definition(id);
|
||||
intravisit::walk_path(self, path);
|
||||
}
|
||||
|
||||
fn visit_path_list_item(&mut self, path: &hir::Path, item: &hir::PathListItem) {
|
||||
self.lookup_and_handle_definition(&item.node.id());
|
||||
self.lookup_and_handle_definition(item.node.id());
|
||||
intravisit::walk_path_list_item(self, path, item);
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
|
||||
self.require_unsafe(expr.span, "use of inline assembly");
|
||||
}
|
||||
hir::ExprPath(..) => {
|
||||
if let Def::Static(_, true) = self.tcx.resolve_expr(expr) {
|
||||
if let Def::Static(_, true) = self.tcx.expect_def(expr.id) {
|
||||
self.require_unsafe(expr.span, "use of mutable static");
|
||||
}
|
||||
}
|
||||
|
@ -955,9 +955,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
debug!("walk_pat cmt_discr={:?} pat={:?}", cmt_discr,
|
||||
pat);
|
||||
|
||||
let tcx = &self.tcx();
|
||||
let mc = &self.mc;
|
||||
let infcx = self.mc.infcx;
|
||||
let def_map = &self.tcx().def_map;
|
||||
let delegate = &mut self.delegate;
|
||||
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| {
|
||||
match pat.node {
|
||||
@ -972,8 +972,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
|
||||
// Each match binding is effectively an assignment to the
|
||||
// binding being produced.
|
||||
let def = def_map.borrow().get(&pat.id).unwrap().full_def();
|
||||
if let Ok(binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty, def) {
|
||||
if let Ok(binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty,
|
||||
tcx.expect_def(pat.id)) {
|
||||
delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init);
|
||||
}
|
||||
|
||||
@ -1002,14 +1002,11 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
// to the above loop's visit of than the bindings that form
|
||||
// the leaves of the pattern tree structure.
|
||||
return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| {
|
||||
let def_map = def_map.borrow();
|
||||
let tcx = infcx.tcx;
|
||||
|
||||
match pat.node {
|
||||
PatKind::Struct(..) | PatKind::TupleStruct(..) |
|
||||
PatKind::Path(..) | PatKind::QPath(..) => {
|
||||
match def_map.get(&pat.id).map(|d| d.full_def()) {
|
||||
Some(Def::Variant(enum_did, variant_did)) => {
|
||||
match tcx.expect_def(pat.id) {
|
||||
Def::Variant(enum_did, variant_did) => {
|
||||
let downcast_cmt =
|
||||
if tcx.lookup_adt_def(enum_did).is_univariant() {
|
||||
cmt_pat
|
||||
@ -1025,7 +1022,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
delegate.matched_pat(pat, downcast_cmt, match_mode);
|
||||
}
|
||||
|
||||
Some(Def::Struct(..)) | Some(Def::TyAlias(..)) => {
|
||||
Def::Struct(..) | Def::TyAlias(..) => {
|
||||
// A struct (in either the value or type
|
||||
// namespace; we encounter the former on
|
||||
// e.g. patterns for unit structs).
|
||||
@ -1037,8 +1034,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
delegate.matched_pat(pat, cmt_pat, match_mode);
|
||||
}
|
||||
|
||||
Some(Def::Const(..)) |
|
||||
Some(Def::AssociatedConst(..)) => {
|
||||
Def::Const(..) | Def::AssociatedConst(..) => {
|
||||
// This is a leaf (i.e. identifier binding
|
||||
// or constant value to match); thus no
|
||||
// `matched_pat` call.
|
||||
|
@ -156,7 +156,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for ExprVisitor<'a, 'gcx, 'tcx> {
|
||||
fn visit_expr(&mut self, expr: &hir::Expr) {
|
||||
if let hir::ExprPath(..) = expr.node {
|
||||
match self.infcx.tcx.resolve_expr(expr) {
|
||||
match self.infcx.tcx.expect_def(expr.id) {
|
||||
Def::Fn(did) if self.def_id_is_transmute(did) => {
|
||||
let typ = self.infcx.tcx.node_id_to_type(expr.id);
|
||||
match typ.sty {
|
||||
|
@ -445,7 +445,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
|
||||
match expr.node {
|
||||
// live nodes required for uses or definitions of variables:
|
||||
hir::ExprPath(..) => {
|
||||
let def = ir.tcx.def_map.borrow().get(&expr.id).unwrap().full_def();
|
||||
let def = ir.tcx.expect_def(expr.id);
|
||||
debug!("expr {}: path that leads to {:?}", expr.id, def);
|
||||
if let Def::Local(..) = def {
|
||||
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
||||
@ -695,8 +695,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
Some(_) => {
|
||||
// Refers to a labeled loop. Use the results of resolve
|
||||
// to find with one
|
||||
match self.ir.tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
|
||||
Some(Def::Label(loop_id)) => loop_id,
|
||||
match self.ir.tcx.expect_def(id) {
|
||||
Def::Label(loop_id) => loop_id,
|
||||
_ => span_bug!(sp, "label on break/loop \
|
||||
doesn't refer to a loop")
|
||||
}
|
||||
@ -1269,7 +1269,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
|
||||
fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: u32)
|
||||
-> LiveNode {
|
||||
match self.ir.tcx.def_map.borrow().get(&expr.id).unwrap().full_def() {
|
||||
match self.ir.tcx.expect_def(expr.id) {
|
||||
Def::Local(_, nid) => {
|
||||
let ln = self.live_node(expr.id, expr.span);
|
||||
if acc != 0 {
|
||||
@ -1534,9 +1534,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
fn check_lvalue(&mut self, expr: &Expr) {
|
||||
match expr.node {
|
||||
hir::ExprPath(..) => {
|
||||
if let Def::Local(_, nid) = self.ir.tcx.def_map.borrow().get(&expr.id)
|
||||
.unwrap()
|
||||
.full_def() {
|
||||
if let Def::Local(_, nid) = self.ir.tcx.expect_def(expr.id) {
|
||||
// Assignment to an immutable variable or argument: only legal
|
||||
// if there is no later assignment. If this local is actually
|
||||
// mutable, then check for a reassignment to flag the mutability
|
||||
|
@ -517,8 +517,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
hir::ExprPath(..) => {
|
||||
let def = self.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
|
||||
self.cat_def(expr.id, expr.span, expr_ty, def)
|
||||
self.cat_def(expr.id, expr.span, expr_ty, self.tcx().expect_def(expr.id))
|
||||
}
|
||||
|
||||
hir::ExprType(ref e, _) => {
|
||||
@ -1106,18 +1105,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
|
||||
(*op)(self, cmt.clone(), pat);
|
||||
|
||||
let opt_def = if let Some(path_res) = self.tcx().def_map.borrow().get(&pat.id) {
|
||||
if path_res.depth != 0 || path_res.base_def == Def::Err {
|
||||
// Since patterns can be associated constants
|
||||
// which are resolved during typeck, we might have
|
||||
// some unresolved patterns reaching this stage
|
||||
// without aborting
|
||||
return Err(());
|
||||
}
|
||||
Some(path_res.full_def())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let opt_def = self.tcx().expect_def_or_none(pat.id);
|
||||
if opt_def == Some(Def::Err) {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
// Note: This goes up here (rather than within the PatKind::TupleStruct arm
|
||||
// alone) because struct patterns can refer to struct types or
|
||||
|
@ -92,13 +92,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
|
||||
fn visit_expr(&mut self, expr: &hir::Expr) {
|
||||
match expr.node {
|
||||
hir::ExprPath(..) => {
|
||||
let def = match self.tcx.def_map.borrow().get(&expr.id) {
|
||||
Some(d) => d.full_def(),
|
||||
None => {
|
||||
span_bug!(expr.span, "def ID not in def map?!")
|
||||
}
|
||||
};
|
||||
|
||||
let def = self.tcx.expect_def(expr.id);
|
||||
let def_id = def.def_id();
|
||||
if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) {
|
||||
if self.def_id_represents_local_inlined_item(def_id) {
|
||||
|
@ -494,7 +494,7 @@ pub fn check_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
// individually as it's possible to have a stable trait with unstable
|
||||
// items.
|
||||
hir::ItemImpl(_, _, _, Some(ref t), _, ref impl_items) => {
|
||||
let trait_did = tcx.def_map.borrow().get(&t.ref_id).unwrap().def_id();
|
||||
let trait_did = tcx.expect_def(t.ref_id).def_id();
|
||||
let trait_items = tcx.trait_items(trait_did);
|
||||
|
||||
for impl_item in impl_items {
|
||||
@ -580,7 +580,8 @@ pub fn check_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
cb: &mut FnMut(DefId, Span,
|
||||
&Option<&Stability>,
|
||||
&Option<Deprecation>)) {
|
||||
match tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
|
||||
// Paths in import prefixes may have no resolution.
|
||||
match tcx.expect_def_or_none(id) {
|
||||
Some(Def::PrimTy(..)) => {}
|
||||
Some(Def::SelfTy(..)) => {}
|
||||
Some(def) => {
|
||||
@ -595,12 +596,11 @@ pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
cb: &mut FnMut(DefId, Span,
|
||||
&Option<&Stability>,
|
||||
&Option<Deprecation>)) {
|
||||
match tcx.def_map.borrow().get(&item.node.id()).map(|d| d.full_def()) {
|
||||
Some(Def::PrimTy(..)) => {}
|
||||
Some(def) => {
|
||||
match tcx.expect_def(item.node.id()) {
|
||||
Def::PrimTy(..) => {}
|
||||
def => {
|
||||
maybe_do_stability_check(tcx, def.def_id(), item.span, cb);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ use dep_graph::{self, DepNode};
|
||||
use hir::map as ast_map;
|
||||
use middle;
|
||||
use middle::cstore::{self, LOCAL_CRATE};
|
||||
use hir::def::{self, Def, ExportMap};
|
||||
use hir::def::{Def, PathResolution, ExportMap};
|
||||
use hir::def_id::DefId;
|
||||
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
|
||||
use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
|
||||
@ -308,13 +308,11 @@ impl Visibility {
|
||||
match *visibility {
|
||||
hir::Public => Visibility::Public,
|
||||
hir::Visibility::Crate => Visibility::Restricted(ast::CRATE_NODE_ID),
|
||||
hir::Visibility::Restricted { id, .. } => match tcx.def_map.borrow().get(&id) {
|
||||
Some(resolution) => Visibility::Restricted({
|
||||
tcx.map.as_local_node_id(resolution.base_def.def_id()).unwrap()
|
||||
}),
|
||||
hir::Visibility::Restricted { id, .. } => match tcx.expect_def(id) {
|
||||
// If there is no resolution, `resolve` will have already reported an error, so
|
||||
// assume that the visibility is public to avoid reporting more privacy errors.
|
||||
None => Visibility::Public,
|
||||
Def::Err => Visibility::Public,
|
||||
def => Visibility::Restricted(tcx.map.as_local_node_id(def.def_id()).unwrap()),
|
||||
},
|
||||
hir::Inherited => Visibility::Restricted(tcx.map.get_module_parent(id)),
|
||||
}
|
||||
@ -2249,34 +2247,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_expr(self, expr: &hir::Expr) -> Def {
|
||||
match self.def_map.borrow().get(&expr.id) {
|
||||
Some(def) => def.full_def(),
|
||||
None => {
|
||||
span_bug!(expr.span, "no def-map entry for expr {}", expr.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expr_is_lval(self, expr: &hir::Expr) -> bool {
|
||||
match expr.node {
|
||||
hir::ExprPath(..) => {
|
||||
// We can't use resolve_expr here, as this needs to run on broken
|
||||
// programs. We don't need to through - associated items are all
|
||||
// rvalues.
|
||||
match self.def_map.borrow().get(&expr.id) {
|
||||
Some(&def::PathResolution {
|
||||
base_def: Def::Static(..), ..
|
||||
}) | Some(&def::PathResolution {
|
||||
base_def: Def::Upvar(..), ..
|
||||
}) | Some(&def::PathResolution {
|
||||
base_def: Def::Local(..), ..
|
||||
}) => {
|
||||
true
|
||||
}
|
||||
Some(&def::PathResolution { base_def: Def::Err, .. })=> true,
|
||||
Some(..) => false,
|
||||
None => span_bug!(expr.span, "no def for path {}", expr.id)
|
||||
// This function can be used during type checking when not all paths are
|
||||
// fully resolved. Partially resolved paths in expressions can only legally
|
||||
// refer to associated items which are always rvalues.
|
||||
match self.expect_resolution(expr.id).base_def {
|
||||
Def::Local(..) | Def::Upvar(..) | Def::Static(..) | Def::Err => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2459,8 +2438,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trait_ref_to_def_id(self, tr: &hir::TraitRef) -> DefId {
|
||||
self.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id()
|
||||
/// Returns a path resolution for node id if it exists, panics otherwise.
|
||||
pub fn expect_resolution(self, id: NodeId) -> PathResolution {
|
||||
*self.def_map.borrow().get(&id).expect("no def-map entry for node id")
|
||||
}
|
||||
|
||||
/// Returns a fully resolved definition for node id if it exists, panics otherwise.
|
||||
pub fn expect_def(self, id: NodeId) -> Def {
|
||||
self.expect_resolution(id).full_def()
|
||||
}
|
||||
|
||||
/// Returns a fully resolved definition for node id if it exists, or none if no
|
||||
/// definition exists, panics on partial resolutions to catch errors.
|
||||
pub fn expect_def_or_none(self, id: NodeId) -> Option<Def> {
|
||||
self.def_map.borrow().get(&id).map(|resolution| resolution.full_def())
|
||||
}
|
||||
|
||||
pub fn def_key(self, id: DefId) -> ast_map::DefKey {
|
||||
|
@ -245,8 +245,7 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
|
||||
if let PatKind::Binding(hir::BindByValue(hir::MutImmutable), name, None) = p.node {
|
||||
let pat_ty = cx.tcx.pat_ty(p);
|
||||
if let ty::TyEnum(edef, _) = pat_ty.sty {
|
||||
let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
|
||||
if let Some(Def::Local(..)) = def {
|
||||
if let Def::Local(..) = cx.tcx.expect_def(p.id) {
|
||||
if edef.variants.iter().any(|variant|
|
||||
variant.name == name.node.unhygienize()
|
||||
&& variant.kind() == VariantKind::Unit
|
||||
@ -492,9 +491,8 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
|
||||
fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
|
||||
return match pat.node {
|
||||
PatKind::Path(..) | PatKind::QPath(..) => {
|
||||
let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
|
||||
match def {
|
||||
Some(Def::AssociatedConst(did)) | Some(Def::Const(did)) => {
|
||||
match self.tcx.expect_def(pat.id) {
|
||||
Def::AssociatedConst(did) | Def::Const(did) => {
|
||||
let substs = Some(self.tcx.node_id_item_substs(pat.id).substs);
|
||||
if let Some((const_expr, _)) = lookup_const_by_id(self.tcx, did, substs) {
|
||||
match const_expr_to_pat(self.tcx, const_expr, pat.id, pat.span) {
|
||||
@ -788,7 +786,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
|
||||
let pat = raw_pat(p);
|
||||
match pat.node {
|
||||
PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) =>
|
||||
match cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def() {
|
||||
match cx.tcx.expect_def(pat.id) {
|
||||
Def::Const(..) | Def::AssociatedConst(..) =>
|
||||
span_bug!(pat.span, "const pattern should've \
|
||||
been rewritten"),
|
||||
@ -903,21 +901,19 @@ pub fn specialize<'a, 'b, 'tcx>(
|
||||
Some(vec![dummy_pat; arity]),
|
||||
|
||||
PatKind::Path(..) => {
|
||||
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
|
||||
match def {
|
||||
match cx.tcx.expect_def(pat_id) {
|
||||
Def::Const(..) | Def::AssociatedConst(..) =>
|
||||
span_bug!(pat_span, "const pattern should've \
|
||||
been rewritten"),
|
||||
Def::Variant(_, id) if *constructor != Variant(id) => None,
|
||||
Def::Variant(..) | Def::Struct(..) => Some(Vec::new()),
|
||||
_ => span_bug!(pat_span, "specialize: unexpected \
|
||||
def => span_bug!(pat_span, "specialize: unexpected \
|
||||
definition {:?}", def),
|
||||
}
|
||||
}
|
||||
|
||||
PatKind::TupleStruct(_, ref args, ddpos) => {
|
||||
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
|
||||
match def {
|
||||
match cx.tcx.expect_def(pat_id) {
|
||||
Def::Const(..) | Def::AssociatedConst(..) =>
|
||||
span_bug!(pat_span, "const pattern should've \
|
||||
been rewritten"),
|
||||
@ -944,10 +940,9 @@ pub fn specialize<'a, 'b, 'tcx>(
|
||||
}
|
||||
|
||||
PatKind::Struct(_, ref pattern_fields, _) => {
|
||||
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
|
||||
let adt = cx.tcx.node_id_to_type(pat_id).ty_adt_def().unwrap();
|
||||
let variant = constructor.variant_for_adt(adt);
|
||||
let def_variant = adt.variant_of_def(def);
|
||||
let def_variant = adt.variant_of_def(cx.tcx.expect_def(pat_id));
|
||||
if variant.did == def_variant.did {
|
||||
Some(variant.fields.iter().map(|sf| {
|
||||
match pattern_fields.iter().find(|f| f.node.name == sf.name) {
|
||||
|
@ -19,7 +19,7 @@ use rustc::hir::map as ast_map;
|
||||
use rustc::hir::map::blocks::FnLikeNode;
|
||||
use rustc::middle::cstore::{self, InlinedItem};
|
||||
use rustc::traits;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def::{Def, PathResolution};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::pat_util::def_to_path;
|
||||
use rustc::ty::{self, Ty, TyCtxt, subst};
|
||||
@ -276,11 +276,11 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
.collect()), None),
|
||||
|
||||
hir::ExprCall(ref callee, ref args) => {
|
||||
let def = *tcx.def_map.borrow().get(&callee.id).unwrap();
|
||||
let def = tcx.expect_def(callee.id);
|
||||
if let Vacant(entry) = tcx.def_map.borrow_mut().entry(expr.id) {
|
||||
entry.insert(def);
|
||||
entry.insert(PathResolution::new(def));
|
||||
}
|
||||
let path = match def.full_def() {
|
||||
let path = match def {
|
||||
Def::Struct(def_id) => def_to_path(tcx, def_id),
|
||||
Def::Variant(_, variant_did) => def_to_path(tcx, variant_did),
|
||||
Def::Fn(..) | Def::Method(..) => return Ok(P(hir::Pat {
|
||||
@ -322,12 +322,9 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
|
||||
hir::ExprPath(_, ref path) => {
|
||||
let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def());
|
||||
match opt_def {
|
||||
Some(Def::Struct(..)) | Some(Def::Variant(..)) =>
|
||||
PatKind::Path(path.clone()),
|
||||
Some(Def::Const(def_id)) |
|
||||
Some(Def::AssociatedConst(def_id)) => {
|
||||
match tcx.expect_def(expr.id) {
|
||||
Def::Struct(..) | Def::Variant(..) => PatKind::Path(path.clone()),
|
||||
Def::Const(def_id) | Def::AssociatedConst(def_id) => {
|
||||
let substs = Some(tcx.node_id_item_substs(expr.id).substs);
|
||||
let (expr, _ty) = lookup_const_by_id(tcx, def_id, substs).unwrap();
|
||||
return const_expr_to_pat(tcx, expr, pat_id, span);
|
||||
@ -714,21 +711,13 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
hir::ExprPath(..) => {
|
||||
let opt_def = if let Some(def) = tcx.def_map.borrow().get(&e.id) {
|
||||
// After type-checking, def_map contains definition of the
|
||||
// item referred to by the path. During type-checking, it
|
||||
// can contain the raw output of path resolution, which
|
||||
// might be a partially resolved path.
|
||||
// FIXME: There's probably a better way to make sure we don't
|
||||
// panic here.
|
||||
if def.depth != 0 {
|
||||
signal!(e, UnresolvedPath);
|
||||
}
|
||||
def.full_def()
|
||||
} else {
|
||||
signal!(e, NonConstPath);
|
||||
};
|
||||
match opt_def {
|
||||
// This function can be used before type checking when not all paths are fully resolved.
|
||||
// FIXME: There's probably a better way to make sure we don't panic here.
|
||||
let resolution = tcx.expect_resolution(e.id);
|
||||
if resolution.depth != 0 {
|
||||
signal!(e, UnresolvedPath);
|
||||
}
|
||||
match resolution.base_def {
|
||||
Def::Const(def_id) |
|
||||
Def::AssociatedConst(def_id) => {
|
||||
let substs = if let ExprTypeChecked = ty_hint {
|
||||
|
@ -276,7 +276,7 @@ impl LateLintPass for NonSnakeCase {
|
||||
fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
|
||||
if let &PatKind::Binding(_, ref path1, _) = &p.node {
|
||||
// Exclude parameter names from foreign functions (they have no `Def`)
|
||||
if cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def()).is_some() {
|
||||
if cx.tcx.expect_def_or_none(p.id).is_some() {
|
||||
self.check_snake_case(cx, "variable", &path1.node.as_str(), Some(p.span));
|
||||
}
|
||||
}
|
||||
@ -362,8 +362,7 @@ impl LateLintPass for NonUpperCaseGlobals {
|
||||
// Lint for constants that look like binding identifiers (#7526)
|
||||
if let PatKind::Path(ref path) = p.node {
|
||||
if !path.global && path.segments.len() == 1 && path.segments[0].parameters.is_empty() {
|
||||
if let Some(Def::Const(..)) = cx.tcx.def_map.borrow().get(&p.id)
|
||||
.map(|d| d.full_def()) {
|
||||
if let Def::Const(..) = cx.tcx.expect_def(p.id) {
|
||||
NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
|
||||
path.segments[0].name, path.span);
|
||||
}
|
||||
|
@ -157,20 +157,11 @@ impl LintPass for NonShorthandFieldPatterns {
|
||||
|
||||
impl LateLintPass for NonShorthandFieldPatterns {
|
||||
fn check_pat(&mut self, cx: &LateContext, pat: &hir::Pat) {
|
||||
let def_map = cx.tcx.def_map.borrow();
|
||||
if let PatKind::Struct(_, ref v, _) = pat.node {
|
||||
let field_pats = v.iter().filter(|fieldpat| {
|
||||
if fieldpat.node.is_shorthand {
|
||||
return false;
|
||||
}
|
||||
let def = def_map.get(&fieldpat.node.pat.id).map(|d| d.full_def());
|
||||
if let Some(def_id) = cx.tcx.map.opt_local_def_id(fieldpat.node.pat.id) {
|
||||
def == Some(Def::Local(def_id, fieldpat.node.pat.id))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
if let PatKind::Struct(_, ref field_pats, _) = pat.node {
|
||||
for fieldpat in field_pats {
|
||||
if fieldpat.node.is_shorthand {
|
||||
continue;
|
||||
}
|
||||
if let PatKind::Binding(_, ident, None) = fieldpat.node.pat.node {
|
||||
if ident.node.unhygienize() == fieldpat.node.name {
|
||||
cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span,
|
||||
@ -377,7 +368,7 @@ impl LateLintPass for MissingDoc {
|
||||
hir::ItemImpl(_, _, _, Some(ref trait_ref), _, ref impl_items) => {
|
||||
// If the trait is private, add the impl items to private_traits so they don't get
|
||||
// reported for missing docs.
|
||||
let real_trait = cx.tcx.trait_ref_to_def_id(trait_ref);
|
||||
let real_trait = cx.tcx.expect_def(trait_ref.ref_id).def_id();
|
||||
if let Some(node_id) = cx.tcx.map.as_local_node_id(real_trait) {
|
||||
match cx.tcx.map.find(node_id) {
|
||||
Some(hir_map::NodeItem(item)) => if item.vis == hir::Visibility::Inherited {
|
||||
@ -780,11 +771,9 @@ impl LateLintPass for UnconditionalRecursion {
|
||||
id: ast::NodeId) -> bool {
|
||||
match tcx.map.get(id) {
|
||||
hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => {
|
||||
tcx.def_map
|
||||
.borrow()
|
||||
.get(&callee.id)
|
||||
.map_or(false,
|
||||
|def| def.def_id() == tcx.map.local_def_id(fn_id))
|
||||
tcx.expect_def_or_none(callee.id).map_or(false, |def| {
|
||||
def.def_id() == tcx.map.local_def_id(fn_id)
|
||||
})
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
@ -820,7 +809,9 @@ impl LateLintPass for UnconditionalRecursion {
|
||||
// Check for calls to methods via explicit paths (e.g. `T::method()`).
|
||||
match tcx.map.get(id) {
|
||||
hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => {
|
||||
match tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def()) {
|
||||
// The callee is an arbitrary expression,
|
||||
// it doesn't necessarily have a definition.
|
||||
match tcx.expect_def_or_none(callee.id) {
|
||||
Some(Def::Method(def_id)) => {
|
||||
let item_substs = tcx.node_id_item_substs(callee.id);
|
||||
method_call_refers_to_method(
|
||||
@ -1057,7 +1048,7 @@ impl LateLintPass for MutableTransmutes {
|
||||
hir::ExprPath(..) => (),
|
||||
_ => return None
|
||||
}
|
||||
if let Def::Fn(did) = cx.tcx.resolve_expr(expr) {
|
||||
if let Def::Fn(did) = cx.tcx.expect_def(expr.id) {
|
||||
if !def_id_is_transmute(cx, did) {
|
||||
return None;
|
||||
}
|
||||
|
@ -719,7 +719,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
||||
|
||||
debug!("Encoding side tables for id {}", id);
|
||||
|
||||
if let Some(def) = tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
|
||||
if let Some(def) = tcx.expect_def_or_none(id) {
|
||||
rbml_w.tag(c::tag_table_def, |rbml_w| {
|
||||
rbml_w.id(id);
|
||||
def.encode(rbml_w).unwrap();
|
||||
@ -1133,10 +1133,7 @@ fn decode_side_tables(dcx: &DecodeContext,
|
||||
match value {
|
||||
c::tag_table_def => {
|
||||
let def = decode_def(dcx, val_dsr);
|
||||
dcx.tcx.def_map.borrow_mut().insert(id, def::PathResolution {
|
||||
base_def: def,
|
||||
depth: 0
|
||||
});
|
||||
dcx.tcx.def_map.borrow_mut().insert(id, def::PathResolution::new(def));
|
||||
}
|
||||
c::tag_table_node_type => {
|
||||
let ty = val_dsr.read_ty(dcx);
|
||||
|
@ -9,7 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
use hair::*;
|
||||
use rustc_data_structures::fnv::FnvHashMap;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use rustc_const_math::ConstInt;
|
||||
use hair::cx::Cx;
|
||||
@ -20,7 +19,6 @@ use rustc::hir::def::Def;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc_const_eval as const_eval;
|
||||
use rustc::middle::region::CodeExtent;
|
||||
use rustc::hir::pat_util;
|
||||
use rustc::ty::{self, VariantDef, Ty};
|
||||
use rustc::ty::cast::CastKind as TyCastKind;
|
||||
use rustc::mir::repr::*;
|
||||
@ -264,7 +262,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
let adt_data = if let hir::ExprPath(..) = fun.node {
|
||||
// Tuple-like ADTs are represented as ExprCall. We convert them here.
|
||||
expr_ty.ty_adt_def().and_then(|adt_def|{
|
||||
match cx.tcx.def_map.borrow()[&fun.id].full_def() {
|
||||
match cx.tcx.expect_def(fun.id) {
|
||||
Def::Variant(_, variant_id) => {
|
||||
Some((adt_def, adt_def.variant_index_with_id(variant_id)))
|
||||
},
|
||||
@ -472,7 +470,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
ty::TyEnum(adt, substs) => {
|
||||
match cx.tcx.def_map.borrow()[&expr.id].full_def() {
|
||||
match cx.tcx.expect_def(expr.id) {
|
||||
Def::Variant(enum_id, variant_id) => {
|
||||
debug_assert!(adt.did == enum_id);
|
||||
assert!(base.is_none());
|
||||
@ -652,19 +650,8 @@ fn to_borrow_kind(m: hir::Mutability) -> BorrowKind {
|
||||
|
||||
fn convert_arm<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
arm: &'tcx hir::Arm) -> Arm<'tcx> {
|
||||
let mut map;
|
||||
let opt_map = if arm.pats.len() == 1 {
|
||||
None
|
||||
} else {
|
||||
map = FnvHashMap();
|
||||
pat_util::pat_bindings(&arm.pats[0], |_, p_id, _, path| {
|
||||
map.insert(path.node, p_id);
|
||||
});
|
||||
Some(&map)
|
||||
};
|
||||
|
||||
Arm {
|
||||
patterns: arm.pats.iter().map(|p| cx.refutable_pat(opt_map, p)).collect(),
|
||||
patterns: arm.pats.iter().map(|p| cx.refutable_pat(p)).collect(),
|
||||
guard: arm.guard.to_ref(),
|
||||
body: arm.body.to_ref(),
|
||||
}
|
||||
@ -675,7 +662,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
-> ExprKind<'tcx> {
|
||||
let substs = cx.tcx.node_id_item_substs(expr.id).substs;
|
||||
// Otherwise there may be def_map borrow conflicts
|
||||
let def = cx.tcx.def_map.borrow()[&expr.id].full_def();
|
||||
let def = cx.tcx.expect_def(expr.id);
|
||||
let def_id = match def {
|
||||
// A regular function.
|
||||
Def::Fn(def_id) | Def::Method(def_id) => def_id,
|
||||
@ -731,14 +718,9 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
id: node_id,
|
||||
},
|
||||
|
||||
def @ Def::Local(..) |
|
||||
def @ Def::Upvar(..) => return convert_var(cx, expr, def),
|
||||
Def::Local(..) | Def::Upvar(..) => return convert_var(cx, expr, def),
|
||||
|
||||
def =>
|
||||
span_bug!(
|
||||
expr.span,
|
||||
"def `{:?}` not yet implemented",
|
||||
def),
|
||||
_ => span_bug!(expr.span, "def `{:?}` not yet implemented", def),
|
||||
};
|
||||
ExprKind::Literal {
|
||||
literal: Literal::Item { def_id: def_id, substs: substs }
|
||||
@ -1039,11 +1021,9 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
|
||||
fn loop_label<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
expr: &'tcx hir::Expr) -> CodeExtent {
|
||||
match cx.tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()) {
|
||||
Some(Def::Label(loop_id)) => cx.tcx.region_maps.node_extent(loop_id),
|
||||
d => {
|
||||
span_bug!(expr.span, "loop scope resolved to {:?}", d);
|
||||
}
|
||||
match cx.tcx.expect_def(expr.id) {
|
||||
Def::Label(loop_id) => cx.tcx.region_maps.node_extent(loop_id),
|
||||
d => span_bug!(expr.span, "loop scope resolved to {:?}", d),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
use hair::*;
|
||||
use hair::cx::Cx;
|
||||
use rustc_data_structures::fnv::FnvHashMap;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use rustc_const_eval as const_eval;
|
||||
use rustc::hir::def::Def;
|
||||
@ -18,7 +17,6 @@ use rustc::hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::hir::{self, PatKind};
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::ptr::P;
|
||||
|
||||
@ -37,29 +35,25 @@ use syntax::ptr::P;
|
||||
/// ```
|
||||
struct PatCx<'patcx, 'cx: 'patcx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
|
||||
cx: &'patcx mut Cx<'cx, 'gcx, 'tcx>,
|
||||
binding_map: Option<&'patcx FnvHashMap<ast::Name, ast::NodeId>>,
|
||||
}
|
||||
|
||||
impl<'cx, 'gcx, 'tcx> Cx<'cx, 'gcx, 'tcx> {
|
||||
pub fn irrefutable_pat(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
|
||||
PatCx::new(self, None).to_pattern(pat)
|
||||
PatCx::new(self).to_pattern(pat)
|
||||
}
|
||||
|
||||
pub fn refutable_pat(&mut self,
|
||||
binding_map: Option<&FnvHashMap<ast::Name, ast::NodeId>>,
|
||||
pat: &hir::Pat)
|
||||
-> Pattern<'tcx> {
|
||||
PatCx::new(self, binding_map).to_pattern(pat)
|
||||
PatCx::new(self).to_pattern(pat)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
|
||||
fn new(cx: &'patcx mut Cx<'cx, 'gcx, 'tcx>,
|
||||
binding_map: Option<&'patcx FnvHashMap<ast::Name, ast::NodeId>>)
|
||||
fn new(cx: &'patcx mut Cx<'cx, 'gcx, 'tcx>)
|
||||
-> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
|
||||
PatCx {
|
||||
cx: cx,
|
||||
binding_map: binding_map,
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,8 +79,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
|
||||
PatKind::Path(..) | PatKind::QPath(..)
|
||||
if pat_is_resolved_const(&self.cx.tcx.def_map.borrow(), pat) =>
|
||||
{
|
||||
let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
|
||||
match def {
|
||||
match self.cx.tcx.expect_def(pat.id) {
|
||||
Def::Const(def_id) | Def::AssociatedConst(def_id) => {
|
||||
let tcx = self.cx.tcx.global_tcx();
|
||||
let substs = Some(self.cx.tcx.node_id_item_substs(pat.id).substs);
|
||||
@ -111,7 +104,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
_ =>
|
||||
def =>
|
||||
span_bug!(
|
||||
pat.span,
|
||||
"def not a constant: {:?}",
|
||||
@ -169,10 +162,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
PatKind::Binding(bm, ref ident, ref sub) => {
|
||||
let id = match self.binding_map {
|
||||
None => pat.id,
|
||||
Some(ref map) => map[&ident.node],
|
||||
};
|
||||
let id = self.cx.tcx.expect_def(pat.id).var_id();
|
||||
let var_ty = self.cx.tcx.node_id_to_type(pat.id);
|
||||
let region = match var_ty.sty {
|
||||
ty::TyRef(&r, _) => Some(r),
|
||||
@ -219,8 +209,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
|
||||
ty::TyStruct(adt_def, _) | ty::TyEnum(adt_def, _) => adt_def,
|
||||
_ => span_bug!(pat.span, "tuple struct pattern not applied to struct or enum"),
|
||||
};
|
||||
let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
|
||||
let variant_def = adt_def.variant_of_def(def);
|
||||
let variant_def = adt_def.variant_of_def(self.cx.tcx.expect_def(pat.id));
|
||||
|
||||
let subpatterns =
|
||||
subpatterns.iter()
|
||||
@ -243,9 +232,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
|
||||
"struct pattern not applied to struct or enum");
|
||||
}
|
||||
};
|
||||
|
||||
let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
|
||||
let variant_def = adt_def.variant_of_def(def);
|
||||
let variant_def = adt_def.variant_of_def(self.cx.tcx.expect_def(pat.id));
|
||||
|
||||
let subpatterns =
|
||||
fields.iter()
|
||||
@ -324,8 +311,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
|
||||
pat: &hir::Pat,
|
||||
subpatterns: Vec<FieldPattern<'tcx>>)
|
||||
-> PatternKind<'tcx> {
|
||||
let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
|
||||
match def {
|
||||
match self.cx.tcx.expect_def(pat.id) {
|
||||
Def::Variant(enum_id, variant_id) => {
|
||||
let adt_def = self.cx.tcx.lookup_adt_def(enum_id);
|
||||
if adt_def.variants.len() > 1 {
|
||||
@ -343,7 +329,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
|
||||
PatternKind::Leaf { subpatterns: subpatterns }
|
||||
}
|
||||
|
||||
_ => {
|
||||
def => {
|
||||
span_bug!(pat.span, "inappropriate def for pattern: {:?}", def);
|
||||
}
|
||||
}
|
||||
|
@ -499,38 +499,36 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
hir::ExprPath(..) => {
|
||||
let def = v.tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
|
||||
match def {
|
||||
Some(Def::Variant(..)) => {
|
||||
match v.tcx.expect_def(e.id) {
|
||||
Def::Variant(..) => {
|
||||
// Count the discriminator or function pointer.
|
||||
v.add_qualif(ConstQualif::NON_ZERO_SIZED);
|
||||
}
|
||||
Some(Def::Struct(..)) => {
|
||||
Def::Struct(..) => {
|
||||
if let ty::TyFnDef(..) = node_ty.sty {
|
||||
// Count the function pointer.
|
||||
v.add_qualif(ConstQualif::NON_ZERO_SIZED);
|
||||
}
|
||||
}
|
||||
Some(Def::Fn(..)) | Some(Def::Method(..)) => {
|
||||
Def::Fn(..) | Def::Method(..) => {
|
||||
// Count the function pointer.
|
||||
v.add_qualif(ConstQualif::NON_ZERO_SIZED);
|
||||
}
|
||||
Some(Def::Static(..)) => {
|
||||
Def::Static(..) => {
|
||||
match v.mode {
|
||||
Mode::Static | Mode::StaticMut => {}
|
||||
Mode::Const | Mode::ConstFn => {}
|
||||
Mode::Var => v.add_qualif(ConstQualif::NOT_CONST)
|
||||
}
|
||||
}
|
||||
Some(Def::Const(did)) |
|
||||
Some(Def::AssociatedConst(did)) => {
|
||||
Def::Const(did) | Def::AssociatedConst(did) => {
|
||||
let substs = Some(v.tcx.node_id_item_substs(e.id).substs);
|
||||
if let Some((expr, _)) = lookup_const_by_id(v.tcx, did, substs) {
|
||||
let inner = v.global_expr(Mode::Const, expr);
|
||||
v.add_qualif(inner);
|
||||
}
|
||||
}
|
||||
Some(Def::Local(..)) if v.mode == Mode::ConstFn => {
|
||||
Def::Local(..) if v.mode == Mode::ConstFn => {
|
||||
// Sadly, we can't determine whether the types are zero-sized.
|
||||
v.add_qualif(ConstQualif::NOT_CONST | ConstQualif::NON_ZERO_SIZED);
|
||||
}
|
||||
@ -550,8 +548,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
||||
_ => break
|
||||
};
|
||||
}
|
||||
let def = v.tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def());
|
||||
let is_const = match def {
|
||||
// The callee is an arbitrary expression, it doesn't necessarily have a definition.
|
||||
let is_const = match v.tcx.expect_def_or_none(callee.id) {
|
||||
Some(Def::Struct(..)) => true,
|
||||
Some(Def::Variant(..)) => {
|
||||
// Count the discriminator.
|
||||
@ -586,8 +584,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
hir::ExprStruct(..) => {
|
||||
let did = v.tcx.def_map.borrow().get(&e.id).map(|def| def.def_id());
|
||||
if did == v.tcx.lang_items.unsafe_cell_type() {
|
||||
// unsafe_cell_type doesn't necessarily exist with no_core
|
||||
if Some(v.tcx.expect_def(e.id).def_id()) == v.tcx.lang_items.unsafe_cell_type() {
|
||||
v.add_qualif(ConstQualif::MUTABLE_MEM);
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ struct ReachEverythingInTheInterfaceVisitor<'b, 'a: 'b, 'tcx: 'a> {
|
||||
impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
|
||||
fn ty_level(&self, ty: &hir::Ty) -> Option<AccessLevel> {
|
||||
if let hir::TyPath(..) = ty.node {
|
||||
match self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def() {
|
||||
match self.tcx.expect_def(ty.id) {
|
||||
Def::PrimTy(..) | Def::SelfTy(..) | Def::TyParam(..) => {
|
||||
Some(AccessLevel::Public)
|
||||
}
|
||||
@ -83,7 +83,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn trait_level(&self, trait_ref: &hir::TraitRef) -> Option<AccessLevel> {
|
||||
let did = self.tcx.trait_ref_to_def_id(trait_ref);
|
||||
let did = self.tcx.expect_def(trait_ref.ref_id).def_id();
|
||||
if let Some(node_id) = self.tcx.map.as_local_node_id(did) {
|
||||
self.get(node_id)
|
||||
} else {
|
||||
@ -317,7 +317,7 @@ impl<'b, 'a, 'tcx: 'a> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
|
||||
impl<'b, 'a, 'tcx: 'a, 'v> Visitor<'v> for ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
|
||||
fn visit_ty(&mut self, ty: &hir::Ty) {
|
||||
if let hir::TyPath(_, ref path) = ty.node {
|
||||
let def = self.ev.tcx.def_map.borrow().get(&ty.id).unwrap().full_def();
|
||||
let def = self.ev.tcx.expect_def(ty.id);
|
||||
match def {
|
||||
Def::Struct(def_id) | Def::Enum(def_id) | Def::TyAlias(def_id) |
|
||||
Def::Trait(def_id) | Def::AssociatedTy(def_id, _) => {
|
||||
@ -343,7 +343,7 @@ impl<'b, 'a, 'tcx: 'a, 'v> Visitor<'v> for ReachEverythingInTheInterfaceVisitor<
|
||||
}
|
||||
|
||||
fn visit_trait_ref(&mut self, trait_ref: &hir::TraitRef) {
|
||||
let def_id = self.ev.tcx.trait_ref_to_def_id(trait_ref);
|
||||
let def_id = self.ev.tcx.expect_def(trait_ref.ref_id).def_id();
|
||||
if let Some(node_id) = self.ev.tcx.map.as_local_node_id(def_id) {
|
||||
let item = self.ev.tcx.map.expect_item(node_id);
|
||||
self.ev.update(item.id, Some(AccessLevel::Reachable));
|
||||
@ -426,7 +426,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
||||
}
|
||||
hir::ExprStruct(..) => {
|
||||
let adt = self.tcx.expr_ty(expr).ty_adt_def().unwrap();
|
||||
let variant = adt.variant_of_def(self.tcx.resolve_expr(expr));
|
||||
let variant = adt.variant_of_def(self.tcx.expect_def(expr.id));
|
||||
// RFC 736: ensure all unmentioned fields are visible.
|
||||
// Rather than computing the set of unmentioned fields
|
||||
// (i.e. `all_fields - fields`), just check them all.
|
||||
@ -436,7 +436,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
||||
}
|
||||
hir::ExprPath(..) => {
|
||||
|
||||
if let Def::Struct(..) = self.tcx.resolve_expr(expr) {
|
||||
if let Def::Struct(..) = self.tcx.expect_def(expr.id) {
|
||||
let expr_ty = self.tcx.expr_ty(expr);
|
||||
let def = match expr_ty.sty {
|
||||
ty::TyFnDef(_, _, &ty::BareFnTy { sig: ty::Binder(ty::FnSig {
|
||||
@ -470,8 +470,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
||||
match pattern.node {
|
||||
PatKind::Struct(_, ref fields, _) => {
|
||||
let adt = self.tcx.pat_ty(pattern).ty_adt_def().unwrap();
|
||||
let def = self.tcx.def_map.borrow().get(&pattern.id).unwrap().full_def();
|
||||
let variant = adt.variant_of_def(def);
|
||||
let variant = adt.variant_of_def(self.tcx.expect_def(pattern.id));
|
||||
for field in fields {
|
||||
self.check_field(pattern.span, adt, variant.field_named(field.node.name));
|
||||
}
|
||||
@ -534,10 +533,9 @@ struct ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b: 'a, 'tcx: 'b> {
|
||||
|
||||
impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||
fn path_is_private_type(&self, path_id: ast::NodeId) -> bool {
|
||||
let did = match self.tcx.def_map.borrow().get(&path_id).map(|d| d.full_def()) {
|
||||
// `int` etc. (None doesn't seem to occur.)
|
||||
None | Some(Def::PrimTy(..)) | Some(Def::SelfTy(..)) => return false,
|
||||
Some(def) => def.def_id(),
|
||||
let did = match self.tcx.expect_def(path_id) {
|
||||
Def::PrimTy(..) | Def::SelfTy(..) => return false,
|
||||
def => def.def_id(),
|
||||
};
|
||||
|
||||
// A path can only be private if:
|
||||
@ -653,7 +651,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx>
|
||||
let not_private_trait =
|
||||
trait_ref.as_ref().map_or(true, // no trait counts as public trait
|
||||
|tr| {
|
||||
let did = self.tcx.trait_ref_to_def_id(tr);
|
||||
let did = self.tcx.expect_def(tr.ref_id).def_id();
|
||||
|
||||
if let Some(node_id) = self.tcx.map.as_local_node_id(did) {
|
||||
self.trait_is_public(node_id)
|
||||
@ -911,8 +909,7 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
|
||||
impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
|
||||
fn visit_ty(&mut self, ty: &hir::Ty) {
|
||||
if let hir::TyPath(_, ref path) = ty.node {
|
||||
let def = self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def();
|
||||
match def {
|
||||
match self.tcx.expect_def(ty.id) {
|
||||
Def::PrimTy(..) | Def::SelfTy(..) | Def::TyParam(..) => {
|
||||
// Public
|
||||
}
|
||||
@ -962,7 +959,7 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a,
|
||||
|
||||
fn visit_trait_ref(&mut self, trait_ref: &hir::TraitRef) {
|
||||
// Non-local means public (private items can't leave their crate, modulo bugs)
|
||||
let def_id = self.tcx.trait_ref_to_def_id(trait_ref);
|
||||
let def_id = self.tcx.expect_def(trait_ref.ref_id).def_id();
|
||||
if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) {
|
||||
let item = self.tcx.map.expect_item(node_id);
|
||||
let vis = ty::Visibility::from_hir(&item.vis, node_id, self.tcx);
|
||||
|
@ -677,100 +677,6 @@ fn foo<T>(x: T) {} // ok!
|
||||
```
|
||||
"##,
|
||||
|
||||
E0413: r##"
|
||||
A declaration shadows an enum variant or unit-like struct in scope. Example of
|
||||
erroneous code:
|
||||
|
||||
```compile_fail
|
||||
struct Foo;
|
||||
|
||||
let Foo = 12i32; // error: declaration of `Foo` shadows an enum variant or
|
||||
// unit-like struct in scope
|
||||
```
|
||||
|
||||
To fix this error, rename the variable such that it doesn't shadow any enum
|
||||
variable or structure in scope. Example:
|
||||
|
||||
```
|
||||
struct Foo;
|
||||
|
||||
let foo = 12i32; // ok!
|
||||
```
|
||||
|
||||
Or:
|
||||
|
||||
```
|
||||
struct FooStruct;
|
||||
|
||||
let Foo = 12i32; // ok!
|
||||
```
|
||||
|
||||
The goal here is to avoid a conflict of names.
|
||||
"##,
|
||||
|
||||
E0414: r##"
|
||||
A variable binding in an irrefutable pattern is shadowing the name of a
|
||||
constant. Example of erroneous code:
|
||||
|
||||
```compile_fail
|
||||
const FOO: u8 = 7;
|
||||
|
||||
let FOO = 5; // error: variable bindings cannot shadow constants
|
||||
|
||||
// or
|
||||
|
||||
fn bar(FOO: u8) { // error: variable bindings cannot shadow constants
|
||||
|
||||
}
|
||||
|
||||
// or
|
||||
|
||||
for FOO in bar {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Introducing a new variable in Rust is done through a pattern. Thus you can have
|
||||
`let` bindings like `let (a, b) = ...`. However, patterns also allow constants
|
||||
in them, e.g. if you want to match over a constant:
|
||||
|
||||
```ignore
|
||||
const FOO: u8 = 1;
|
||||
|
||||
match (x,y) {
|
||||
(3, 4) => { .. }, // it is (3,4)
|
||||
(FOO, 1) => { .. }, // it is (1,1)
|
||||
(foo, 1) => { .. }, // it is (anything, 1)
|
||||
// call the value in the first slot "foo"
|
||||
_ => { .. } // it is anything
|
||||
}
|
||||
```
|
||||
|
||||
Here, the second arm matches the value of `x` against the constant `FOO`,
|
||||
whereas the third arm will accept any value of `x` and call it `foo`.
|
||||
|
||||
This works for `match`, however in cases where an irrefutable pattern is
|
||||
required, constants can't be used. An irrefutable pattern is one which always
|
||||
matches, whose purpose is only to bind variable names to values. These are
|
||||
required by let, for, and function argument patterns.
|
||||
|
||||
Refutable patterns in such a situation do not make sense, for example:
|
||||
|
||||
```ignore
|
||||
let Some(x) = foo; // what if foo is None, instead?
|
||||
|
||||
let (1, x) = foo; // what if foo.0 is not 1?
|
||||
|
||||
let (SOME_CONST, x) = foo; // what if foo.0 is not SOME_CONST?
|
||||
|
||||
let SOME_CONST = foo; // what if foo is not SOME_CONST?
|
||||
```
|
||||
|
||||
Thus, an irrefutable variable binding can't contain a constant.
|
||||
|
||||
To fix this error, just give the marked variable a different name.
|
||||
"##,
|
||||
|
||||
E0415: r##"
|
||||
More than one function parameter have the same name. Example of erroneous code:
|
||||
|
||||
@ -814,60 +720,6 @@ match (A, B, C) {
|
||||
```
|
||||
"##,
|
||||
|
||||
E0417: r##"
|
||||
A static variable was referenced in a pattern. Example of erroneous code:
|
||||
|
||||
```compile_fail
|
||||
static FOO : i32 = 0;
|
||||
|
||||
match 0 {
|
||||
FOO => {} // error: static variables cannot be referenced in a
|
||||
// pattern, use a `const` instead
|
||||
_ => {}
|
||||
}
|
||||
```
|
||||
|
||||
The compiler needs to know the value of the pattern at compile time;
|
||||
compile-time patterns can defined via const or enum items. Please verify
|
||||
that the identifier is spelled correctly, and if so, use a const instead
|
||||
of static to define it. Example:
|
||||
|
||||
```
|
||||
const FOO : i32 = 0;
|
||||
|
||||
match 0 {
|
||||
FOO => {} // ok!
|
||||
_ => {}
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0419: r##"
|
||||
An unknown enum variant, struct or const was used. Example of erroneous code:
|
||||
|
||||
```compile_fail
|
||||
match 0 {
|
||||
Something::Foo => {} // error: unresolved enum variant, struct
|
||||
// or const `Foo`
|
||||
}
|
||||
```
|
||||
|
||||
Please verify you didn't misspell it and the enum variant, struct or const has
|
||||
been declared and imported into scope. Example:
|
||||
|
||||
```
|
||||
enum Something {
|
||||
Foo,
|
||||
NotFoo,
|
||||
}
|
||||
|
||||
match Something::NotFoo {
|
||||
Something::Foo => {} // ok!
|
||||
_ => {}
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0422: r##"
|
||||
You are trying to use an identifier that is either undefined or not a struct.
|
||||
For instance:
|
||||
@ -1255,8 +1107,15 @@ register_diagnostics! {
|
||||
E0402, // cannot use an outer type parameter in this context
|
||||
E0406, // undeclared associated type
|
||||
// E0410, merged into 408
|
||||
E0418, // is not an enum variant, struct or const
|
||||
E0420, // is not an associated const
|
||||
E0421, // unresolved associated const
|
||||
E0427, // cannot use `ref` binding mode with ...
|
||||
// E0413, merged into 530
|
||||
// E0414, merged into 530
|
||||
// E0417, merged into 532
|
||||
// E0418, merged into 532
|
||||
// E0419, merged into 531
|
||||
// E0420, merged into 532
|
||||
// E0421, merged into 531
|
||||
E0530, // X bindings cannot shadow Ys
|
||||
E0531, // unresolved pattern path kind `name`
|
||||
E0532, // expected pattern path kind, found another pattern path kind
|
||||
// E0427, merged into 530
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -598,7 +598,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||
Some(def) => def,
|
||||
None => value_result.success().and_then(NameBinding::def).unwrap(),
|
||||
};
|
||||
let path_resolution = PathResolution { base_def: def, depth: 0 };
|
||||
let path_resolution = PathResolution::new(def);
|
||||
self.resolver.def_map.insert(directive.id, path_resolution);
|
||||
|
||||
debug!("(resolving single import) successfully resolved import");
|
||||
@ -644,7 +644,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||
|
||||
// Record the destination of this import
|
||||
if let Some(did) = target_module.def_id() {
|
||||
let resolution = PathResolution { base_def: Def::Mod(did), depth: 0 };
|
||||
let resolution = PathResolution::new(Def::Mod(did));
|
||||
self.resolver.def_map.insert(directive.id, resolution);
|
||||
}
|
||||
|
||||
|
@ -269,14 +269,10 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||
|
||||
// looks up anything, not just a type
|
||||
fn lookup_type_ref(&self, ref_id: NodeId) -> Option<DefId> {
|
||||
if !self.tcx.def_map.borrow().contains_key(&ref_id) {
|
||||
bug!("def_map has no key for {} in lookup_type_ref", ref_id);
|
||||
}
|
||||
let def = self.tcx.def_map.borrow().get(&ref_id).unwrap().full_def();
|
||||
match def {
|
||||
match self.tcx.expect_def(ref_id) {
|
||||
Def::PrimTy(..) => None,
|
||||
Def::SelfTy(..) => None,
|
||||
_ => Some(def.def_id()),
|
||||
def => Some(def.def_id()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,13 +286,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||
return;
|
||||
}
|
||||
|
||||
let def_map = self.tcx.def_map.borrow();
|
||||
if !def_map.contains_key(&ref_id) {
|
||||
span_bug!(span,
|
||||
"def_map has no key for {} in lookup_def_kind",
|
||||
ref_id);
|
||||
}
|
||||
let def = def_map.get(&ref_id).unwrap().full_def();
|
||||
let def = self.tcx.expect_def(ref_id);
|
||||
match def {
|
||||
Def::Mod(_) |
|
||||
Def::ForeignMod(_) => {
|
||||
@ -853,9 +843,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||
}
|
||||
|
||||
// Modules or types in the path prefix.
|
||||
let def_map = self.tcx.def_map.borrow();
|
||||
let def = def_map.get(&id).unwrap().full_def();
|
||||
match def {
|
||||
match self.tcx.expect_def(id) {
|
||||
Def::Method(did) => {
|
||||
let ti = self.tcx.impl_or_trait_item(did);
|
||||
if let ty::MethodTraitItem(m) = ti {
|
||||
@ -924,8 +912,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||
PatKind::Struct(ref path, ref fields, _) => {
|
||||
visit::walk_path(self, path);
|
||||
let adt = self.tcx.node_id_to_type(p.id).ty_adt_def().unwrap();
|
||||
let def = self.tcx.def_map.borrow()[&p.id].full_def();
|
||||
let variant = adt.variant_of_def(def);
|
||||
let variant = adt.variant_of_def(self.tcx.expect_def(p.id));
|
||||
|
||||
for &Spanned { node: ref field, span } in fields {
|
||||
let sub_span = self.span.span_for_first_ident(span);
|
||||
@ -1269,7 +1256,7 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx,
|
||||
ast::ExprKind::Struct(ref path, ref fields, ref base) => {
|
||||
let hir_expr = self.save_ctxt.tcx.map.expect_expr(ex.id);
|
||||
let adt = self.tcx.expr_ty(&hir_expr).ty_adt_def().unwrap();
|
||||
let def = self.tcx.resolve_expr(&hir_expr);
|
||||
let def = self.tcx.expect_def(hir_expr.id);
|
||||
self.process_struct_lit(ex, path, fields, adt.variant_of_def(def), base)
|
||||
}
|
||||
ast::ExprKind::MethodCall(_, _, ref args) => self.process_method_call(ex, args),
|
||||
@ -1366,12 +1353,7 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx,
|
||||
|
||||
// process collected paths
|
||||
for &(id, ref p, immut, ref_kind) in &collector.collected_paths {
|
||||
let def_map = self.tcx.def_map.borrow();
|
||||
if !def_map.contains_key(&id) {
|
||||
span_bug!(p.span, "def_map has no key for {} in visit_arm", id);
|
||||
}
|
||||
let def = def_map.get(&id).unwrap().full_def();
|
||||
match def {
|
||||
match self.tcx.expect_def(id) {
|
||||
Def::Local(_, id) => {
|
||||
let value = if immut == ast::Mutability::Immutable {
|
||||
self.span.snippet(p.span).to_string()
|
||||
@ -1401,8 +1383,8 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx,
|
||||
Def::Static(_, _) |
|
||||
Def::Const(..) |
|
||||
Def::AssociatedConst(..) => {}
|
||||
_ => error!("unexpected definition kind when processing collected paths: {:?}",
|
||||
def),
|
||||
def => error!("unexpected definition kind when processing collected paths: {:?}",
|
||||
def),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -465,11 +465,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option<Data> {
|
||||
let def_map = self.tcx.def_map.borrow();
|
||||
if !def_map.contains_key(&id) {
|
||||
span_bug!(path.span, "def_map has no key for {} in visit_expr", id);
|
||||
}
|
||||
let def = def_map.get(&id).unwrap().full_def();
|
||||
let def = self.tcx.expect_def(id);
|
||||
let sub_span = self.span_utils.span_for_last_ident(path.span);
|
||||
filter!(self.span_utils, sub_span, path.span, None);
|
||||
match def {
|
||||
@ -637,13 +633,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||
}
|
||||
|
||||
fn lookup_ref_id(&self, ref_id: NodeId) -> Option<DefId> {
|
||||
if !self.tcx.def_map.borrow().contains_key(&ref_id) {
|
||||
bug!("def_map has no key for {} in lookup_type_ref", ref_id);
|
||||
}
|
||||
let def = self.tcx.def_map.borrow().get(&ref_id).unwrap().full_def();
|
||||
match def {
|
||||
match self.tcx.expect_def(ref_id) {
|
||||
Def::PrimTy(_) | Def::SelfTy(..) => None,
|
||||
_ => Some(def.def_id()),
|
||||
def => Some(def.def_id()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -657,9 +657,8 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
ConstantValue(ConstantExpr(&l), debug_loc)
|
||||
}
|
||||
PatKind::Path(..) | PatKind::TupleStruct(..) | PatKind::Struct(..) => {
|
||||
let opt_def = tcx.def_map.borrow().get(&cur.id).map(|d| d.full_def());
|
||||
match opt_def {
|
||||
Some(Def::Variant(enum_id, var_id)) => {
|
||||
match tcx.expect_def(cur.id) {
|
||||
Def::Variant(enum_id, var_id) => {
|
||||
let variant = tcx.lookup_adt_def(enum_id).variant_with_id(var_id);
|
||||
Variant(Disr::from(variant.disr_val),
|
||||
adt::represent_node(bcx, cur.id),
|
||||
@ -796,7 +795,7 @@ fn any_irrefutable_adt_pat(tcx: TyCtxt, m: &[Match], col: usize) -> bool {
|
||||
match pat.node {
|
||||
PatKind::Tuple(..) => true,
|
||||
PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) => {
|
||||
match tcx.def_map.borrow().get(&pat.id).unwrap().full_def() {
|
||||
match tcx.expect_def(pat.id) {
|
||||
Def::Struct(..) | Def::TyAlias(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
@ -1444,19 +1443,19 @@ pub fn trans_match<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
/// Checks whether the binding in `discr` is assigned to anywhere in the expression `body`
|
||||
fn is_discr_reassigned(bcx: Block, discr: &hir::Expr, body: &hir::Expr) -> bool {
|
||||
let (vid, field) = match discr.node {
|
||||
hir::ExprPath(..) => match bcx.def(discr.id) {
|
||||
hir::ExprPath(..) => match bcx.tcx().expect_def(discr.id) {
|
||||
Def::Local(_, vid) | Def::Upvar(_, vid, _, _) => (vid, None),
|
||||
_ => return false
|
||||
},
|
||||
hir::ExprField(ref base, field) => {
|
||||
let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) {
|
||||
let vid = match bcx.tcx().expect_def_or_none(base.id) {
|
||||
Some(Def::Local(_, vid)) | Some(Def::Upvar(_, vid, _, _)) => vid,
|
||||
_ => return false
|
||||
};
|
||||
(vid, Some(mc::NamedField(field.node)))
|
||||
},
|
||||
hir::ExprTupField(ref base, field) => {
|
||||
let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) {
|
||||
let vid = match bcx.tcx().expect_def_or_none(base.id) {
|
||||
Some(Def::Local(_, vid)) | Some(Def::Upvar(_, vid, _, _)) => vid,
|
||||
_ => return false
|
||||
};
|
||||
@ -1835,9 +1834,8 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
}
|
||||
}
|
||||
PatKind::TupleStruct(_, ref sub_pats, ddpos) => {
|
||||
let opt_def = bcx.tcx().def_map.borrow().get(&pat.id).map(|d| d.full_def());
|
||||
match opt_def {
|
||||
Some(Def::Variant(enum_id, var_id)) => {
|
||||
match bcx.tcx().expect_def(pat.id) {
|
||||
Def::Variant(enum_id, var_id) => {
|
||||
let repr = adt::represent_node(bcx, pat.id);
|
||||
let vinfo = ccx.tcx().lookup_adt_def(enum_id).variant_with_id(var_id);
|
||||
let args = extract_variant_args(bcx,
|
||||
@ -1853,7 +1851,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
cleanup_scope);
|
||||
}
|
||||
}
|
||||
Some(Def::Struct(..)) => {
|
||||
Def::Struct(..) => {
|
||||
let expected_len = match *ccx.tcx().pat_ty(&pat) {
|
||||
ty::TyS{sty: ty::TyStruct(adt_def, _), ..} => {
|
||||
adt_def.struct_variant().fields.len()
|
||||
|
@ -260,8 +260,7 @@ impl<'a, 'tcx> VariantInfo<'tcx> {
|
||||
|
||||
/// Return the variant corresponding to a given node (e.g. expr)
|
||||
pub fn of_node(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>, id: ast::NodeId) -> Self {
|
||||
let node_def = tcx.def_map.borrow().get(&id).map(|v| v.full_def());
|
||||
Self::from_ty(tcx, ty, node_def)
|
||||
Self::from_ty(tcx, ty, Some(tcx.expect_def(id)))
|
||||
}
|
||||
|
||||
pub fn field_index(&self, name: ast::Name) -> usize {
|
||||
@ -656,15 +655,6 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
|
||||
self.tcx().map.node_to_string(id).to_string()
|
||||
}
|
||||
|
||||
pub fn def(&self, nid: ast::NodeId) -> Def {
|
||||
match self.tcx().def_map.borrow().get(&nid) {
|
||||
Some(v) => v.full_def(),
|
||||
None => {
|
||||
bug!("no def associated with node id {}", nid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_str(&self) -> String {
|
||||
format!("[block {:p}]", self)
|
||||
}
|
||||
|
@ -297,8 +297,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
// `def` must be its own statement and cannot be in the `match`
|
||||
// otherwise the `def_map` will be borrowed for the entire match instead
|
||||
// of just to get the `def` value
|
||||
let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
|
||||
match def {
|
||||
match ccx.tcx().expect_def(expr.id) {
|
||||
Def::Const(def_id) | Def::AssociatedConst(def_id) => {
|
||||
if !ccx.tcx().tables.borrow().adjustments.contains_key(&expr.id) {
|
||||
debug!("get_const_expr_as_global ({:?}): found const {:?}",
|
||||
@ -803,8 +802,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
let opt_def = cx.tcx().def_map.borrow().get(&cur.id).map(|d| d.full_def());
|
||||
if let Some(Def::Static(def_id, _)) = opt_def {
|
||||
if let Some(Def::Static(def_id, _)) = cx.tcx().expect_def_or_none(cur.id) {
|
||||
get_static(cx, def_id).val
|
||||
} else {
|
||||
// If this isn't the address of a static, then keep going through
|
||||
@ -891,8 +889,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
}
|
||||
},
|
||||
hir::ExprPath(..) => {
|
||||
let def = cx.tcx().def_map.borrow().get(&e.id).unwrap().full_def();
|
||||
match def {
|
||||
match cx.tcx().expect_def(e.id) {
|
||||
Def::Local(_, id) => {
|
||||
if let Some(val) = fn_args.and_then(|args| args.get(&id).cloned()) {
|
||||
val
|
||||
@ -937,9 +934,8 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
_ => break,
|
||||
};
|
||||
}
|
||||
let def = cx.tcx().def_map.borrow()[&callee.id].full_def();
|
||||
let arg_vals = map_list(args)?;
|
||||
match def {
|
||||
match cx.tcx().expect_def(callee.id) {
|
||||
Def::Fn(did) | Def::Method(did) => {
|
||||
const_fn_call(
|
||||
cx,
|
||||
|
@ -318,8 +318,8 @@ pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let loop_id = match opt_label {
|
||||
None => fcx.top_loop_scope(),
|
||||
Some(_) => {
|
||||
match bcx.tcx().def_map.borrow().get(&expr.id).map(|d| d.full_def()) {
|
||||
Some(Def::Label(loop_id)) => loop_id,
|
||||
match bcx.tcx().expect_def(expr.id) {
|
||||
Def::Label(loop_id) => loop_id,
|
||||
r => {
|
||||
bug!("{:?} in def-map for label", r)
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
// have side effects. This seems to be reached through tuple struct constructors being
|
||||
// passed zero-size constants.
|
||||
if let hir::ExprPath(..) = expr.node {
|
||||
match bcx.def(expr.id) {
|
||||
match bcx.tcx().expect_def(expr.id) {
|
||||
Def::Const(_) | Def::AssociatedConst(_) => {
|
||||
assert!(type_is_zero_size(bcx.ccx(), bcx.tcx().node_id_to_type(expr.id)));
|
||||
return bcx;
|
||||
@ -172,7 +172,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
// `[x; N]` somewhere within.
|
||||
match expr.node {
|
||||
hir::ExprPath(..) => {
|
||||
match bcx.def(expr.id) {
|
||||
match bcx.tcx().expect_def(expr.id) {
|
||||
Def::Const(did) | Def::AssociatedConst(did) => {
|
||||
let empty_substs = bcx.tcx().mk_substs(Substs::empty());
|
||||
let const_expr = consts::get_const_expr(bcx.ccx(), did, expr,
|
||||
@ -651,7 +651,7 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
trans(bcx, &e)
|
||||
}
|
||||
hir::ExprPath(..) => {
|
||||
let var = trans_var(bcx, bcx.def(expr.id));
|
||||
let var = trans_var(bcx, bcx.tcx().expect_def(expr.id));
|
||||
DatumBlock::new(bcx, var.to_expr_datum())
|
||||
}
|
||||
hir::ExprField(ref base, name) => {
|
||||
@ -1073,7 +1073,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
trans_into(bcx, &e, dest)
|
||||
}
|
||||
hir::ExprPath(..) => {
|
||||
trans_def_dps_unadjusted(bcx, expr, bcx.def(expr.id), dest)
|
||||
trans_def_dps_unadjusted(bcx, expr, bcx.tcx().expect_def(expr.id), dest)
|
||||
}
|
||||
hir::ExprIf(ref cond, ref thn, ref els) => {
|
||||
controlflow::trans_if(bcx, expr.id, &cond, &thn, els.as_ref().map(|e| &**e), dest)
|
||||
@ -2373,7 +2373,7 @@ fn expr_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, expr: &hir::Expr) -> ExprKin
|
||||
|
||||
match expr.node {
|
||||
hir::ExprPath(..) => {
|
||||
match tcx.resolve_expr(expr) {
|
||||
match tcx.expect_def(expr.id) {
|
||||
// Put functions and ctors with the ADTs, as they
|
||||
// are zero-sized, so DPS is the cheapest option.
|
||||
Def::Struct(..) | Def::Variant(..) |
|
||||
|
@ -734,7 +734,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
|
||||
fn trait_def_id(&self, trait_ref: &hir::TraitRef) -> DefId {
|
||||
let path = &trait_ref.path;
|
||||
match ::lookup_full_def(self.tcx(), path.span, trait_ref.ref_id) {
|
||||
match self.tcx().expect_def(trait_ref.ref_id) {
|
||||
Def::Trait(trait_def_id) => trait_def_id,
|
||||
Def::Err => {
|
||||
self.tcx().sess.fatal("cannot continue compilation due to previous error");
|
||||
@ -1064,12 +1064,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
|
||||
match ty.node {
|
||||
hir::TyPath(None, ref path) => {
|
||||
let def = match self.tcx().def_map.borrow().get(&ty.id) {
|
||||
Some(&def::PathResolution { base_def, depth: 0, .. }) => Some(base_def),
|
||||
_ => None
|
||||
};
|
||||
match def {
|
||||
Some(Def::Trait(trait_def_id)) => {
|
||||
let resolution = self.tcx().expect_resolution(ty.id);
|
||||
match resolution.base_def {
|
||||
Def::Trait(trait_def_id) if resolution.depth == 0 => {
|
||||
let mut projection_bounds = Vec::new();
|
||||
let trait_ref =
|
||||
self.object_path_to_poly_trait_ref(rscope,
|
||||
@ -1721,17 +1718,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
}
|
||||
hir::TyPath(ref maybe_qself, ref path) => {
|
||||
debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
|
||||
let path_res = if let Some(&d) = tcx.def_map.borrow().get(&ast_ty.id) {
|
||||
d
|
||||
} else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
|
||||
// Create some fake resolution that can't possibly be a type.
|
||||
def::PathResolution {
|
||||
base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
|
||||
depth: path.segments.len()
|
||||
}
|
||||
} else {
|
||||
span_bug!(ast_ty.span, "unbound path {:?}", ast_ty)
|
||||
};
|
||||
let path_res = tcx.expect_resolution(ast_ty.id);
|
||||
let def = path_res.base_def;
|
||||
let base_ty_end = path.segments.len() - path_res.depth;
|
||||
let opt_self_ty = maybe_qself.as_ref().map(|qself| {
|
||||
@ -1748,10 +1735,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
|
||||
if path_res.depth != 0 && ty.sty != ty::TyError {
|
||||
// Write back the new resolution.
|
||||
tcx.def_map.borrow_mut().insert(ast_ty.id, def::PathResolution {
|
||||
base_def: def,
|
||||
depth: 0
|
||||
});
|
||||
tcx.def_map.borrow_mut().insert(ast_ty.id, def::PathResolution::new(def));
|
||||
}
|
||||
|
||||
ty
|
||||
@ -2232,7 +2216,7 @@ pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
for ast_bound in ast_bounds {
|
||||
match *ast_bound {
|
||||
hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => {
|
||||
match ::lookup_full_def(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) {
|
||||
match tcx.expect_def(b.trait_ref.ref_id) {
|
||||
Def::Trait(trait_did) => {
|
||||
if tcx.try_add_builtin_trait(trait_did,
|
||||
&mut builtin_bounds) {
|
||||
|
@ -8,9 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use hir::def::{self, Def};
|
||||
use hir::def::Def;
|
||||
use rustc::infer::{self, InferOk, TypeOrigin};
|
||||
use hir::pat_util::{PatIdMap, pat_id_map};
|
||||
use hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const};
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference};
|
||||
@ -21,7 +20,6 @@ use session::Session;
|
||||
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use std::cmp;
|
||||
use std::ops::Deref;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::{Span, Spanned};
|
||||
use syntax::ptr::P;
|
||||
@ -29,18 +27,6 @@ use syntax::ptr::P;
|
||||
use rustc::hir::{self, PatKind};
|
||||
use rustc::hir::print as pprust;
|
||||
|
||||
pub struct PatCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
pub fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
|
||||
pub map: PatIdMap,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Deref for PatCtxt<'a, 'gcx, 'tcx> {
|
||||
type Target = FnCtxt<'a, 'gcx, 'tcx>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.fcx
|
||||
}
|
||||
}
|
||||
|
||||
// This function exists due to the warning "diagnostic code E0164 already used"
|
||||
fn bad_struct_kind_err(sess: &Session, pat: &hir::Pat, path: &hir::Path, lint: bool) {
|
||||
let name = pprust::path_to_string(path);
|
||||
@ -55,7 +41,7 @@ fn bad_struct_kind_err(sess: &Session, pat: &hir::Pat, path: &hir::Path, lint: b
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) {
|
||||
let tcx = self.tcx;
|
||||
|
||||
@ -150,26 +136,22 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
|
||||
self.demand_eqtype(pat.span, expected, lhs_ty);
|
||||
}
|
||||
PatKind::Path(..) if pat_is_resolved_const(&tcx.def_map.borrow(), pat) => {
|
||||
if let Some(pat_def) = tcx.def_map.borrow().get(&pat.id) {
|
||||
let const_did = pat_def.def_id();
|
||||
let const_scheme = tcx.lookup_item_type(const_did);
|
||||
assert!(const_scheme.generics.is_empty());
|
||||
let const_ty = self.instantiate_type_scheme(pat.span,
|
||||
&Substs::empty(),
|
||||
&const_scheme.ty);
|
||||
self.write_ty(pat.id, const_ty);
|
||||
let const_did = tcx.expect_def(pat.id).def_id();
|
||||
let const_scheme = tcx.lookup_item_type(const_did);
|
||||
assert!(const_scheme.generics.is_empty());
|
||||
let const_ty = self.instantiate_type_scheme(pat.span,
|
||||
&Substs::empty(),
|
||||
&const_scheme.ty);
|
||||
self.write_ty(pat.id, const_ty);
|
||||
|
||||
// FIXME(#20489) -- we should limit the types here to scalars or something!
|
||||
// FIXME(#20489) -- we should limit the types here to scalars or something!
|
||||
|
||||
// As with PatKind::Lit, what we really want here is that there
|
||||
// exist a LUB, but for the cases that can occur, subtype
|
||||
// is good enough.
|
||||
self.demand_suptype(pat.span, expected, const_ty);
|
||||
} else {
|
||||
self.write_error(pat.id);
|
||||
}
|
||||
// As with PatKind::Lit, what we really want here is that there
|
||||
// exist a LUB, but for the cases that can occur, subtype
|
||||
// is good enough.
|
||||
self.demand_suptype(pat.span, expected, const_ty);
|
||||
}
|
||||
PatKind::Binding(bm, ref path, ref sub) => {
|
||||
PatKind::Binding(bm, _, ref sub) => {
|
||||
let typ = self.local_ty(pat.span, pat.id);
|
||||
match bm {
|
||||
hir::BindByRef(mutbl) => {
|
||||
@ -198,15 +180,19 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
// if there are multiple arms, make sure they all agree on
|
||||
// what the type of the binding `x` ought to be
|
||||
if let Some(&canon_id) = self.map.get(&path.node) {
|
||||
if canon_id != pat.id {
|
||||
let ct = self.local_ty(pat.span, canon_id);
|
||||
self.demand_eqtype(pat.span, ct, typ);
|
||||
match tcx.expect_def(pat.id) {
|
||||
Def::Err => {}
|
||||
Def::Local(_, var_id) => {
|
||||
if var_id != pat.id {
|
||||
let vt = self.local_ty(pat.span, var_id);
|
||||
self.demand_eqtype(pat.span, vt, typ);
|
||||
}
|
||||
}
|
||||
d => bug!("bad def for pattern binding `{:?}`", d)
|
||||
}
|
||||
|
||||
if let Some(ref p) = *sub {
|
||||
self.check_pat(&p, expected);
|
||||
}
|
||||
if let Some(ref p) = *sub {
|
||||
self.check_pat(&p, expected);
|
||||
}
|
||||
}
|
||||
PatKind::TupleStruct(ref path, ref subpats, ddpos) => {
|
||||
@ -217,25 +203,12 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
PatKind::QPath(ref qself, ref path) => {
|
||||
let self_ty = self.to_ty(&qself.ty);
|
||||
let path_res = if let Some(&d) = tcx.def_map.borrow().get(&pat.id) {
|
||||
if d.base_def == Def::Err {
|
||||
self.set_tainted_by_errors();
|
||||
self.write_error(pat.id);
|
||||
return;
|
||||
}
|
||||
d
|
||||
} else if qself.position == 0 {
|
||||
// This is just a sentinel for finish_resolving_def_to_ty.
|
||||
let sentinel = self.tcx.map.local_def_id(ast::CRATE_NODE_ID);
|
||||
def::PathResolution {
|
||||
base_def: Def::Mod(sentinel),
|
||||
depth: path.segments.len()
|
||||
}
|
||||
} else {
|
||||
debug!("unbound path {:?}", pat);
|
||||
let path_res = tcx.expect_resolution(pat.id);
|
||||
if path_res.base_def == Def::Err {
|
||||
self.set_tainted_by_errors();
|
||||
self.write_error(pat.id);
|
||||
return;
|
||||
};
|
||||
}
|
||||
if let Some((opt_ty, segments, def)) =
|
||||
self.resolve_ty_and_def_ufcs(path_res, Some(self_ty),
|
||||
path, pat.span, pat.id) {
|
||||
@ -493,12 +466,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// Typecheck the patterns first, so that we get types for all the
|
||||
// bindings.
|
||||
for arm in arms {
|
||||
let pcx = PatCtxt {
|
||||
fcx: self,
|
||||
map: pat_id_map(&arm.pats[0]),
|
||||
};
|
||||
for p in &arm.pats {
|
||||
pcx.check_pat(&p, discrim_ty);
|
||||
self.check_pat(&p, discrim_ty);
|
||||
}
|
||||
}
|
||||
|
||||
@ -583,13 +552,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn check_pat_struct(&self, pat: &'gcx hir::Pat,
|
||||
path: &hir::Path, fields: &'gcx [Spanned<hir::FieldPat>],
|
||||
etc: bool, expected: Ty<'tcx>) {
|
||||
let tcx = self.tcx;
|
||||
|
||||
let def = tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
|
||||
let def = tcx.expect_def(pat.id);
|
||||
let variant = match self.def_struct_variant(def, path.span) {
|
||||
Some((_, variant)) => variant,
|
||||
None => {
|
||||
@ -630,18 +599,16 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
|
||||
// Typecheck the path.
|
||||
let tcx = self.tcx;
|
||||
|
||||
let path_res = match tcx.def_map.borrow().get(&pat.id) {
|
||||
Some(&path_res) if path_res.base_def != Def::Err => path_res,
|
||||
_ => {
|
||||
self.set_tainted_by_errors();
|
||||
self.write_error(pat.id);
|
||||
let path_res = tcx.expect_resolution(pat.id);
|
||||
if path_res.base_def == Def::Err {
|
||||
self.set_tainted_by_errors();
|
||||
self.write_error(pat.id);
|
||||
|
||||
for pat in subpats {
|
||||
self.check_pat(&pat, tcx.types.err);
|
||||
}
|
||||
return;
|
||||
for pat in subpats {
|
||||
self.check_pat(&pat, tcx.types.err);
|
||||
}
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
let (opt_ty, segments, def) = match self.resolve_ty_and_def_ufcs(path_res,
|
||||
None, path,
|
||||
|
@ -222,7 +222,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
let tcx = self.tcx;
|
||||
if let Some(pr) = tcx.def_map.borrow().get(&expr.id) {
|
||||
if pr.depth == 0 && pr.base_def != Def::Err {
|
||||
if let Some(span) = tcx.map.span_if_local(pr.def_id()) {
|
||||
if let Some(span) = tcx.map.span_if_local(pr.base_def.def_id()) {
|
||||
err.span_note(span, "defined here");
|
||||
}
|
||||
}
|
||||
|
@ -81,14 +81,13 @@ pub use self::compare_method::{compare_impl_method, compare_const_impl};
|
||||
use self::TupleArgumentsFlag::*;
|
||||
|
||||
use astconv::{AstConv, ast_region_to_region, PathParamMode};
|
||||
use check::_match::PatCtxt;
|
||||
use dep_graph::DepNode;
|
||||
use fmt_macros::{Parser, Piece, Position};
|
||||
use middle::cstore::LOCAL_CRATE;
|
||||
use hir::def::{self, Def};
|
||||
use hir::def_id::DefId;
|
||||
use hir::pat_util;
|
||||
use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin, TypeTrace, type_variable};
|
||||
use hir::pat_util::{self, pat_id_map};
|
||||
use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace};
|
||||
use rustc::traits::{self, ProjectionMode};
|
||||
use rustc::ty::{GenericPredicates, TypeScheme};
|
||||
@ -102,7 +101,7 @@ use rustc::ty::util::{Representability, IntTypeExt};
|
||||
use require_c_abi_if_variadic;
|
||||
use rscope::{ElisionFailureInfo, RegionScope};
|
||||
use session::{Session, CompileResult};
|
||||
use {CrateCtxt, lookup_full_def};
|
||||
use CrateCtxt;
|
||||
use TypeAndSubsts;
|
||||
use lint;
|
||||
use util::common::{block_query, ErrorReported, indenter, loop_query};
|
||||
@ -672,11 +671,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
|
||||
});
|
||||
|
||||
// Check the pattern.
|
||||
let pcx = PatCtxt {
|
||||
fcx: &fcx,
|
||||
map: pat_id_map(&input.pat),
|
||||
};
|
||||
pcx.check_pat(&input.pat, *arg_ty);
|
||||
fcx.check_pat(&input.pat, *arg_ty);
|
||||
}
|
||||
|
||||
visit.visit_block(body);
|
||||
@ -3158,7 +3153,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
let tcx = self.tcx;
|
||||
|
||||
// Find the relevant variant
|
||||
let def = lookup_full_def(tcx, path.span, expr.id);
|
||||
let def = tcx.expect_def(expr.id);
|
||||
if def == Def::Err {
|
||||
self.set_tainted_by_errors();
|
||||
self.check_struct_fields_on_error(expr.id, fields, base_expr);
|
||||
@ -3350,18 +3345,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
self.to_ty(&qself.ty)
|
||||
});
|
||||
|
||||
let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
|
||||
d
|
||||
} else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
|
||||
// Create some fake resolution that can't possibly be a type.
|
||||
def::PathResolution {
|
||||
base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
|
||||
depth: path.segments.len()
|
||||
}
|
||||
} else {
|
||||
span_bug!(expr.span, "unbound path {:?}", expr)
|
||||
};
|
||||
|
||||
let path_res = tcx.expect_resolution(id);
|
||||
if let Some((opt_ty, segments, def)) =
|
||||
self.resolve_ty_and_def_ufcs(path_res, opt_self_ty, path,
|
||||
expr.span, expr.id) {
|
||||
@ -3752,10 +3736,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
if let Some(def) = def {
|
||||
// Write back the new resolution.
|
||||
self.tcx().def_map.borrow_mut().insert(node_id, def::PathResolution {
|
||||
base_def: def,
|
||||
depth: 0,
|
||||
});
|
||||
self.tcx().def_map.borrow_mut().insert(node_id, def::PathResolution::new(def));
|
||||
Some((Some(ty), slice::ref_slice(item_segment), def))
|
||||
} else {
|
||||
self.write_error(node_id);
|
||||
@ -3800,11 +3781,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
let pcx = PatCtxt {
|
||||
fcx: self,
|
||||
map: pat_id_map(&local.pat),
|
||||
};
|
||||
pcx.check_pat(&local.pat, t);
|
||||
self.check_pat(&local.pat, t);
|
||||
let pat_ty = self.node_ty(local.pat.id);
|
||||
if pat_ty.references_error() {
|
||||
self.write_ty(local.id, pat_ty);
|
||||
@ -4562,7 +4539,7 @@ pub fn may_break(tcx: TyCtxt, id: ast::NodeId, b: &hir::Block) -> bool {
|
||||
// <id> nested anywhere inside the loop?
|
||||
(block_query(b, |e| {
|
||||
if let hir::ExprBreak(Some(_)) = e.node {
|
||||
lookup_full_def(tcx, e.span, e.id) == Def::Label(id)
|
||||
tcx.expect_def(e.id) == Def::Label(id)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
@ -532,17 +532,13 @@ fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
-> bool
|
||||
{
|
||||
if let hir::TyPath(None, _) = ast_ty.node {
|
||||
let path_res = *tcx.def_map.borrow().get(&ast_ty.id).unwrap();
|
||||
let path_res = tcx.expect_resolution(ast_ty.id);
|
||||
match path_res.base_def {
|
||||
Def::SelfTy(Some(def_id), None) => {
|
||||
path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
|
||||
}
|
||||
Def::TyParam(_, _, def_id, _) => {
|
||||
path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
|
||||
}
|
||||
_ => {
|
||||
false
|
||||
Def::SelfTy(Some(def_id), None) |
|
||||
Def::TyParam(_, _, def_id, _) if path_res.depth == 0 => {
|
||||
def_id == tcx.map.local_def_id(param_id)
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
@ -1719,7 +1715,7 @@ fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
|
||||
match unbound {
|
||||
Some(ref tpb) => {
|
||||
// FIXME(#8559) currently requires the unbound to be built-in.
|
||||
let trait_def_id = tcx.trait_ref_to_def_id(tpb);
|
||||
let trait_def_id = tcx.expect_def(tpb.ref_id).def_id();
|
||||
match kind_id {
|
||||
Ok(kind_id) if trait_def_id != kind_id => {
|
||||
tcx.sess.span_warn(span,
|
||||
|
@ -4125,7 +4125,7 @@ register_diagnostics! {
|
||||
// E0239, // `next` method of `Iterator` trait has unexpected type
|
||||
// E0240,
|
||||
// E0241,
|
||||
E0242, // internal error looking up a definition
|
||||
// E0242,
|
||||
E0245, // not a trait
|
||||
// E0246, // invalid recursive type
|
||||
// E0247,
|
||||
|
@ -103,7 +103,6 @@ pub use rustc::util;
|
||||
|
||||
use dep_graph::DepNode;
|
||||
use hir::map as hir_map;
|
||||
use hir::def::Def;
|
||||
use rustc::infer::TypeOrigin;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
@ -176,15 +175,6 @@ fn write_substs_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
fn lookup_full_def(tcx: TyCtxt, sp: Span, id: ast::NodeId) -> Def {
|
||||
match tcx.def_map.borrow().get(&id) {
|
||||
Some(x) => x.full_def(),
|
||||
None => {
|
||||
span_fatal!(tcx.sess, sp, E0242, "internal error looking up a definition")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn require_c_abi_if_variadic(tcx: TyCtxt,
|
||||
decl: &hir::FnDecl,
|
||||
abi: Abi,
|
||||
|
@ -50,8 +50,8 @@ pub fn try_inline(cx: &DocContext, id: ast::NodeId, into: Option<ast::Name>)
|
||||
Some(tcx) => tcx,
|
||||
None => return None,
|
||||
};
|
||||
let def = match tcx.def_map.borrow().get(&id) {
|
||||
Some(d) => d.full_def(),
|
||||
let def = match tcx.expect_def_or_none(id) {
|
||||
Some(def) => def,
|
||||
None => return None,
|
||||
};
|
||||
let did = def.def_id();
|
||||
|
@ -2631,7 +2631,7 @@ fn resolve_type(cx: &DocContext,
|
||||
};
|
||||
}
|
||||
};
|
||||
let def = tcx.def_map.borrow().get(&id).expect("unresolved id not in defmap").full_def();
|
||||
let def = tcx.expect_def(id);
|
||||
debug!("resolve_type: def={:?}", def);
|
||||
|
||||
let is_generic = match def {
|
||||
@ -2700,7 +2700,7 @@ fn resolve_use_source(cx: &DocContext, path: Path, id: ast::NodeId) -> ImportSou
|
||||
|
||||
fn resolve_def(cx: &DocContext, id: ast::NodeId) -> Option<DefId> {
|
||||
cx.tcx_opt().and_then(|tcx| {
|
||||
tcx.def_map.borrow().get(&id).map(|d| register_def(cx, d.full_def()))
|
||||
tcx.expect_def_or_none(id).map(|def| register_def(cx, def))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -241,7 +241,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
Some(tcx) => tcx,
|
||||
None => return false
|
||||
};
|
||||
let def = tcx.def_map.borrow()[&id];
|
||||
let def = tcx.expect_def(id);
|
||||
let def_did = def.def_id();
|
||||
|
||||
let use_attrs = tcx.map.attrs(id).clean(self.cx);
|
||||
@ -251,10 +251,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
// reachable in documentation - a previously nonreachable item can be
|
||||
// made reachable by cross-crate inlining which we're checking here.
|
||||
// (this is done here because we need to know this upfront)
|
||||
if !def.def_id().is_local() && !is_no_inline {
|
||||
if !def_did.is_local() && !is_no_inline {
|
||||
let attrs = clean::inline::load_attrs(self.cx, tcx, def_did);
|
||||
let self_is_hidden = attrs.list("doc").has_word("hidden");
|
||||
match def.base_def {
|
||||
match def {
|
||||
Def::Trait(did) |
|
||||
Def::Struct(did) |
|
||||
Def::Enum(did) |
|
||||
|
@ -15,6 +15,7 @@ pub use use_from_trait_xc::Trait;
|
||||
|
||||
fn main() {
|
||||
match () {
|
||||
Trait { x: 42 } => () //~ ERROR `Trait` does not name a struct
|
||||
Trait { x: 42 } => () //~ ERROR expected variant, struct or type alias, found trait `Trait`
|
||||
//~^ ERROR `Trait` does not name a struct or a struct variant
|
||||
}
|
||||
}
|
||||
|
@ -23,5 +23,5 @@ mod bar1 {
|
||||
|
||||
fn main() {
|
||||
assert_eq!(1, bar1::Foo::ID);
|
||||
//~^ERROR associated const `ID` is private
|
||||
//~^ERROR associated constant `ID` is private
|
||||
}
|
||||
|
@ -12,6 +12,6 @@ mod foo { pub struct bar; }
|
||||
|
||||
fn main() {
|
||||
let bar = 5;
|
||||
//~^ ERROR cannot be named the same
|
||||
//~^ ERROR let bindings cannot shadow structs
|
||||
use foo::bar;
|
||||
}
|
||||
|
@ -19,10 +19,10 @@ use foo::d; //~ NOTE is imported here
|
||||
const a: u8 = 2; //~ NOTE is defined here
|
||||
|
||||
fn main() {
|
||||
let a = 4; //~ ERROR let variables cannot
|
||||
//~^ NOTE cannot be named the same as a const variable
|
||||
let c = 4; //~ ERROR let variables cannot
|
||||
//~^ NOTE cannot be named the same as a const variable
|
||||
let d = 4; //~ ERROR let variables cannot
|
||||
//~^ NOTE cannot be named the same as a const variable
|
||||
let a = 4; //~ ERROR let bindings cannot shadow constants
|
||||
//~^ NOTE cannot be named the same as a constant
|
||||
let c = 4; //~ ERROR let bindings cannot shadow constants
|
||||
//~^ NOTE cannot be named the same as a constant
|
||||
let d = 4; //~ ERROR let bindings cannot shadow constants
|
||||
//~^ NOTE cannot be named the same as a constant
|
||||
}
|
||||
|
@ -29,9 +29,9 @@ fn main() {
|
||||
// XEmpty1() => () // ERROR unresolved enum variant, struct or const `XEmpty1`
|
||||
// }
|
||||
match e1 {
|
||||
Empty1(..) => () //~ ERROR unresolved enum variant, struct or const `Empty1`
|
||||
Empty1(..) => () //~ ERROR unresolved variant or struct `Empty1`
|
||||
}
|
||||
match xe1 {
|
||||
XEmpty1(..) => () //~ ERROR unresolved enum variant, struct or const `XEmpty1`
|
||||
XEmpty1(..) => () //~ ERROR unresolved variant or struct `XEmpty1`
|
||||
}
|
||||
}
|
||||
|
@ -11,5 +11,5 @@
|
||||
struct hello(isize);
|
||||
|
||||
fn main() {
|
||||
let hello = 0; //~ERROR cannot be named the same
|
||||
let hello = 0; //~ERROR let bindings cannot shadow structs
|
||||
}
|
||||
|
@ -8,9 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//error-pattern:unresolved enum variant
|
||||
|
||||
fn main() {
|
||||
// a bug in the parser is allowing this:
|
||||
let a(1) = 13;
|
||||
let a(1) = 13; //~ ERROR unresolved variant or struct `a`
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ fn foo(_: usize) -> Foo { Foo(false) }
|
||||
|
||||
fn main() {
|
||||
match Foo(true) {
|
||||
foo(x) //~ ERROR `foo` is not an enum variant, struct or const
|
||||
foo(x) //~ ERROR expected variant or struct, found function `foo`
|
||||
=> ()
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,6 @@ mod foo { pub fn bar() {} }
|
||||
|
||||
fn main() {
|
||||
match () {
|
||||
foo::bar => {} //~ ERROR `bar` is not an enum variant, struct or const
|
||||
foo::bar => {} //~ ERROR expected variant, struct or constant, found function `bar`
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ extern {
|
||||
fn main() {
|
||||
let boolValue = match 42 {
|
||||
externalValue => true,
|
||||
//~^ ERROR static variables cannot be referenced in a pattern
|
||||
//~^ ERROR match bindings cannot shadow statics
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ enum Foo {
|
||||
|
||||
fn main() {
|
||||
match Foo::Bar(1) {
|
||||
Foo { i } => () //~ ERROR `Foo` does not name a struct or a struct variant
|
||||
Foo { i } => () //~ ERROR expected variant, struct or type alias, found enum `Foo`
|
||||
//~^ ERROR `Foo` does not name a struct or a struct variant
|
||||
}
|
||||
}
|
||||
|
@ -12,10 +12,10 @@
|
||||
|
||||
extern crate issue_17718_const_privacy as other;
|
||||
|
||||
use a::B; //~ ERROR: const `B` is private
|
||||
use a::B; //~ ERROR: constant `B` is private
|
||||
use other::{
|
||||
FOO,
|
||||
BAR, //~ ERROR: const `BAR` is private
|
||||
BAR, //~ ERROR: constant `BAR` is private
|
||||
FOO2,
|
||||
};
|
||||
|
||||
|
@ -14,8 +14,8 @@ const A3: usize = 1;
|
||||
|
||||
fn main() {
|
||||
match 1 {
|
||||
A1 => {} //~ ERROR: static variables cannot be referenced in a pattern
|
||||
A2 => {} //~ ERROR: static variables cannot be referenced in a pattern
|
||||
A1 => {} //~ ERROR: match bindings cannot shadow statics
|
||||
A2 => {} //~ ERROR: match bindings cannot shadow statics
|
||||
A3 => {}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ pub static X: usize = 1;
|
||||
fn main() {
|
||||
match 1 {
|
||||
self::X => { },
|
||||
//~^ ERROR static variables cannot be referenced in a pattern, use a `const` instead
|
||||
//~^ ERROR expected variant, struct or constant, found static `X`
|
||||
_ => { },
|
||||
}
|
||||
}
|
||||
|
@ -9,21 +9,21 @@
|
||||
// except according to those terms.
|
||||
|
||||
static foo: i32 = 0;
|
||||
//~^ NOTE static variable defined here
|
||||
//~^ NOTE a static `foo` is defined here
|
||||
|
||||
fn bar(foo: i32) {}
|
||||
//~^ ERROR static variables cannot be referenced in a pattern, use a `const` instead
|
||||
//~| static variable used in pattern
|
||||
//~^ ERROR function parameters cannot shadow statics
|
||||
//~| cannot be named the same as a static
|
||||
|
||||
mod submod {
|
||||
pub static answer: i32 = 42;
|
||||
}
|
||||
|
||||
use self::submod::answer;
|
||||
//~^ NOTE static variable imported here
|
||||
//~^ NOTE a static `answer` is imported here
|
||||
|
||||
fn question(answer: i32) {}
|
||||
//~^ ERROR static variables cannot be referenced in a pattern, use a `const` instead
|
||||
//~| static variable used in pattern
|
||||
//~^ ERROR function parameters cannot shadow statics
|
||||
//~| cannot be named the same as a static
|
||||
fn main() {
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
fn main() {
|
||||
match 'a' {
|
||||
char{ch} => true
|
||||
//~^ ERROR `char` does not name a struct or a struct variant
|
||||
//~^ ERROR expected variant, struct or type alias, found builtin type `char`
|
||||
//~| ERROR `char` does not name a struct or a struct variant
|
||||
};
|
||||
}
|
||||
|
@ -10,11 +10,11 @@
|
||||
|
||||
fn main() {
|
||||
match Some(1) {
|
||||
None @ _ => {} //~ ERROR cannot be named the same
|
||||
None @ _ => {} //~ ERROR match bindings cannot shadow variants
|
||||
};
|
||||
const C: u8 = 1;
|
||||
match 1 {
|
||||
C @ 2 => { //~ ERROR cannot be named the same
|
||||
C @ 2 => { //~ ERROR match bindings cannot shadow constant
|
||||
println!("{}", C);
|
||||
}
|
||||
_ => {}
|
||||
|
@ -14,7 +14,9 @@ fn main() {
|
||||
let u = A { x: 1 }; //~ ERROR `A` does not name a structure
|
||||
let v = u32 { x: 1 }; //~ ERROR `u32` does not name a structure
|
||||
match () {
|
||||
A { x: 1 } => {} //~ ERROR `A` does not name a struct
|
||||
u32 { x: 1 } => {} //~ ERROR `u32` does not name a struct
|
||||
A { x: 1 } => {} //~ ERROR expected variant, struct or type alias, found module `A`
|
||||
//~^ ERROR `A` does not name a struct or a struct variant
|
||||
u32 { x: 1 } => {} //~ ERROR expected variant, struct or type alias, found builtin type `u32
|
||||
//~^ ERROR `u32` does not name a struct or a struct variant
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,6 @@ impl S {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if let C1(..) = 0 {} //~ ERROR `C1` does not name a tuple variant or a tuple struct
|
||||
if let C1(..) = 0 {} //~ ERROR expected variant or struct, found constant `C1`
|
||||
if let S::C2(..) = 0 {} //~ ERROR `S::C2` does not name a tuple variant or a tuple struct
|
||||
}
|
||||
|
17
src/test/compile-fail/issue-32086.rs
Normal file
17
src/test/compile-fail/issue-32086.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
struct S(u8);
|
||||
const C: S = S(10);
|
||||
|
||||
fn main() {
|
||||
let C(a) = S(11); //~ ERROR expected variant or struct, found constant `C`
|
||||
let C(..) = S(11); //~ ERROR expected variant or struct, found constant `C`
|
||||
}
|
19
src/test/compile-fail/issue-34047.rs
Normal file
19
src/test/compile-fail/issue-34047.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
const C: u8 = 0; //~ NOTE a constant `C` is defined here
|
||||
|
||||
fn main() {
|
||||
match 1u8 {
|
||||
mut C => {} //~ ERROR match bindings cannot shadow constants
|
||||
//~^ NOTE cannot be named the same as a constant
|
||||
_ => {}
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
|
||||
fn main() {
|
||||
let z = match 3 {
|
||||
x(1) => x(1) //~ ERROR unresolved enum variant
|
||||
x(1) => x(1) //~ ERROR unresolved variant or struct `x`
|
||||
//~^ ERROR unresolved name `x`
|
||||
};
|
||||
assert!(z == 3);
|
||||
|
@ -19,6 +19,6 @@ impl MyTrait for Foo {}
|
||||
fn main() {
|
||||
match 0u32 {
|
||||
<Foo as MyTrait>::trait_bar => {}
|
||||
//~^ ERROR `trait_bar` is not an associated const
|
||||
//~^ ERROR expected associated constant, found method `trait_bar`
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,11 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:cannot be named the same
|
||||
use std::option::*;
|
||||
|
||||
fn main() {
|
||||
let None: isize = 42;
|
||||
let None: isize = 42; //~ ERROR let bindings cannot shadow variants
|
||||
log(debug, None);
|
||||
//~^ ERROR unresolved name `debug`
|
||||
//~| ERROR unresolved name `log`
|
||||
}
|
||||
|
@ -11,5 +11,5 @@
|
||||
struct foo(usize);
|
||||
|
||||
fn main() {
|
||||
let (foo, _) = (2, 3); //~ ERROR `foo` cannot be named the same as
|
||||
let (foo, _) = (2, 3); //~ ERROR let bindings cannot shadow structs
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ impl S {
|
||||
|
||||
fn main() {
|
||||
match 10 {
|
||||
<S as Tr>::A::f::<u8> => {} //~ ERROR `f` is not an associated const
|
||||
<S as Tr>::A::f::<u8> => {} //~ ERROR associated items in match patterns must be constants
|
||||
0 ... <S as Tr>::A::f::<u8> => {} //~ ERROR only char and numeric types are allowed in range
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ fn main() {
|
||||
// instead of spitting out a custom error about some identifier collisions
|
||||
// (we should allow shadowing)
|
||||
match 4 {
|
||||
a => {} //~ ERROR static variables cannot be referenced in a pattern
|
||||
a => {} //~ ERROR match bindings cannot shadow statics
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@ -44,7 +44,7 @@ fn mutable_statics() {
|
||||
match (Foo { bar: Some(Direction::North), baz: NewBool(true) }) {
|
||||
Foo { bar: None, baz: NewBool(true) } => (),
|
||||
STATIC_MUT_FOO => (),
|
||||
//~^ ERROR static variables cannot be referenced in a pattern
|
||||
//~^ ERROR match bindings cannot shadow statics
|
||||
Foo { bar: Some(Direction::South), .. } => (),
|
||||
Foo { bar: Some(EAST), .. } => (),
|
||||
Foo { bar: Some(Direction::North), baz: NewBool(true) } => (),
|
||||
|
@ -14,7 +14,7 @@ mod a {
|
||||
trait A {
|
||||
}
|
||||
|
||||
impl A for a { //~ ERROR type name `a` is undefined or not in scope
|
||||
impl A for a { //~ ERROR expected type, found module
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
18
src/test/run-pass/issue-34074.rs
Normal file
18
src/test/run-pass/issue-34074.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Make sure several unnamed function arguments don't conflict with each other
|
||||
|
||||
trait Tr {
|
||||
fn f(u8, u8) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
Loading…
Reference in New Issue
Block a user