rustc: separate bodies for static/(associated)const and embedded constants.
This commit is contained in:
parent
864928297d
commit
e64f64a2fc
@ -327,10 +327,6 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
||||
self.opt_expr(base, field_cfg)
|
||||
}
|
||||
|
||||
hir::ExprRepeat(ref elem, ref count) => {
|
||||
self.straightline(expr, pred, [elem, count].iter().map(|&e| &**e))
|
||||
}
|
||||
|
||||
hir::ExprAssign(ref l, ref r) |
|
||||
hir::ExprAssignOp(_, ref l, ref r) => {
|
||||
self.straightline(expr, pred, [r, l].iter().map(|&e| &**e))
|
||||
@ -347,7 +343,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
||||
hir::ExprType(ref e, _) |
|
||||
hir::ExprUnary(_, ref e) |
|
||||
hir::ExprField(ref e, _) |
|
||||
hir::ExprTupField(ref e, _) => {
|
||||
hir::ExprTupField(ref e, _) |
|
||||
hir::ExprRepeat(ref e, _) => {
|
||||
self.straightline(expr, pred, Some(&**e).into_iter())
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,6 @@ pub fn visit_all_item_likes_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>
|
||||
let task_id = (self.dep_node_fn)(trait_item_def_id);
|
||||
let _task = self.tcx.dep_graph.in_task(task_id.clone());
|
||||
debug!("Started task {:?}", task_id);
|
||||
assert!(!self.tcx.map.is_inlined_def_id(trait_item_def_id));
|
||||
self.tcx.dep_graph.read(DepNode::Hir(trait_item_def_id));
|
||||
self.visitor.visit_trait_item(i);
|
||||
debug!("Ended task {:?}", task_id);
|
||||
|
@ -203,10 +203,10 @@ pub trait Visitor<'v> : Sized {
|
||||
/// visit_nested_item, does nothing by default unless you override
|
||||
/// `nested_visit_map` to return `Some(_)`, in which case it will walk the
|
||||
/// body.
|
||||
fn visit_body(&mut self, id: ExprId) {
|
||||
let opt_expr = self.nested_visit_map().intra().map(|map| map.expr(id));
|
||||
if let Some(expr) = opt_expr {
|
||||
self.visit_expr(expr);
|
||||
fn visit_nested_body(&mut self, id: BodyId) {
|
||||
let opt_body = self.nested_visit_map().intra().map(|map| map.body(id));
|
||||
if let Some(body) = opt_body {
|
||||
self.visit_body(body);
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,6 +216,10 @@ pub trait Visitor<'v> : Sized {
|
||||
walk_item(self, i)
|
||||
}
|
||||
|
||||
fn visit_body(&mut self, b: &'v Body) {
|
||||
walk_body(self, b);
|
||||
}
|
||||
|
||||
/// When invoking `visit_all_item_likes()`, you need to supply an
|
||||
/// item-like visitor. This method converts a "intra-visit"
|
||||
/// visitor into an item-like visitor that walks the entire tree.
|
||||
@ -264,8 +268,6 @@ pub trait Visitor<'v> : Sized {
|
||||
fn visit_expr(&mut self, ex: &'v Expr) {
|
||||
walk_expr(self, ex)
|
||||
}
|
||||
fn visit_expr_post(&mut self, _ex: &'v Expr) {
|
||||
}
|
||||
fn visit_ty(&mut self, t: &'v Ty) {
|
||||
walk_ty(self, t)
|
||||
}
|
||||
@ -278,7 +280,7 @@ pub trait Visitor<'v> : Sized {
|
||||
fn visit_fn_decl(&mut self, fd: &'v FnDecl) {
|
||||
walk_fn_decl(self, fd)
|
||||
}
|
||||
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: ExprId, s: Span, id: NodeId) {
|
||||
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: BodyId, s: Span, id: NodeId) {
|
||||
walk_fn(self, fk, fd, b, s, id)
|
||||
}
|
||||
fn visit_trait_item(&mut self, ti: &'v TraitItem) {
|
||||
@ -392,6 +394,10 @@ pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod, mod_node_i
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body) {
|
||||
visitor.visit_expr(&body.value);
|
||||
}
|
||||
|
||||
pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
|
||||
visitor.visit_id(local.id);
|
||||
visitor.visit_pat(&local.pat);
|
||||
@ -437,11 +443,11 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
|
||||
visitor.visit_id(item.id);
|
||||
visitor.visit_path(path, item.id);
|
||||
}
|
||||
ItemStatic(ref typ, _, ref expr) |
|
||||
ItemConst(ref typ, ref expr) => {
|
||||
ItemStatic(ref typ, _, body) |
|
||||
ItemConst(ref typ, body) => {
|
||||
visitor.visit_id(item.id);
|
||||
visitor.visit_ty(typ);
|
||||
visitor.visit_expr(expr);
|
||||
visitor.visit_nested_body(body);
|
||||
}
|
||||
ItemFn(ref declaration, unsafety, constness, abi, ref generics, body_id) => {
|
||||
visitor.visit_fn(FnKind::ItemFn(item.name,
|
||||
@ -523,7 +529,7 @@ pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
generics,
|
||||
parent_item_id,
|
||||
variant.span);
|
||||
walk_list!(visitor, visit_expr, &variant.node.disr_expr);
|
||||
walk_list!(visitor, visit_nested_body, variant.node.disr_expr);
|
||||
walk_list!(visitor, visit_attribute, &variant.node.attrs);
|
||||
}
|
||||
|
||||
@ -556,9 +562,9 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
|
||||
visitor.visit_ty(ty);
|
||||
walk_list!(visitor, visit_ty_param_bound, bounds);
|
||||
}
|
||||
TyArray(ref ty, ref expression) => {
|
||||
TyArray(ref ty, length) => {
|
||||
visitor.visit_ty(ty);
|
||||
visitor.visit_expr(expression)
|
||||
visitor.visit_nested_body(length)
|
||||
}
|
||||
TyPolyTraitRef(ref bounds) => {
|
||||
walk_list!(visitor, visit_ty_param_bound, bounds);
|
||||
@ -566,8 +572,8 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
|
||||
TyImplTrait(ref bounds) => {
|
||||
walk_list!(visitor, visit_ty_param_bound, bounds);
|
||||
}
|
||||
TyTypeof(ref expression) => {
|
||||
visitor.visit_expr(expression)
|
||||
TyTypeof(expression) => {
|
||||
visitor.visit_nested_body(expression)
|
||||
}
|
||||
TyInfer => {}
|
||||
}
|
||||
@ -775,35 +781,23 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'
|
||||
pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
function_kind: FnKind<'v>,
|
||||
function_declaration: &'v FnDecl,
|
||||
body_id: ExprId,
|
||||
body_id: BodyId,
|
||||
_span: Span,
|
||||
id: NodeId) {
|
||||
visitor.visit_id(id);
|
||||
visitor.visit_fn_decl(function_declaration);
|
||||
walk_fn_kind(visitor, function_kind);
|
||||
visitor.visit_body(body_id)
|
||||
}
|
||||
|
||||
pub fn walk_fn_with_body<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
function_kind: FnKind<'v>,
|
||||
function_declaration: &'v FnDecl,
|
||||
body: &'v Expr,
|
||||
_span: Span,
|
||||
id: NodeId) {
|
||||
visitor.visit_id(id);
|
||||
visitor.visit_fn_decl(function_declaration);
|
||||
walk_fn_kind(visitor, function_kind);
|
||||
visitor.visit_expr(body)
|
||||
visitor.visit_nested_body(body_id)
|
||||
}
|
||||
|
||||
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) {
|
||||
visitor.visit_name(trait_item.span, trait_item.name);
|
||||
walk_list!(visitor, visit_attribute, &trait_item.attrs);
|
||||
match trait_item.node {
|
||||
TraitItemKind::Const(ref ty, ref default) => {
|
||||
TraitItemKind::Const(ref ty, default) => {
|
||||
visitor.visit_id(trait_item.id);
|
||||
visitor.visit_ty(ty);
|
||||
walk_list!(visitor, visit_expr, default);
|
||||
walk_list!(visitor, visit_nested_body, default);
|
||||
}
|
||||
TraitItemKind::Method(ref sig, None) => {
|
||||
visitor.visit_id(trait_item.id);
|
||||
@ -846,10 +840,10 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
|
||||
visitor.visit_defaultness(defaultness);
|
||||
walk_list!(visitor, visit_attribute, attrs);
|
||||
match *node {
|
||||
ImplItemKind::Const(ref ty, ref expr) => {
|
||||
ImplItemKind::Const(ref ty, body) => {
|
||||
visitor.visit_id(impl_item.id);
|
||||
visitor.visit_ty(ty);
|
||||
visitor.visit_expr(expr);
|
||||
visitor.visit_nested_body(body);
|
||||
}
|
||||
ImplItemKind::Method(ref sig, body_id) => {
|
||||
visitor.visit_fn(FnKind::Method(impl_item.name,
|
||||
@ -928,9 +922,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
|
||||
ExprArray(ref subexpressions) => {
|
||||
walk_list!(visitor, visit_expr, subexpressions);
|
||||
}
|
||||
ExprRepeat(ref element, ref count) => {
|
||||
ExprRepeat(ref element, count) => {
|
||||
visitor.visit_expr(element);
|
||||
visitor.visit_expr(count)
|
||||
visitor.visit_nested_body(count)
|
||||
}
|
||||
ExprStruct(ref qpath, ref fields, ref optional_base) => {
|
||||
visitor.visit_qpath(qpath, expression.id, expression.span);
|
||||
@ -1037,8 +1031,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visitor.visit_expr_post(expression)
|
||||
}
|
||||
|
||||
pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
|
||||
@ -1125,12 +1117,12 @@ impl<'a, 'ast> Visitor<'ast> for IdRangeComputingVisitor<'a, 'ast> {
|
||||
/// Computes the id range for a single fn body, ignoring nested items.
|
||||
pub fn compute_id_range_for_fn_body<'v>(fk: FnKind<'v>,
|
||||
decl: &'v FnDecl,
|
||||
body: &'v Expr,
|
||||
body: BodyId,
|
||||
sp: Span,
|
||||
id: NodeId,
|
||||
map: &map::Map<'v>)
|
||||
-> IdRange {
|
||||
let mut visitor = IdRangeComputingVisitor::new(map);
|
||||
walk_fn_with_body(&mut visitor, fk, decl, body, sp, id);
|
||||
visitor.visit_fn(fk, decl, body, sp, id);
|
||||
visitor.result()
|
||||
}
|
||||
|
@ -46,8 +46,7 @@ use hir::map::definitions::DefPathData;
|
||||
use hir::def_id::{DefIndex, DefId};
|
||||
use hir::def::{Def, PathResolution};
|
||||
use session::Session;
|
||||
use util::nodemap::NodeMap;
|
||||
use rustc_data_structures::fnv::FnvHashMap;
|
||||
use util::nodemap::{NodeMap, FxHashMap};
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::iter;
|
||||
@ -70,7 +69,6 @@ pub struct LoweringContext<'a> {
|
||||
// the form of a DefIndex) so that if we create a new node which introduces
|
||||
// a definition, then we can properly create the def id.
|
||||
parent_def: Option<DefIndex>,
|
||||
exprs: FnvHashMap<hir::ExprId, hir::Expr>,
|
||||
resolver: &'a mut Resolver,
|
||||
|
||||
/// The items being lowered are collected here.
|
||||
@ -78,6 +76,7 @@ pub struct LoweringContext<'a> {
|
||||
|
||||
trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem>,
|
||||
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
|
||||
bodies: FxHashMap<hir::BodyId, hir::Body>,
|
||||
}
|
||||
|
||||
pub trait Resolver {
|
||||
@ -105,11 +104,11 @@ pub fn lower_crate(sess: &Session,
|
||||
crate_root: std_inject::injected_crate_name(krate),
|
||||
sess: sess,
|
||||
parent_def: None,
|
||||
exprs: FnvHashMap(),
|
||||
resolver: resolver,
|
||||
items: BTreeMap::new(),
|
||||
trait_items: BTreeMap::new(),
|
||||
impl_items: BTreeMap::new(),
|
||||
bodies: FxHashMap(),
|
||||
}.lower_crate(krate)
|
||||
}
|
||||
|
||||
@ -136,7 +135,7 @@ impl<'a> LoweringContext<'a> {
|
||||
items: self.items,
|
||||
trait_items: self.trait_items,
|
||||
impl_items: self.impl_items,
|
||||
exprs: self.exprs,
|
||||
bodies: self.bodies,
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,9 +170,12 @@ impl<'a> LoweringContext<'a> {
|
||||
visit::walk_crate(&mut item_lowerer, c);
|
||||
}
|
||||
|
||||
fn record_expr(&mut self, expr: hir::Expr) -> hir::ExprId {
|
||||
let id = hir::ExprId(expr.id);
|
||||
self.exprs.insert(id, expr);
|
||||
fn record_body(&mut self, value: hir::Expr) -> hir::BodyId {
|
||||
let body = hir::Body {
|
||||
value: value
|
||||
};
|
||||
let id = body.id();
|
||||
self.bodies.insert(id, body);
|
||||
id
|
||||
}
|
||||
|
||||
@ -305,11 +307,14 @@ impl<'a> LoweringContext<'a> {
|
||||
TyKind::ObjectSum(ref ty, ref bounds) => {
|
||||
hir::TyObjectSum(self.lower_ty(ty), self.lower_bounds(bounds))
|
||||
}
|
||||
TyKind::Array(ref ty, ref e) => {
|
||||
hir::TyArray(self.lower_ty(ty), P(self.lower_expr(e)))
|
||||
TyKind::Array(ref ty, ref length) => {
|
||||
let length = self.lower_expr(length);
|
||||
hir::TyArray(self.lower_ty(ty),
|
||||
self.record_body(length))
|
||||
}
|
||||
TyKind::Typeof(ref expr) => {
|
||||
hir::TyTypeof(P(self.lower_expr(expr)))
|
||||
let expr = self.lower_expr(expr);
|
||||
hir::TyTypeof(self.record_body(expr))
|
||||
}
|
||||
TyKind::PolyTraitRef(ref bounds) => {
|
||||
hir::TyPolyTraitRef(self.lower_bounds(bounds))
|
||||
@ -336,7 +341,10 @@ impl<'a> LoweringContext<'a> {
|
||||
name: v.node.name.name,
|
||||
attrs: self.lower_attrs(&v.node.attrs),
|
||||
data: self.lower_variant_data(&v.node.data),
|
||||
disr_expr: v.node.disr_expr.as_ref().map(|e| P(self.lower_expr(e))),
|
||||
disr_expr: v.node.disr_expr.as_ref().map(|e| {
|
||||
let e = self.lower_expr(e);
|
||||
self.record_body(e)
|
||||
}),
|
||||
},
|
||||
span: v.span,
|
||||
}
|
||||
@ -858,17 +866,20 @@ impl<'a> LoweringContext<'a> {
|
||||
hir::ItemUse(path, kind)
|
||||
}
|
||||
ItemKind::Static(ref t, m, ref e) => {
|
||||
let value = self.lower_expr(e);
|
||||
hir::ItemStatic(self.lower_ty(t),
|
||||
self.lower_mutability(m),
|
||||
P(self.lower_expr(e)))
|
||||
self.record_body(value))
|
||||
}
|
||||
ItemKind::Const(ref t, ref e) => {
|
||||
hir::ItemConst(self.lower_ty(t), P(self.lower_expr(e)))
|
||||
let value = self.lower_expr(e);
|
||||
hir::ItemConst(self.lower_ty(t),
|
||||
self.record_body(value))
|
||||
}
|
||||
ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
|
||||
let body = self.lower_block(body);
|
||||
let body = self.expr_block(body, ThinVec::new());
|
||||
let body_id = self.record_expr(body);
|
||||
let body_id = self.record_body(body);
|
||||
hir::ItemFn(self.lower_fn_decl(decl),
|
||||
self.lower_unsafety(unsafety),
|
||||
self.lower_constness(constness),
|
||||
@ -935,14 +946,17 @@ impl<'a> LoweringContext<'a> {
|
||||
node: match i.node {
|
||||
TraitItemKind::Const(ref ty, ref default) => {
|
||||
hir::TraitItemKind::Const(this.lower_ty(ty),
|
||||
default.as_ref().map(|x| P(this.lower_expr(x))))
|
||||
default.as_ref().map(|x| {
|
||||
let value = this.lower_expr(x);
|
||||
this.record_body(value)
|
||||
}))
|
||||
}
|
||||
TraitItemKind::Method(ref sig, ref body) => {
|
||||
hir::TraitItemKind::Method(this.lower_method_sig(sig),
|
||||
body.as_ref().map(|x| {
|
||||
let body = this.lower_block(x);
|
||||
let expr = this.expr_block(body, ThinVec::new());
|
||||
this.record_expr(expr)
|
||||
this.record_body(expr)
|
||||
}))
|
||||
}
|
||||
TraitItemKind::Type(ref bounds, ref default) => {
|
||||
@ -990,13 +1004,15 @@ impl<'a> LoweringContext<'a> {
|
||||
defaultness: this.lower_defaultness(i.defaultness, true /* [1] */),
|
||||
node: match i.node {
|
||||
ImplItemKind::Const(ref ty, ref expr) => {
|
||||
hir::ImplItemKind::Const(this.lower_ty(ty), P(this.lower_expr(expr)))
|
||||
let value = this.lower_expr(expr);
|
||||
let body_id = this.record_body(value);
|
||||
hir::ImplItemKind::Const(this.lower_ty(ty), body_id)
|
||||
}
|
||||
ImplItemKind::Method(ref sig, ref body) => {
|
||||
let body = this.lower_block(body);
|
||||
let expr = this.expr_block(body, ThinVec::new());
|
||||
let expr_id = this.record_expr(expr);
|
||||
hir::ImplItemKind::Method(this.lower_method_sig(sig), expr_id)
|
||||
let body_id = this.record_body(expr);
|
||||
hir::ImplItemKind::Method(this.lower_method_sig(sig), body_id)
|
||||
}
|
||||
ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)),
|
||||
ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
|
||||
@ -1350,8 +1366,8 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
ExprKind::Repeat(ref expr, ref count) => {
|
||||
let expr = P(self.lower_expr(expr));
|
||||
let count = P(self.lower_expr(count));
|
||||
hir::ExprRepeat(expr, count)
|
||||
let count = self.lower_expr(count);
|
||||
hir::ExprRepeat(expr, self.record_body(count))
|
||||
}
|
||||
ExprKind::Tup(ref elts) => {
|
||||
hir::ExprTup(elts.iter().map(|x| self.lower_expr(x)).collect())
|
||||
@ -1434,7 +1450,7 @@ impl<'a> LoweringContext<'a> {
|
||||
let expr = this.lower_expr(body);
|
||||
hir::ExprClosure(this.lower_capture_clause(capture_clause),
|
||||
this.lower_fn_decl(decl),
|
||||
this.record_expr(expr),
|
||||
this.record_body(expr),
|
||||
fn_decl_span)
|
||||
})
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; }
|
||||
/// Components shared by fn-like things (fn items, methods, closures).
|
||||
pub struct FnParts<'a> {
|
||||
pub decl: &'a FnDecl,
|
||||
pub body: ast::ExprId,
|
||||
pub body: ast::BodyId,
|
||||
pub kind: FnKind<'a>,
|
||||
pub span: Span,
|
||||
pub id: NodeId,
|
||||
@ -115,7 +115,7 @@ struct ItemFnParts<'a> {
|
||||
abi: abi::Abi,
|
||||
vis: &'a ast::Visibility,
|
||||
generics: &'a ast::Generics,
|
||||
body: ast::ExprId,
|
||||
body: ast::BodyId,
|
||||
id: NodeId,
|
||||
span: Span,
|
||||
attrs: &'a [Attribute],
|
||||
@ -125,14 +125,14 @@ struct ItemFnParts<'a> {
|
||||
/// for use when implementing FnLikeNode operations.
|
||||
struct ClosureParts<'a> {
|
||||
decl: &'a FnDecl,
|
||||
body: ast::ExprId,
|
||||
body: ast::BodyId,
|
||||
id: NodeId,
|
||||
span: Span,
|
||||
attrs: &'a [Attribute],
|
||||
}
|
||||
|
||||
impl<'a> ClosureParts<'a> {
|
||||
fn new(d: &'a FnDecl, b: ast::ExprId, id: NodeId, s: Span, attrs: &'a [Attribute]) -> Self {
|
||||
fn new(d: &'a FnDecl, b: ast::BodyId, id: NodeId, s: Span, attrs: &'a [Attribute]) -> Self {
|
||||
ClosureParts {
|
||||
decl: d,
|
||||
body: b,
|
||||
@ -172,9 +172,9 @@ impl<'a> FnLikeNode<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn body(self) -> ast::ExprId {
|
||||
pub fn body(self) -> ast::BodyId {
|
||||
self.handle(|i: ItemFnParts<'a>| i.body,
|
||||
|_, _, _: &'a ast::MethodSig, _, body: ast::ExprId, _, _| body,
|
||||
|_, _, _: &'a ast::MethodSig, _, body: ast::BodyId, _, _| body,
|
||||
|c: ClosureParts<'a>| c.body)
|
||||
}
|
||||
|
||||
@ -227,7 +227,7 @@ impl<'a> FnLikeNode<'a> {
|
||||
Name,
|
||||
&'a ast::MethodSig,
|
||||
Option<&'a ast::Visibility>,
|
||||
ast::ExprId,
|
||||
ast::BodyId,
|
||||
Span,
|
||||
&'a [Attribute])
|
||||
-> A,
|
||||
|
@ -99,15 +99,21 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
||||
}
|
||||
|
||||
fn visit_nested_trait_item(&mut self, item_id: TraitItemId) {
|
||||
self.visit_trait_item(self.krate.trait_item(item_id))
|
||||
if !self.ignore_nested_items {
|
||||
self.visit_trait_item(self.krate.trait_item(item_id))
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
|
||||
self.visit_impl_item(self.krate.impl_item(item_id))
|
||||
if !self.ignore_nested_items {
|
||||
self.visit_impl_item(self.krate.impl_item(item_id))
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_body(&mut self, id: ExprId) {
|
||||
self.visit_expr(self.krate.expr(id))
|
||||
fn visit_nested_body(&mut self, id: BodyId) {
|
||||
if !self.ignore_nested_items {
|
||||
self.visit_body(self.krate.body(id))
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, i: &'ast Item) {
|
||||
@ -117,11 +123,6 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
||||
|
||||
self.with_parent(i.id, |this| {
|
||||
match i.node {
|
||||
ItemEnum(ref enum_definition, _) => {
|
||||
for v in &enum_definition.variants {
|
||||
this.insert(v.node.data.id(), NodeVariant(v));
|
||||
}
|
||||
}
|
||||
ItemStruct(ref struct_def, _) => {
|
||||
// If this is a tuple-like struct, register the constructor.
|
||||
if !struct_def.is_struct() {
|
||||
@ -213,7 +214,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl,
|
||||
b: ExprId, s: Span, id: NodeId) {
|
||||
b: BodyId, s: Span, id: NodeId) {
|
||||
assert_eq!(self.parent_node, id);
|
||||
intravisit::walk_fn(self, fk, fd, b, s, id);
|
||||
}
|
||||
@ -247,6 +248,14 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
||||
self.insert_entry(macro_def.id, NotPresent);
|
||||
}
|
||||
|
||||
fn visit_variant(&mut self, v: &'ast Variant, g: &'ast Generics, item_id: NodeId) {
|
||||
let id = v.node.data.id();
|
||||
self.insert(id, NodeVariant(v));
|
||||
self.with_parent(id, |this| {
|
||||
intravisit::walk_variant(this, v, g, item_id);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_struct_field(&mut self, field: &'ast StructField) {
|
||||
self.insert(field.id, NodeField(field));
|
||||
self.with_parent(field.id, |this| {
|
||||
|
@ -16,7 +16,7 @@ use syntax::ext::hygiene::Mark;
|
||||
use syntax::visit;
|
||||
use syntax::symbol::{Symbol, keywords};
|
||||
|
||||
/// Creates def ids for nodes in the HIR.
|
||||
/// Creates def ids for nodes in the AST.
|
||||
pub struct DefCollector<'a> {
|
||||
definitions: &'a mut Definitions,
|
||||
parent_def: Option<DefIndex>,
|
||||
|
@ -220,7 +220,6 @@ impl DefPath {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
||||
pub enum DefPathData {
|
||||
// Root: these should only be used for the root nodes, because
|
||||
@ -339,7 +338,7 @@ impl Definitions {
|
||||
data,
|
||||
self.table.def_key(self.node_to_def_index[&node_id]));
|
||||
|
||||
assert!(parent.is_some() ^ (data == DefPathData::CrateRoot));
|
||||
assert_eq!(parent.is_some(), data != DefPathData::CrateRoot);
|
||||
|
||||
// Find a unique DefKey. This basically means incrementing the disambiguator
|
||||
// until we get no match.
|
||||
|
@ -266,7 +266,6 @@ impl<'ast> Map<'ast> {
|
||||
|
||||
EntryTraitItem(_, item) => {
|
||||
let def_id = self.local_def_id(id);
|
||||
assert!(!self.is_inlined_def_id(def_id));
|
||||
|
||||
if let Some(last_id) = last_expr {
|
||||
// The body of the item may have a separate dep node
|
||||
@ -289,8 +288,19 @@ impl<'ast> Map<'ast> {
|
||||
return DepNode::Hir(def_id);
|
||||
}
|
||||
|
||||
EntryVariant(p, v) => {
|
||||
id = p;
|
||||
|
||||
if last_expr.is_some() {
|
||||
if v.node.disr_expr.map(|e| e.node_id) == last_expr {
|
||||
// The enum parent holds both Hir and HirBody nodes.
|
||||
let def_id = self.local_def_id(id);
|
||||
return DepNode::HirBody(def_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EntryForeignItem(p, _) |
|
||||
EntryVariant(p, _) |
|
||||
EntryField(p, _) |
|
||||
EntryStmt(p, _) |
|
||||
EntryTy(p, _) |
|
||||
@ -317,7 +327,7 @@ impl<'ast> Map<'ast> {
|
||||
bug!("node {} has inlined ancestor but is not inlined", id0),
|
||||
|
||||
NotPresent =>
|
||||
// Some nodes, notably struct fields, are not
|
||||
// Some nodes, notably macro definitions, are not
|
||||
// present in the map for whatever reason, but
|
||||
// they *do* have def-ids. So if we encounter an
|
||||
// empty hole, check for that case.
|
||||
@ -369,21 +379,25 @@ impl<'ast> Map<'ast> {
|
||||
|
||||
fn is_item_body(&self, node_id: NodeId, item: &Item) -> bool {
|
||||
match item.node {
|
||||
ItemFn(_, _, _, _, _, body) => body.node_id() == node_id,
|
||||
ItemConst(_, body) |
|
||||
ItemStatic(.., body) |
|
||||
ItemFn(_, _, _, _, _, body) => body.node_id == node_id,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_trait_item_body(&self, node_id: NodeId, item: &TraitItem) -> bool {
|
||||
match item.node {
|
||||
TraitItemKind::Method(_, Some(body)) => body.node_id() == node_id,
|
||||
TraitItemKind::Const(_, Some(body)) |
|
||||
TraitItemKind::Method(_, Some(body)) => body.node_id == node_id,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_impl_item_body(&self, node_id: NodeId, item: &ImplItem) -> bool {
|
||||
match item.node {
|
||||
ImplItemKind::Method(_, body) => body.node_id() == node_id,
|
||||
ImplItemKind::Const(_, body) |
|
||||
ImplItemKind::Method(_, body) => body.node_id == node_id,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
@ -459,6 +473,14 @@ impl<'ast> Map<'ast> {
|
||||
self.forest.krate.impl_item(id)
|
||||
}
|
||||
|
||||
pub fn body(&self, id: BodyId) -> &'ast Body {
|
||||
self.read(id.node_id);
|
||||
|
||||
// NB: intentionally bypass `self.forest.krate()` so that we
|
||||
// do not trigger a read of the whole krate here
|
||||
self.forest.krate.body(id)
|
||||
}
|
||||
|
||||
/// Get the attributes on the krate. This is preferable to
|
||||
/// invoking `krate.attrs` because it registers a tighter
|
||||
/// dep-graph access.
|
||||
@ -709,10 +731,6 @@ impl<'ast> Map<'ast> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expr(&self, id: ExprId) -> &'ast Expr {
|
||||
self.expect_expr(id.node_id())
|
||||
}
|
||||
|
||||
/// Returns the name associated with the given NodeId's AST.
|
||||
pub fn name(&self, id: NodeId) -> Name {
|
||||
match self.get(id) {
|
||||
@ -793,7 +811,7 @@ impl<'ast> Map<'ast> {
|
||||
Some(EntryVisibility(_, v)) => bug!("unexpected Visibility {:?}", v),
|
||||
|
||||
Some(RootCrate) => self.forest.krate.span,
|
||||
Some(RootInlinedParent(parent)) => parent.body.span,
|
||||
Some(RootInlinedParent(parent)) => parent.body.value.span,
|
||||
Some(NotPresent) | None => {
|
||||
bug!("hir::map::Map::span: id not in map: {:?}", id)
|
||||
}
|
||||
|
@ -31,8 +31,7 @@ pub use self::PathParameters::*;
|
||||
|
||||
use hir::def::Def;
|
||||
use hir::def_id::DefId;
|
||||
use util::nodemap::{NodeMap, FxHashSet};
|
||||
use rustc_data_structures::fnv::FnvHashMap;
|
||||
use util::nodemap::{NodeMap, FxHashMap, FxHashSet};
|
||||
|
||||
use syntax_pos::{Span, ExpnId, DUMMY_SP};
|
||||
use syntax::codemap::{self, Spanned};
|
||||
@ -40,7 +39,7 @@ use syntax::abi::Abi;
|
||||
use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, AsmDialect};
|
||||
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
|
||||
use syntax::ptr::P;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax::symbol::{Symbol, keywords};
|
||||
use syntax::tokenstream::TokenTree;
|
||||
use syntax::util::ThinVec;
|
||||
|
||||
@ -432,7 +431,7 @@ pub struct Crate {
|
||||
|
||||
pub trait_items: BTreeMap<TraitItemId, TraitItem>,
|
||||
pub impl_items: BTreeMap<ImplItemId, ImplItem>,
|
||||
pub exprs: FnvHashMap<ExprId, Expr>,
|
||||
pub bodies: FxHashMap<BodyId, Body>,
|
||||
}
|
||||
|
||||
impl Crate {
|
||||
@ -472,8 +471,8 @@ impl Crate {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expr(&self, id: ExprId) -> &Expr {
|
||||
&self.exprs[&id]
|
||||
pub fn body(&self, id: BodyId) -> &Body {
|
||||
&self.bodies[&id]
|
||||
}
|
||||
}
|
||||
|
||||
@ -862,11 +861,21 @@ pub enum UnsafeSource {
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct ExprId(NodeId);
|
||||
pub struct BodyId {
|
||||
pub node_id: NodeId,
|
||||
}
|
||||
|
||||
impl ExprId {
|
||||
pub fn node_id(self) -> NodeId {
|
||||
self.0
|
||||
/// The body of a function or constant value.
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct Body {
|
||||
pub value: Expr
|
||||
}
|
||||
|
||||
impl Body {
|
||||
pub fn id(&self) -> BodyId {
|
||||
BodyId {
|
||||
node_id: self.value.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -879,12 +888,6 @@ pub struct Expr {
|
||||
pub attrs: ThinVec<Attribute>,
|
||||
}
|
||||
|
||||
impl Expr {
|
||||
pub fn expr_id(&self) -> ExprId {
|
||||
ExprId(self.id)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Expr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "expr({}: {})", self.id, print::expr_to_string(self))
|
||||
@ -944,7 +947,7 @@ pub enum Expr_ {
|
||||
/// A closure (for example, `move |a, b, c| {a + b + c}`).
|
||||
///
|
||||
/// The final span is the span of the argument block `|...|`
|
||||
ExprClosure(CaptureClause, P<FnDecl>, ExprId, Span),
|
||||
ExprClosure(CaptureClause, P<FnDecl>, BodyId, Span),
|
||||
/// A block (`{ ... }`)
|
||||
ExprBlock(P<Block>),
|
||||
|
||||
@ -988,7 +991,7 @@ pub enum Expr_ {
|
||||
///
|
||||
/// For example, `[1; 5]`. The first expression is the element
|
||||
/// to be repeated; the second is the number of times to repeat it.
|
||||
ExprRepeat(P<Expr>, P<Expr>),
|
||||
ExprRepeat(P<Expr>, BodyId),
|
||||
}
|
||||
|
||||
/// Optionally `Self`-qualified value/type path or associated extension.
|
||||
@ -1104,9 +1107,9 @@ pub struct TraitItem {
|
||||
pub enum TraitItemKind {
|
||||
/// An associated constant with an optional value (otherwise `impl`s
|
||||
/// must contain a value)
|
||||
Const(P<Ty>, Option<P<Expr>>),
|
||||
Const(P<Ty>, Option<BodyId>),
|
||||
/// A method with an optional body
|
||||
Method(MethodSig, Option<ExprId>),
|
||||
Method(MethodSig, Option<BodyId>),
|
||||
/// An associated type with (possibly empty) bounds and optional concrete
|
||||
/// type
|
||||
Type(TyParamBounds, Option<P<Ty>>),
|
||||
@ -1137,9 +1140,9 @@ pub struct ImplItem {
|
||||
pub enum ImplItemKind {
|
||||
/// An associated constant of the given type, set to the constant result
|
||||
/// of the expression
|
||||
Const(P<Ty>, P<Expr>),
|
||||
Const(P<Ty>, BodyId),
|
||||
/// A method implementation with the given signature and body
|
||||
Method(MethodSig, ExprId),
|
||||
Method(MethodSig, BodyId),
|
||||
/// An associated type
|
||||
Type(P<Ty>),
|
||||
}
|
||||
@ -1192,7 +1195,7 @@ pub enum Ty_ {
|
||||
/// A variable length slice (`[T]`)
|
||||
TySlice(P<Ty>),
|
||||
/// A fixed length array (`[T; n]`)
|
||||
TyArray(P<Ty>, P<Expr>),
|
||||
TyArray(P<Ty>, BodyId),
|
||||
/// A raw pointer (`*const T` or `*mut T`)
|
||||
TyPtr(MutTy),
|
||||
/// A reference (`&'a T` or `&'a mut T`)
|
||||
@ -1216,7 +1219,7 @@ pub enum Ty_ {
|
||||
/// An `impl TraitA+TraitB` type.
|
||||
TyImplTrait(TyParamBounds),
|
||||
/// Unused for now
|
||||
TyTypeof(P<Expr>),
|
||||
TyTypeof(BodyId),
|
||||
/// TyInfer means the type should be inferred instead of it having been
|
||||
/// specified. This can appear anywhere in a type.
|
||||
TyInfer,
|
||||
@ -1371,7 +1374,7 @@ pub struct Variant_ {
|
||||
pub attrs: HirVec<Attribute>,
|
||||
pub data: VariantData,
|
||||
/// Explicit discriminant, eg `Foo = 1`
|
||||
pub disr_expr: Option<P<Expr>>,
|
||||
pub disr_expr: Option<BodyId>,
|
||||
}
|
||||
|
||||
pub type Variant = Spanned<Variant_>;
|
||||
@ -1530,11 +1533,11 @@ pub enum Item_ {
|
||||
ItemUse(P<Path>, UseKind),
|
||||
|
||||
/// A `static` item
|
||||
ItemStatic(P<Ty>, Mutability, P<Expr>),
|
||||
ItemStatic(P<Ty>, Mutability, BodyId),
|
||||
/// A `const` item
|
||||
ItemConst(P<Ty>, P<Expr>),
|
||||
ItemConst(P<Ty>, BodyId),
|
||||
/// A function declaration
|
||||
ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, ExprId),
|
||||
ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, BodyId),
|
||||
/// A module
|
||||
ItemMod(Mod),
|
||||
/// An external module
|
||||
|
@ -462,7 +462,7 @@ impl<'a> State<'a> {
|
||||
|
||||
pub fn print_mod(&mut self, _mod: &hir::Mod, attrs: &[ast::Attribute]) -> io::Result<()> {
|
||||
self.print_inner_attributes(attrs)?;
|
||||
for item_id in &_mod.item_ids {
|
||||
for &item_id in &_mod.item_ids {
|
||||
self.print_item_id(item_id)?;
|
||||
}
|
||||
Ok(())
|
||||
@ -545,16 +545,16 @@ impl<'a> State<'a> {
|
||||
hir::TyImplTrait(ref bounds) => {
|
||||
self.print_bounds("impl ", &bounds[..])?;
|
||||
}
|
||||
hir::TyArray(ref ty, ref v) => {
|
||||
hir::TyArray(ref ty, v) => {
|
||||
word(&mut self.s, "[")?;
|
||||
self.print_type(&ty)?;
|
||||
word(&mut self.s, "; ")?;
|
||||
self.print_expr(&v)?;
|
||||
self.print_body_id(v)?;
|
||||
word(&mut self.s, "]")?;
|
||||
}
|
||||
hir::TyTypeof(ref e) => {
|
||||
hir::TyTypeof(e) => {
|
||||
word(&mut self.s, "typeof(")?;
|
||||
self.print_expr(&e)?;
|
||||
self.print_body_id(e)?;
|
||||
word(&mut self.s, ")")?;
|
||||
}
|
||||
hir::TyInfer => {
|
||||
@ -600,7 +600,7 @@ impl<'a> State<'a> {
|
||||
fn print_associated_const(&mut self,
|
||||
name: ast::Name,
|
||||
ty: &hir::Ty,
|
||||
default: Option<&hir::Expr>,
|
||||
default: Option<hir::BodyId>,
|
||||
vis: &hir::Visibility)
|
||||
-> io::Result<()> {
|
||||
word(&mut self.s, &visibility_qualified(vis, ""))?;
|
||||
@ -611,7 +611,7 @@ impl<'a> State<'a> {
|
||||
if let Some(expr) = default {
|
||||
space(&mut self.s)?;
|
||||
self.word_space("=")?;
|
||||
self.print_expr(expr)?;
|
||||
self.print_body_id(expr)?;
|
||||
}
|
||||
word(&mut self.s, ";")
|
||||
}
|
||||
@ -634,7 +634,7 @@ impl<'a> State<'a> {
|
||||
word(&mut self.s, ";")
|
||||
}
|
||||
|
||||
pub fn print_item_id(&mut self, item_id: &hir::ItemId) -> io::Result<()> {
|
||||
pub fn print_item_id(&mut self, item_id: hir::ItemId) -> io::Result<()> {
|
||||
if let Some(krate) = self.krate {
|
||||
// skip nested items if krate context was not provided
|
||||
let item = &krate.items[&item_id.id];
|
||||
@ -644,9 +644,9 @@ impl<'a> State<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_expr_id(&mut self, expr_id: &hir::ExprId) -> io::Result<()> {
|
||||
fn print_body_id(&mut self, body_id: hir::BodyId) -> io::Result<()> {
|
||||
if let Some(krate) = self.krate {
|
||||
let expr = &krate.exprs[expr_id];
|
||||
let expr = &krate.body(body_id).value;
|
||||
self.print_expr(expr)
|
||||
} else {
|
||||
Ok(())
|
||||
@ -697,7 +697,7 @@ impl<'a> State<'a> {
|
||||
self.end()?; // end inner head-block
|
||||
self.end()?; // end outer head-block
|
||||
}
|
||||
hir::ItemStatic(ref ty, m, ref expr) => {
|
||||
hir::ItemStatic(ref ty, m, expr) => {
|
||||
self.head(&visibility_qualified(&item.vis, "static"))?;
|
||||
if m == hir::MutMutable {
|
||||
self.word_space("mut")?;
|
||||
@ -709,11 +709,11 @@ impl<'a> State<'a> {
|
||||
self.end()?; // end the head-ibox
|
||||
|
||||
self.word_space("=")?;
|
||||
self.print_expr(&expr)?;
|
||||
self.print_body_id(expr)?;
|
||||
word(&mut self.s, ";")?;
|
||||
self.end()?; // end the outer cbox
|
||||
}
|
||||
hir::ItemConst(ref ty, ref expr) => {
|
||||
hir::ItemConst(ref ty, expr) => {
|
||||
self.head(&visibility_qualified(&item.vis, "const"))?;
|
||||
self.print_name(item.name)?;
|
||||
self.word_space(":")?;
|
||||
@ -722,11 +722,11 @@ impl<'a> State<'a> {
|
||||
self.end()?; // end the head-ibox
|
||||
|
||||
self.word_space("=")?;
|
||||
self.print_expr(&expr)?;
|
||||
self.print_body_id(expr)?;
|
||||
word(&mut self.s, ";")?;
|
||||
self.end()?; // end the outer cbox
|
||||
}
|
||||
hir::ItemFn(ref decl, unsafety, constness, abi, ref typarams, ref body) => {
|
||||
hir::ItemFn(ref decl, unsafety, constness, abi, ref typarams, body) => {
|
||||
self.head("")?;
|
||||
self.print_fn(decl,
|
||||
unsafety,
|
||||
@ -738,7 +738,7 @@ impl<'a> State<'a> {
|
||||
word(&mut self.s, " ")?;
|
||||
self.end()?; // need to close a box
|
||||
self.end()?; // need to close a box
|
||||
self.print_expr_id(body)?;
|
||||
self.print_body_id(body)?;
|
||||
}
|
||||
hir::ItemMod(ref _mod) => {
|
||||
self.head(&visibility_qualified(&item.vis, "mod"))?;
|
||||
@ -985,14 +985,12 @@ impl<'a> State<'a> {
|
||||
self.head("")?;
|
||||
let generics = hir::Generics::empty();
|
||||
self.print_struct(&v.node.data, &generics, v.node.name, v.span, false)?;
|
||||
match v.node.disr_expr {
|
||||
Some(ref d) => {
|
||||
space(&mut self.s)?;
|
||||
self.word_space("=")?;
|
||||
self.print_expr(&d)
|
||||
}
|
||||
_ => Ok(()),
|
||||
if let Some(d) = v.node.disr_expr {
|
||||
space(&mut self.s)?;
|
||||
self.word_space("=")?;
|
||||
self.print_body_id(d)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn print_method_sig(&mut self,
|
||||
name: ast::Name,
|
||||
@ -1024,22 +1022,19 @@ impl<'a> State<'a> {
|
||||
self.maybe_print_comment(ti.span.lo)?;
|
||||
self.print_outer_attributes(&ti.attrs)?;
|
||||
match ti.node {
|
||||
hir::TraitItemKind::Const(ref ty, ref default) => {
|
||||
self.print_associated_const(ti.name,
|
||||
&ty,
|
||||
default.as_ref().map(|expr| &**expr),
|
||||
&hir::Inherited)?;
|
||||
hir::TraitItemKind::Const(ref ty, default) => {
|
||||
self.print_associated_const(ti.name, &ty, default, &hir::Inherited)?;
|
||||
}
|
||||
hir::TraitItemKind::Method(ref sig, ref body) => {
|
||||
hir::TraitItemKind::Method(ref sig, body) => {
|
||||
if body.is_some() {
|
||||
self.head("")?;
|
||||
}
|
||||
self.print_method_sig(ti.name, sig, &hir::Inherited)?;
|
||||
if let Some(ref body) = *body {
|
||||
if let Some(body) = body {
|
||||
self.nbsp()?;
|
||||
self.end()?; // need to close a box
|
||||
self.end()?; // need to close a box
|
||||
self.print_expr_id(body)?;
|
||||
self.print_body_id(body)?;
|
||||
} else {
|
||||
word(&mut self.s, ";")?;
|
||||
}
|
||||
@ -1075,16 +1070,16 @@ impl<'a> State<'a> {
|
||||
}
|
||||
|
||||
match ii.node {
|
||||
hir::ImplItemKind::Const(ref ty, ref expr) => {
|
||||
self.print_associated_const(ii.name, &ty, Some(&expr), &ii.vis)?;
|
||||
hir::ImplItemKind::Const(ref ty, expr) => {
|
||||
self.print_associated_const(ii.name, &ty, Some(expr), &ii.vis)?;
|
||||
}
|
||||
hir::ImplItemKind::Method(ref sig, ref body) => {
|
||||
hir::ImplItemKind::Method(ref sig, body) => {
|
||||
self.head("")?;
|
||||
self.print_method_sig(ii.name, sig, &ii.vis)?;
|
||||
self.nbsp()?;
|
||||
self.end()?; // need to close a box
|
||||
self.end()?; // need to close a box
|
||||
self.print_expr_id(body)?;
|
||||
self.print_body_id(body)?;
|
||||
}
|
||||
hir::ImplItemKind::Type(ref ty) => {
|
||||
self.print_associated_type(ii.name, None, Some(ty))?;
|
||||
@ -1256,12 +1251,12 @@ impl<'a> State<'a> {
|
||||
self.end()
|
||||
}
|
||||
|
||||
fn print_expr_repeat(&mut self, element: &hir::Expr, count: &hir::Expr) -> io::Result<()> {
|
||||
fn print_expr_repeat(&mut self, element: &hir::Expr, count: hir::BodyId) -> io::Result<()> {
|
||||
self.ibox(indent_unit)?;
|
||||
word(&mut self.s, "[")?;
|
||||
self.print_expr(element)?;
|
||||
self.word_space(";")?;
|
||||
self.print_expr(count)?;
|
||||
self.print_body_id(count)?;
|
||||
word(&mut self.s, "]")?;
|
||||
self.end()
|
||||
}
|
||||
@ -1372,8 +1367,8 @@ impl<'a> State<'a> {
|
||||
hir::ExprArray(ref exprs) => {
|
||||
self.print_expr_vec(exprs)?;
|
||||
}
|
||||
hir::ExprRepeat(ref element, ref count) => {
|
||||
self.print_expr_repeat(&element, &count)?;
|
||||
hir::ExprRepeat(ref element, count) => {
|
||||
self.print_expr_repeat(&element, count)?;
|
||||
}
|
||||
hir::ExprStruct(ref qpath, ref fields, ref wth) => {
|
||||
self.print_expr_struct(qpath, &fields[..], wth)?;
|
||||
@ -1444,14 +1439,14 @@ impl<'a> State<'a> {
|
||||
}
|
||||
self.bclose_(expr.span, indent_unit)?;
|
||||
}
|
||||
hir::ExprClosure(capture_clause, ref decl, ref body, _fn_decl_span) => {
|
||||
hir::ExprClosure(capture_clause, ref decl, body, _fn_decl_span) => {
|
||||
self.print_capture_clause(capture_clause)?;
|
||||
|
||||
self.print_fn_block_args(&decl)?;
|
||||
space(&mut self.s)?;
|
||||
|
||||
// this is a bare expression
|
||||
self.print_expr_id(body)?;
|
||||
self.print_body_id(body)?;
|
||||
self.end()?; // need to close a box
|
||||
|
||||
// a box will be closed by print_expr, but we didn't want an overall
|
||||
@ -1625,7 +1620,7 @@ impl<'a> State<'a> {
|
||||
}
|
||||
self.end()
|
||||
}
|
||||
hir::DeclItem(ref item) => {
|
||||
hir::DeclItem(item) => {
|
||||
self.print_item_id(item)
|
||||
}
|
||||
}
|
||||
|
@ -821,6 +821,7 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
||||
self.with_lint_attrs(&e.attrs, |cx| {
|
||||
run_lints!(cx, check_expr, late_passes, e);
|
||||
hir_visit::walk_expr(cx, e);
|
||||
run_lints!(cx, check_expr_post, late_passes, e);
|
||||
})
|
||||
}
|
||||
|
||||
@ -835,8 +836,8 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: hir_visit::FnKind<'tcx>, decl: &'tcx hir::FnDecl,
|
||||
body_id: hir::ExprId, span: Span, id: ast::NodeId) {
|
||||
let body = self.tcx.map.expr(body_id);
|
||||
body_id: hir::BodyId, span: Span, id: ast::NodeId) {
|
||||
let body = self.tcx.map.body(body_id);
|
||||
run_lints!(self, check_fn, late_passes, fk, decl, body, span, id);
|
||||
hir_visit::walk_fn(self, fk, decl, body_id, span, id);
|
||||
run_lints!(self, check_fn_post, late_passes, fk, decl, body, span, id);
|
||||
@ -909,10 +910,6 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
||||
hir_visit::walk_decl(self, d);
|
||||
}
|
||||
|
||||
fn visit_expr_post(&mut self, e: &'tcx hir::Expr) {
|
||||
run_lints!(self, check_expr_post, late_passes, e);
|
||||
}
|
||||
|
||||
fn visit_generics(&mut self, g: &'tcx hir::Generics) {
|
||||
run_lints!(self, check_generics, late_passes, g);
|
||||
hir_visit::walk_generics(self, g);
|
||||
|
@ -162,14 +162,14 @@ pub trait LateLintPass<'a, 'tcx>: LintPass {
|
||||
_: &LateContext<'a, 'tcx>,
|
||||
_: FnKind<'tcx>,
|
||||
_: &'tcx hir::FnDecl,
|
||||
_: &'tcx hir::Expr,
|
||||
_: &'tcx hir::Body,
|
||||
_: Span,
|
||||
_: ast::NodeId) { }
|
||||
fn check_fn_post(&mut self,
|
||||
_: &LateContext<'a, 'tcx>,
|
||||
_: FnKind<'tcx>,
|
||||
_: &'tcx hir::FnDecl,
|
||||
_: &'tcx hir::Expr,
|
||||
_: &'tcx hir::Body,
|
||||
_: Span,
|
||||
_: ast::NodeId) { }
|
||||
fn check_trait_item(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::TraitItem) { }
|
||||
|
@ -38,7 +38,6 @@ use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::ext::base::SyntaxExtension;
|
||||
use syntax::ptr::P;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos::Span;
|
||||
use rustc_back::target::Target;
|
||||
@ -140,7 +139,7 @@ pub struct NativeLibrary {
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct InlinedItem {
|
||||
pub def_id: DefId,
|
||||
pub body: P<hir::Expr>,
|
||||
pub body: hir::Body,
|
||||
pub const_fn_args: Vec<Option<DefId>>,
|
||||
}
|
||||
|
||||
@ -149,7 +148,7 @@ pub struct InlinedItem {
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, Hash, Debug)]
|
||||
pub struct InlinedItemRef<'a> {
|
||||
pub def_id: DefId,
|
||||
pub body: &'a hir::Expr,
|
||||
pub body: &'a hir::Body,
|
||||
pub const_fn_args: Vec<Option<DefId>>,
|
||||
}
|
||||
|
||||
@ -160,31 +159,31 @@ fn get_fn_args(decl: &hir::FnDecl) -> Vec<Option<DefId>> {
|
||||
}).collect()
|
||||
}
|
||||
|
||||
impl<'a> InlinedItemRef<'a> {
|
||||
pub fn from_item<'b, 'tcx>(def_id: DefId,
|
||||
item: &'a hir::Item,
|
||||
tcx: TyCtxt<'b, 'a, 'tcx>)
|
||||
-> InlinedItemRef<'a> {
|
||||
let (body, args) = match item.node {
|
||||
impl<'a, 'tcx> InlinedItemRef<'tcx> {
|
||||
pub fn from_item(def_id: DefId,
|
||||
item: &hir::Item,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||
-> InlinedItemRef<'tcx> {
|
||||
let (body_id, args) = match item.node {
|
||||
hir::ItemFn(ref decl, _, _, _, _, body_id) =>
|
||||
(tcx.map.expr(body_id), get_fn_args(decl)),
|
||||
hir::ItemConst(_, ref body) => (&**body, Vec::new()),
|
||||
(body_id, get_fn_args(decl)),
|
||||
hir::ItemConst(_, body_id) => (body_id, vec![]),
|
||||
_ => bug!("InlinedItemRef::from_item wrong kind")
|
||||
};
|
||||
InlinedItemRef {
|
||||
def_id: def_id,
|
||||
body: body,
|
||||
body: tcx.map.body(body_id),
|
||||
const_fn_args: args
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_trait_item(def_id: DefId,
|
||||
item: &'a hir::TraitItem,
|
||||
_tcx: TyCtxt)
|
||||
-> InlinedItemRef<'a> {
|
||||
let (body, args) = match item.node {
|
||||
hir::TraitItemKind::Const(_, Some(ref body)) =>
|
||||
(&**body, Vec::new()),
|
||||
item: &hir::TraitItem,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||
-> InlinedItemRef<'tcx> {
|
||||
let (body_id, args) = match item.node {
|
||||
hir::TraitItemKind::Const(_, Some(body_id)) =>
|
||||
(body_id, vec![]),
|
||||
hir::TraitItemKind::Const(_, None) => {
|
||||
bug!("InlinedItemRef::from_trait_item called for const without body")
|
||||
},
|
||||
@ -192,33 +191,33 @@ impl<'a> InlinedItemRef<'a> {
|
||||
};
|
||||
InlinedItemRef {
|
||||
def_id: def_id,
|
||||
body: body,
|
||||
body: tcx.map.body(body_id),
|
||||
const_fn_args: args
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_impl_item<'b, 'tcx>(def_id: DefId,
|
||||
item: &'a hir::ImplItem,
|
||||
tcx: TyCtxt<'b, 'a, 'tcx>)
|
||||
-> InlinedItemRef<'a> {
|
||||
let (body, args) = match item.node {
|
||||
pub fn from_impl_item(def_id: DefId,
|
||||
item: &hir::ImplItem,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||
-> InlinedItemRef<'tcx> {
|
||||
let (body_id, args) = match item.node {
|
||||
hir::ImplItemKind::Method(ref sig, body_id) =>
|
||||
(tcx.map.expr(body_id), get_fn_args(&sig.decl)),
|
||||
hir::ImplItemKind::Const(_, ref body) =>
|
||||
(&**body, Vec::new()),
|
||||
(body_id, get_fn_args(&sig.decl)),
|
||||
hir::ImplItemKind::Const(_, body_id) =>
|
||||
(body_id, vec![]),
|
||||
_ => bug!("InlinedItemRef::from_impl_item wrong kind")
|
||||
};
|
||||
InlinedItemRef {
|
||||
def_id: def_id,
|
||||
body: body,
|
||||
body: tcx.map.body(body_id),
|
||||
const_fn_args: args
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit<V>(&self, visitor: &mut V)
|
||||
where V: Visitor<'a>
|
||||
where V: Visitor<'tcx>
|
||||
{
|
||||
visitor.visit_expr(&self.body);
|
||||
visitor.visit_body(self.body);
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,7 +225,7 @@ impl InlinedItem {
|
||||
pub fn visit<'ast,V>(&'ast self, visitor: &mut V)
|
||||
where V: Visitor<'ast>
|
||||
{
|
||||
visitor.visit_expr(&self.body);
|
||||
visitor.visit_body(&self.body);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ fn build_nodeid_to_index(decl: Option<&hir::FnDecl>,
|
||||
intravisit::walk_fn_decl(&mut formals, decl);
|
||||
impl<'a, 'v> intravisit::Visitor<'v> for Formals<'a> {
|
||||
fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'v> {
|
||||
panic!("should not encounter fn bodies or items")
|
||||
intravisit::NestedVisitorMap::None
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, p: &hir::Pat) {
|
||||
@ -502,7 +502,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
|
||||
|
||||
impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> {
|
||||
// ^^^^^^^^^^^^^ only needed for pretty printing
|
||||
pub fn propagate(&mut self, cfg: &cfg::CFG, body: &hir::Expr) {
|
||||
pub fn propagate(&mut self, cfg: &cfg::CFG, body: &hir::Body) {
|
||||
//! Performs the data flow analysis.
|
||||
|
||||
if self.bits_per_id == 0 {
|
||||
@ -534,11 +534,11 @@ impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> {
|
||||
}
|
||||
|
||||
fn pretty_print_to<'b>(&self, wr: Box<io::Write + 'b>,
|
||||
body: &hir::Expr) -> io::Result<()> {
|
||||
body: &hir::Body) -> io::Result<()> {
|
||||
let mut ps = pprust::rust_printer_annotated(wr, self, None);
|
||||
ps.cbox(pprust::indent_unit)?;
|
||||
ps.ibox(0)?;
|
||||
ps.print_expr(body)?;
|
||||
ps.print_expr(&body.value)?;
|
||||
pp::eof(&mut ps.s)
|
||||
}
|
||||
}
|
||||
|
@ -551,19 +551,19 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
|
||||
|
||||
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
|
||||
match impl_item.node {
|
||||
hir::ImplItemKind::Const(_, ref expr) => {
|
||||
hir::ImplItemKind::Const(_, body_id) => {
|
||||
if !self.symbol_is_live(impl_item.id, None) {
|
||||
self.warn_dead_code(impl_item.id, impl_item.span,
|
||||
impl_item.name, "associated const");
|
||||
}
|
||||
intravisit::walk_expr(self, expr)
|
||||
self.visit_nested_body(body_id)
|
||||
}
|
||||
hir::ImplItemKind::Method(_, body_id) => {
|
||||
if !self.symbol_is_live(impl_item.id, None) {
|
||||
self.warn_dead_code(impl_item.id, impl_item.span,
|
||||
impl_item.name, "method");
|
||||
}
|
||||
self.visit_body(body_id)
|
||||
self.visit_nested_body(body_id)
|
||||
}
|
||||
hir::ImplItemKind::Type(..) => {}
|
||||
}
|
||||
@ -572,11 +572,9 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
|
||||
// Overwrite so that we don't warn the trait item itself.
|
||||
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
|
||||
match trait_item.node {
|
||||
hir::TraitItemKind::Const(_, Some(ref body)) => {
|
||||
intravisit::walk_expr(self, body)
|
||||
}
|
||||
hir::TraitItemKind::Const(_, Some(body_id)) |
|
||||
hir::TraitItemKind::Method(_, Some(body_id)) => {
|
||||
self.visit_body(body_id)
|
||||
self.visit_nested_body(body_id)
|
||||
}
|
||||
hir::TraitItemKind::Const(_, None) |
|
||||
hir::TraitItemKind::Method(_, None) |
|
||||
|
@ -98,7 +98,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, fn_decl: &'tcx hir::FnDecl,
|
||||
body_id: hir::ExprId, span: Span, id: ast::NodeId) {
|
||||
body_id: hir::BodyId, span: Span, id: ast::NodeId) {
|
||||
|
||||
let (is_item_fn, is_unsafe_fn) = match fn_kind {
|
||||
FnKind::ItemFn(_, _, unsafety, ..) =>
|
||||
|
@ -289,9 +289,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
|
||||
pub fn walk_fn(&mut self,
|
||||
decl: &hir::FnDecl,
|
||||
body: &hir::Expr) {
|
||||
self.walk_arg_patterns(decl, body);
|
||||
self.consume_expr(body);
|
||||
body: &hir::Body) {
|
||||
self.walk_arg_patterns(decl, &body.value);
|
||||
self.consume_expr(&body.value);
|
||||
}
|
||||
|
||||
fn walk_arg_patterns(&mut self,
|
||||
@ -537,9 +537,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
hir::ExprRepeat(ref base, ref count) => {
|
||||
hir::ExprRepeat(ref base, _) => {
|
||||
self.consume_expr(&base);
|
||||
self.consume_expr(&count);
|
||||
}
|
||||
|
||||
hir::ExprClosure(.., fn_decl_span) => {
|
||||
|
@ -34,13 +34,13 @@ struct ItemVisitor<'a, 'tcx: 'a> {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ItemVisitor<'a, 'tcx> {
|
||||
fn visit_const(&mut self, item_id: ast::NodeId, expr: &'tcx hir::Expr) {
|
||||
fn visit_const(&mut self, item_id: ast::NodeId, body: hir::BodyId) {
|
||||
let param_env = ty::ParameterEnvironment::for_item(self.tcx, item_id);
|
||||
self.tcx.infer_ctxt(None, Some(param_env), Reveal::All).enter(|infcx| {
|
||||
let mut visitor = ExprVisitor {
|
||||
infcx: &infcx
|
||||
};
|
||||
visitor.visit_expr(expr);
|
||||
visitor.visit_nested_body(body);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -122,33 +122,33 @@ impl<'a, 'tcx> Visitor<'tcx> for ItemVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// const, static and N in [T; N].
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
||||
fn visit_body(&mut self, body: &'tcx hir::Body) {
|
||||
self.tcx.infer_ctxt(None, None, Reveal::All).enter(|infcx| {
|
||||
let mut visitor = ExprVisitor {
|
||||
infcx: &infcx
|
||||
};
|
||||
visitor.visit_expr(expr);
|
||||
visitor.visit_body(body);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) {
|
||||
if let hir::TraitItemKind::Const(_, Some(ref expr)) = item.node {
|
||||
self.visit_const(item.id, expr);
|
||||
if let hir::TraitItemKind::Const(_, Some(body)) = item.node {
|
||||
self.visit_const(item.id, body);
|
||||
} else {
|
||||
intravisit::walk_trait_item(self, item);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem) {
|
||||
if let hir::ImplItemKind::Const(_, ref expr) = item.node {
|
||||
self.visit_const(item.id, expr);
|
||||
if let hir::ImplItemKind::Const(_, body) = item.node {
|
||||
self.visit_const(item.id, body);
|
||||
} else {
|
||||
intravisit::walk_impl_item(self, item);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
|
||||
b: hir::ExprId, s: Span, id: ast::NodeId) {
|
||||
b: hir::BodyId, s: Span, id: ast::NodeId) {
|
||||
if let FnKind::Closure(..) = fk {
|
||||
span_bug!(s, "intrinsicck: closure outside of function")
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ impl<'a, 'tcx> Visitor<'tcx> for IrMaps<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
|
||||
b: hir::ExprId, s: Span, id: NodeId) {
|
||||
b: hir::BodyId, s: Span, id: NodeId) {
|
||||
visit_fn(self, fk, fd, b, s, id);
|
||||
}
|
||||
fn visit_local(&mut self, l: &'tcx hir::Local) { visit_local(self, l); }
|
||||
@ -354,13 +354,9 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
|
||||
|
||||
impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> {
|
||||
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
|
||||
NestedVisitorMap::OnlyBodies(&self.ir.tcx.map)
|
||||
NestedVisitorMap::None
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, _: FnKind<'tcx>, _: &'tcx hir::FnDecl,
|
||||
_: hir::ExprId, _: Span, _: NodeId) {
|
||||
// do not check contents of nested fns
|
||||
}
|
||||
fn visit_local(&mut self, l: &'tcx hir::Local) {
|
||||
check_local(self, l);
|
||||
}
|
||||
@ -375,7 +371,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> {
|
||||
fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
|
||||
fk: FnKind<'tcx>,
|
||||
decl: &'tcx hir::FnDecl,
|
||||
body_id: hir::ExprId,
|
||||
body_id: hir::BodyId,
|
||||
sp: Span,
|
||||
id: ast::NodeId) {
|
||||
debug!("visit_fn");
|
||||
@ -408,14 +404,14 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
|
||||
clean_exit_var: fn_maps.add_variable(CleanExit)
|
||||
};
|
||||
|
||||
let body = ir.tcx.map.expr(body_id);
|
||||
let body = ir.tcx.map.body(body_id);
|
||||
|
||||
// compute liveness
|
||||
let mut lsets = Liveness::new(&mut fn_maps, specials);
|
||||
let entry_ln = lsets.compute(body);
|
||||
let entry_ln = lsets.compute(&body.value);
|
||||
|
||||
// check for various error conditions
|
||||
lsets.visit_expr(body);
|
||||
lsets.visit_body(body);
|
||||
lsets.check_ret(id, sp, fk, entry_ln, body);
|
||||
lsets.warn_about_unused_args(decl, entry_ln);
|
||||
}
|
||||
@ -942,7 +938,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
loop. The next-node for a continue is the top of this loop.
|
||||
*/
|
||||
let node = self.live_node(expr.id, expr.span);
|
||||
self.with_loop_nodes(blk_id.node_id(), succ, node, |this| {
|
||||
self.with_loop_nodes(blk_id.node_id, succ, node, |this| {
|
||||
|
||||
// the construction of a closure itself is not important,
|
||||
// but we have to consider the closed over variables.
|
||||
@ -1088,11 +1084,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
self.propagate_through_exprs(exprs, succ)
|
||||
}
|
||||
|
||||
hir::ExprRepeat(ref element, ref count) => {
|
||||
let succ = self.propagate_through_expr(&count, succ);
|
||||
self.propagate_through_expr(&element, succ)
|
||||
}
|
||||
|
||||
hir::ExprStruct(_, ref fields, ref with_expr) => {
|
||||
let succ = self.propagate_through_opt_expr(with_expr.as_ref().map(|e| &**e), succ);
|
||||
fields.iter().rev().fold(succ, |succ, field| {
|
||||
@ -1149,7 +1140,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
hir::ExprAddrOf(_, ref e) |
|
||||
hir::ExprCast(ref e, _) |
|
||||
hir::ExprType(ref e, _) |
|
||||
hir::ExprUnary(_, ref e) => {
|
||||
hir::ExprUnary(_, ref e) |
|
||||
hir::ExprRepeat(ref e, _) => {
|
||||
self.propagate_through_expr(&e, succ)
|
||||
}
|
||||
|
||||
@ -1443,7 +1435,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
sp: Span,
|
||||
fk: FnKind,
|
||||
entry_ln: LiveNode,
|
||||
body: &hir::Expr)
|
||||
body: &hir::Body)
|
||||
{
|
||||
let fn_ty = if let FnKind::Closure(_) = fk {
|
||||
self.ir.tcx.tables().node_id_to_type(id)
|
||||
@ -1460,7 +1452,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
// and must outlive the *call-site* of the function.
|
||||
let fn_ret =
|
||||
self.ir.tcx.liberate_late_bound_regions(
|
||||
self.ir.tcx.region_maps.call_site_extent(id, body.id),
|
||||
self.ir.tcx.region_maps.call_site_extent(id, body.value.id),
|
||||
&fn_ret);
|
||||
|
||||
if !fn_ret.is_never() && self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() {
|
||||
|
@ -705,7 +705,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
};
|
||||
|
||||
match fn_expr.node {
|
||||
hir::ExprClosure(.., body_id, _) => body_id.node_id(),
|
||||
hir::ExprClosure(.., body_id, _) => body_id.node_id,
|
||||
_ => bug!()
|
||||
}
|
||||
};
|
||||
|
@ -250,15 +250,15 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
||||
match item.node {
|
||||
hir::ItemFn(.., body) => {
|
||||
if item_might_be_inlined(&item) {
|
||||
self.visit_body(body);
|
||||
self.visit_nested_body(body);
|
||||
}
|
||||
}
|
||||
|
||||
// Reachable constants will be inlined into other crates
|
||||
// unconditionally, so we need to make sure that their
|
||||
// contents are also reachable.
|
||||
hir::ItemConst(_, ref init) => {
|
||||
self.visit_expr(&init);
|
||||
hir::ItemConst(_, init) => {
|
||||
self.visit_nested_body(init);
|
||||
}
|
||||
|
||||
// These are normal, nothing reachable about these
|
||||
@ -278,24 +278,22 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
||||
hir::TraitItemKind::Method(_, None) => {
|
||||
// Keep going, nothing to get exported
|
||||
}
|
||||
hir::TraitItemKind::Const(_, Some(ref body)) => {
|
||||
self.visit_expr(body);
|
||||
}
|
||||
hir::TraitItemKind::Const(_, Some(body_id)) |
|
||||
hir::TraitItemKind::Method(_, Some(body_id)) => {
|
||||
self.visit_body(body_id);
|
||||
self.visit_nested_body(body_id);
|
||||
}
|
||||
hir::TraitItemKind::Type(..) => {}
|
||||
}
|
||||
}
|
||||
ast_map::NodeImplItem(impl_item) => {
|
||||
match impl_item.node {
|
||||
hir::ImplItemKind::Const(_, ref expr) => {
|
||||
self.visit_expr(&expr);
|
||||
hir::ImplItemKind::Const(_, body) => {
|
||||
self.visit_nested_body(body);
|
||||
}
|
||||
hir::ImplItemKind::Method(ref sig, body) => {
|
||||
let did = self.tcx.map.get_parent_did(search_item);
|
||||
if method_might_be_inlined(self.tcx, sig, impl_item, did) {
|
||||
self.visit_body(body)
|
||||
self.visit_nested_body(body)
|
||||
}
|
||||
}
|
||||
hir::ImplItemKind::Type(_) => {}
|
||||
|
@ -1088,7 +1088,7 @@ fn resolve_item_like<'a, 'tcx, F>(visitor: &mut RegionResolutionVisitor<'tcx, 'a
|
||||
fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
|
||||
kind: FnKind<'tcx>,
|
||||
decl: &'tcx hir::FnDecl,
|
||||
body_id: hir::ExprId,
|
||||
body_id: hir::BodyId,
|
||||
sp: Span,
|
||||
id: ast::NodeId) {
|
||||
debug!("region::resolve_fn(id={:?}, \
|
||||
@ -1101,22 +1101,22 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
|
||||
visitor.cx.parent);
|
||||
|
||||
visitor.cx.parent = visitor.new_code_extent(
|
||||
CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id() });
|
||||
CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id });
|
||||
|
||||
let fn_decl_scope = visitor.new_code_extent(
|
||||
CodeExtentData::ParameterScope { fn_id: id, body_id: body_id.node_id() });
|
||||
CodeExtentData::ParameterScope { fn_id: id, body_id: body_id.node_id });
|
||||
|
||||
if let Some(root_id) = visitor.cx.root_id {
|
||||
visitor.region_maps.record_fn_parent(body_id.node_id(), root_id);
|
||||
visitor.region_maps.record_fn_parent(body_id.node_id, root_id);
|
||||
}
|
||||
|
||||
let outer_cx = visitor.cx;
|
||||
let outer_ts = mem::replace(&mut visitor.terminating_scopes, NodeSet());
|
||||
visitor.terminating_scopes.insert(body_id.node_id());
|
||||
visitor.terminating_scopes.insert(body_id.node_id);
|
||||
|
||||
// The arguments and `self` are parented to the fn.
|
||||
visitor.cx = Context {
|
||||
root_id: Some(body_id.node_id()),
|
||||
root_id: Some(body_id.node_id),
|
||||
parent: ROOT_CODE_EXTENT,
|
||||
var_parent: fn_decl_scope,
|
||||
};
|
||||
@ -1126,11 +1126,11 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
|
||||
|
||||
// The body of the every fn is a root scope.
|
||||
visitor.cx = Context {
|
||||
root_id: Some(body_id.node_id()),
|
||||
root_id: Some(body_id.node_id),
|
||||
parent: fn_decl_scope,
|
||||
var_parent: fn_decl_scope
|
||||
};
|
||||
visitor.visit_body(body_id);
|
||||
visitor.visit_nested_body(body_id);
|
||||
|
||||
// Restore context we had at the start.
|
||||
visitor.cx = outer_cx;
|
||||
@ -1195,7 +1195,7 @@ impl<'ast, 'a> Visitor<'ast> for RegionResolutionVisitor<'ast, 'a> {
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: FnKind<'ast>, fd: &'ast FnDecl,
|
||||
b: hir::ExprId, s: Span, n: NodeId) {
|
||||
b: hir::BodyId, s: Span, n: NodeId) {
|
||||
resolve_fn(self, fk, fd, b, s, n);
|
||||
}
|
||||
fn visit_arm(&mut self, a: &'ast Arm) {
|
||||
|
@ -206,7 +206,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: FnKind<'tcx>, decl: &'tcx hir::FnDecl,
|
||||
b: hir::ExprId, s: Span, fn_id: ast::NodeId) {
|
||||
b: hir::BodyId, s: Span, fn_id: ast::NodeId) {
|
||||
match fk {
|
||||
FnKind::ItemFn(_, generics, ..) => {
|
||||
self.visit_early_late(fn_id,decl, generics, |this| {
|
||||
@ -407,7 +407,7 @@ fn signal_shadowing_problem(sess: &Session, name: ast::Name, orig: Original, sha
|
||||
|
||||
// Adds all labels in `b` to `ctxt.labels_in_fn`, signalling a warning
|
||||
// if one of the label shadows a lifetime or another label.
|
||||
fn extract_labels(ctxt: &mut LifetimeContext, b: hir::ExprId) {
|
||||
fn extract_labels(ctxt: &mut LifetimeContext, b: hir::BodyId) {
|
||||
struct GatherLabels<'a> {
|
||||
sess: &'a Session,
|
||||
scope: Scope<'a>,
|
||||
@ -419,7 +419,7 @@ fn extract_labels(ctxt: &mut LifetimeContext, b: hir::ExprId) {
|
||||
scope: ctxt.scope,
|
||||
labels_in_fn: &mut ctxt.labels_in_fn,
|
||||
};
|
||||
gather.visit_expr(ctxt.hir_map.expr(b));
|
||||
gather.visit_body(ctxt.hir_map.body(b));
|
||||
return;
|
||||
|
||||
impl<'v, 'a> Visitor<'v> for GatherLabels<'a> {
|
||||
@ -501,7 +501,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
fn add_scope_and_walk_fn(&mut self,
|
||||
fk: FnKind<'tcx>,
|
||||
fd: &'tcx hir::FnDecl,
|
||||
fb: hir::ExprId,
|
||||
fb: hir::BodyId,
|
||||
_span: Span,
|
||||
fn_id: ast::NodeId) {
|
||||
match fk {
|
||||
@ -522,8 +522,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
// `self.labels_in_fn`.
|
||||
extract_labels(self, fb);
|
||||
|
||||
self.with(FnScope { fn_id: fn_id, body_id: fb.node_id(), s: self.scope },
|
||||
|_old_scope, this| this.visit_body(fb))
|
||||
self.with(FnScope { fn_id: fn_id, body_id: fb.node_id, s: self.scope },
|
||||
|_old_scope, this| this.visit_nested_body(fb))
|
||||
}
|
||||
|
||||
// FIXME(#37666) this works around a limitation in the region inferencer
|
||||
|
@ -1206,7 +1206,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
|
||||
tcx.construct_parameter_environment(
|
||||
impl_item.span,
|
||||
tcx.map.local_def_id(id),
|
||||
tcx.region_maps.call_site_extent(id, body.node_id()))
|
||||
tcx.region_maps.call_site_extent(id, body.node_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1227,7 +1227,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
|
||||
// to the method id).
|
||||
let extent = if let Some(body_id) = *body {
|
||||
// default impl: use call_site extent as free_id_outlive bound.
|
||||
tcx.region_maps.call_site_extent(id, body_id.node_id())
|
||||
tcx.region_maps.call_site_extent(id, body_id.node_id)
|
||||
} else {
|
||||
// no default impl: use item extent as free_id_outlive bound.
|
||||
tcx.region_maps.item_extent(id)
|
||||
@ -1248,7 +1248,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
|
||||
tcx.construct_parameter_environment(
|
||||
item.span,
|
||||
fn_def_id,
|
||||
tcx.region_maps.call_site_extent(id, body_id.node_id()))
|
||||
tcx.region_maps.call_site_extent(id, body_id.node_id))
|
||||
}
|
||||
hir::ItemEnum(..) |
|
||||
hir::ItemStruct(..) |
|
||||
@ -1284,7 +1284,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
|
||||
tcx.construct_parameter_environment(
|
||||
expr.span,
|
||||
base_def_id,
|
||||
tcx.region_maps.call_site_extent(id, body.node_id()))
|
||||
tcx.region_maps.call_site_extent(id, body.node_id))
|
||||
} else {
|
||||
tcx.empty_parameter_environment()
|
||||
}
|
||||
|
@ -190,8 +190,8 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
all_loans: &[Loan<'tcx>],
|
||||
fn_id: ast::NodeId,
|
||||
decl: &hir::FnDecl,
|
||||
body: &hir::Expr) {
|
||||
debug!("check_loans(body id={})", body.id);
|
||||
body: &hir::Body) {
|
||||
debug!("check_loans(body id={})", body.value.id);
|
||||
|
||||
let param_env = ty::ParameterEnvironment::for_item(bccx.tcx, fn_id);
|
||||
let infcx = bccx.tcx.borrowck_fake_infer_ctxt(param_env);
|
||||
|
@ -42,13 +42,13 @@ mod move_error;
|
||||
pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
fn_id: NodeId,
|
||||
decl: &hir::FnDecl,
|
||||
body: &hir::Expr)
|
||||
body: &hir::Body)
|
||||
-> (Vec<Loan<'tcx>>,
|
||||
move_data::MoveData<'tcx>) {
|
||||
let mut glcx = GatherLoanCtxt {
|
||||
bccx: bccx,
|
||||
all_loans: Vec::new(),
|
||||
item_ub: bccx.tcx.region_maps.node_extent(body.id),
|
||||
item_ub: bccx.tcx.region_maps.node_extent(body.value.id),
|
||||
move_data: MoveData::new(),
|
||||
move_error_collector: move_error::MoveErrorCollector::new(),
|
||||
};
|
||||
@ -548,14 +548,14 @@ impl<'a, 'tcx> Visitor<'tcx> for StaticInitializerCtxt<'a, 'tcx> {
|
||||
|
||||
pub fn gather_loans_in_static_initializer<'a, 'tcx>(bccx: &mut BorrowckCtxt<'a, 'tcx>,
|
||||
item_id: ast::NodeId,
|
||||
expr: &'tcx hir::Expr) {
|
||||
body: hir::BodyId) {
|
||||
|
||||
debug!("gather_loans_in_static_initializer(expr={:?})", expr);
|
||||
debug!("gather_loans_in_static_initializer(expr={:?})", body);
|
||||
|
||||
let mut sicx = StaticInitializerCtxt {
|
||||
bccx: bccx,
|
||||
item_id: item_id
|
||||
};
|
||||
|
||||
sicx.visit_expr(expr);
|
||||
sicx.visit_nested_body(body);
|
||||
}
|
||||
|
@ -11,10 +11,7 @@
|
||||
use borrowck::BorrowckCtxt;
|
||||
|
||||
use syntax::ast::{self, MetaItem};
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::hir::intravisit::{FnKind};
|
||||
use syntax_pos::DUMMY_SP;
|
||||
|
||||
use rustc::mir::{self, BasicBlock, BasicBlockData, Mir, Statement, Terminator, Location};
|
||||
use rustc::session::Session;
|
||||
@ -55,27 +52,14 @@ pub struct MoveDataParamEnv<'tcx> {
|
||||
}
|
||||
|
||||
pub fn borrowck_mir(bcx: &mut BorrowckCtxt,
|
||||
fk: FnKind,
|
||||
_decl: &hir::FnDecl,
|
||||
body: &hir::Expr,
|
||||
_sp: Span,
|
||||
id: ast::NodeId,
|
||||
attributes: &[ast::Attribute]) {
|
||||
match fk {
|
||||
FnKind::ItemFn(name, ..) |
|
||||
FnKind::Method(name, ..) => {
|
||||
debug!("borrowck_mir({}) UNIMPLEMENTED", name);
|
||||
}
|
||||
FnKind::Closure(_) => {
|
||||
debug!("borrowck_mir closure (body.id={}) UNIMPLEMENTED", body.id);
|
||||
}
|
||||
}
|
||||
|
||||
let tcx = bcx.tcx;
|
||||
let def_id = tcx.map.local_def_id(id);
|
||||
debug!("borrowck_mir({}) UNIMPLEMENTED", tcx.item_path_str(def_id));
|
||||
|
||||
let mir = &tcx.item_mir(def_id);
|
||||
let param_env = ty::ParameterEnvironment::for_item(tcx, id);
|
||||
|
||||
let mir = &tcx.item_mir(tcx.map.local_def_id(id));
|
||||
|
||||
let move_data = MoveData::gather_moves(mir, tcx, ¶m_env);
|
||||
let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
|
||||
let flow_inits =
|
||||
|
@ -68,7 +68,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
|
||||
b: hir::ExprId, s: Span, id: ast::NodeId) {
|
||||
b: hir::BodyId, s: Span, id: ast::NodeId) {
|
||||
match fk {
|
||||
FnKind::ItemFn(..) |
|
||||
FnKind::Method(..) => {
|
||||
@ -88,15 +88,15 @@ impl<'a, 'tcx> Visitor<'tcx> for BorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
|
||||
if let hir::TraitItemKind::Const(_, Some(ref expr)) = ti.node {
|
||||
gather_loans::gather_loans_in_static_initializer(self, ti.id, &expr);
|
||||
if let hir::TraitItemKind::Const(_, Some(expr)) = ti.node {
|
||||
gather_loans::gather_loans_in_static_initializer(self, ti.id, expr);
|
||||
}
|
||||
intravisit::walk_trait_item(self, ti);
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
|
||||
if let hir::ImplItemKind::Const(_, ref expr) = ii.node {
|
||||
gather_loans::gather_loans_in_static_initializer(self, ii.id, &expr);
|
||||
if let hir::ImplItemKind::Const(_, expr) = ii.node {
|
||||
gather_loans::gather_loans_in_static_initializer(self, ii.id, expr);
|
||||
}
|
||||
intravisit::walk_impl_item(self, ii);
|
||||
}
|
||||
@ -141,9 +141,9 @@ fn borrowck_item<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, item: &'tcx hir::I
|
||||
// loan step is intended for things that have a data
|
||||
// flow dependent conditions.
|
||||
match item.node {
|
||||
hir::ItemStatic(.., ref ex) |
|
||||
hir::ItemConst(_, ref ex) => {
|
||||
gather_loans::gather_loans_in_static_initializer(this, item.id, &ex);
|
||||
hir::ItemStatic(.., ex) |
|
||||
hir::ItemConst(_, ex) => {
|
||||
gather_loans::gather_loans_in_static_initializer(this, item.id, ex);
|
||||
}
|
||||
_ => { }
|
||||
}
|
||||
@ -161,21 +161,21 @@ pub struct AnalysisData<'a, 'tcx: 'a> {
|
||||
fn borrowck_fn<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
|
||||
fk: FnKind<'tcx>,
|
||||
decl: &'tcx hir::FnDecl,
|
||||
body_id: hir::ExprId,
|
||||
body_id: hir::BodyId,
|
||||
sp: Span,
|
||||
id: ast::NodeId,
|
||||
attributes: &[ast::Attribute]) {
|
||||
debug!("borrowck_fn(id={})", id);
|
||||
|
||||
let body = this.tcx.map.expr(body_id);
|
||||
let body = this.tcx.map.body(body_id);
|
||||
|
||||
if attributes.iter().any(|item| item.check_name("rustc_mir_borrowck")) {
|
||||
this.with_temp_region_map(id, |this| {
|
||||
mir::borrowck_mir(this, fk, decl, body, sp, id, attributes)
|
||||
mir::borrowck_mir(this, id, attributes)
|
||||
});
|
||||
}
|
||||
|
||||
let cfg = cfg::CFG::new(this.tcx, body);
|
||||
let cfg = cfg::CFG::new(this.tcx, &body.value);
|
||||
let AnalysisData { all_loans,
|
||||
loans: loan_dfcx,
|
||||
move_data: flowed_moves } =
|
||||
@ -204,14 +204,14 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
|
||||
fk: FnKind<'tcx>,
|
||||
decl: &'tcx hir::FnDecl,
|
||||
cfg: &cfg::CFG,
|
||||
body: &'tcx hir::Expr,
|
||||
body: &'tcx hir::Body,
|
||||
sp: Span,
|
||||
id: ast::NodeId)
|
||||
-> AnalysisData<'a, 'tcx>
|
||||
{
|
||||
// Check the body of fn items.
|
||||
let tcx = this.tcx;
|
||||
let id_range = intravisit::compute_id_range_for_fn_body(fk, decl, body, sp, id, &tcx.map);
|
||||
let id_range = intravisit::compute_id_range_for_fn_body(fk, decl, body.id(), sp, id, &tcx.map);
|
||||
let (all_loans, move_data) =
|
||||
gather_loans::gather_loans_in_fn(this, id, decl, body);
|
||||
|
||||
@ -263,7 +263,7 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
|
||||
}
|
||||
};
|
||||
|
||||
let body = tcx.map.expr(fn_parts.body);
|
||||
let body = tcx.map.body(fn_parts.body);
|
||||
|
||||
let dataflow_data = build_borrowck_dataflow_data(&mut bccx,
|
||||
fn_parts.kind,
|
||||
@ -416,7 +416,7 @@ pub fn closure_to_block(closure_id: ast::NodeId,
|
||||
match tcx.map.get(closure_id) {
|
||||
hir_map::NodeExpr(expr) => match expr.node {
|
||||
hir::ExprClosure(.., body_id, _) => {
|
||||
body_id.node_id()
|
||||
body_id.node_id
|
||||
}
|
||||
_ => {
|
||||
bug!("encountered non-closure id: {}", closure_id)
|
||||
|
@ -656,7 +656,7 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
||||
cfg: &cfg::CFG,
|
||||
id_range: IdRange,
|
||||
decl: &hir::FnDecl,
|
||||
body: &hir::Expr)
|
||||
body: &hir::Body)
|
||||
-> FlowedMoveData<'a, 'tcx> {
|
||||
let mut dfcx_moves =
|
||||
DataFlowContext::new(tcx,
|
||||
|
@ -67,7 +67,7 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
|
||||
b: hir::ExprId, s: Span, id: ast::NodeId) {
|
||||
b: hir::BodyId, s: Span, id: ast::NodeId) {
|
||||
if let FnKind::Closure(..) = fk {
|
||||
span_bug!(s, "check_match: closure outside of function")
|
||||
}
|
||||
@ -120,7 +120,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
|
||||
b: hir::ExprId, s: Span, n: ast::NodeId) {
|
||||
b: hir::BodyId, s: Span, n: ast::NodeId) {
|
||||
intravisit::walk_fn(self, fk, fd, b, s, n);
|
||||
|
||||
for input in &fd.inputs {
|
||||
|
@ -576,18 +576,18 @@ https://doc.rust-lang.org/reference.html#ffi-attributes
|
||||
|
||||
|
||||
E0306: r##"
|
||||
In an array literal `[x; N]`, `N` is the number of elements in the array. This
|
||||
In an array type `[T; N]`, `N` is the number of elements in the array. This
|
||||
must be an unsigned integer. Erroneous code example:
|
||||
|
||||
```compile_fail,E0306
|
||||
let x = [0i32; true]; // error: expected positive integer for repeat count,
|
||||
// found boolean
|
||||
const X: [i32; true] = [0]; // error: expected `usize` for array length,
|
||||
// found boolean
|
||||
```
|
||||
|
||||
Working example:
|
||||
|
||||
```
|
||||
let x = [0i32; 2];
|
||||
const X: [i32; 1] = [0];
|
||||
```
|
||||
"##,
|
||||
}
|
||||
|
@ -56,15 +56,17 @@ macro_rules! math {
|
||||
fn lookup_variant_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
variant_def: DefId)
|
||||
-> Option<&'tcx Expr> {
|
||||
fn variant_expr<'a>(variants: &'a [hir::Variant], id: ast::NodeId)
|
||||
-> Option<&'a Expr> {
|
||||
let variant_expr = |variants: &'tcx [hir::Variant], id: ast::NodeId |
|
||||
-> Option<&'tcx Expr> {
|
||||
for variant in variants {
|
||||
if variant.node.data.id() == id {
|
||||
return variant.node.disr_expr.as_ref().map(|e| &**e);
|
||||
return variant.node.disr_expr.map(|e| {
|
||||
&tcx.map.body(e).value
|
||||
});
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(variant_node_id) = tcx.map.as_local_node_id(variant_def) {
|
||||
let enum_node_id = tcx.map.get_parent(variant_node_id);
|
||||
@ -96,21 +98,24 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
match tcx.map.find(node_id) {
|
||||
None => None,
|
||||
Some(ast_map::NodeItem(it)) => match it.node {
|
||||
hir::ItemConst(ref ty, ref const_expr) => {
|
||||
Some((&const_expr, tcx.ast_ty_to_prim_ty(ty)))
|
||||
hir::ItemConst(ref ty, body) => {
|
||||
Some((&tcx.map.body(body).value,
|
||||
tcx.ast_ty_to_prim_ty(ty)))
|
||||
}
|
||||
_ => None
|
||||
},
|
||||
Some(ast_map::NodeTraitItem(ti)) => match ti.node {
|
||||
hir::TraitItemKind::Const(ref ty, ref expr_option) => {
|
||||
hir::TraitItemKind::Const(ref ty, default) => {
|
||||
if let Some(substs) = substs {
|
||||
// If we have a trait item and the substitutions for it,
|
||||
// `resolve_trait_associated_const` will select an impl
|
||||
// or the default.
|
||||
let trait_id = tcx.map.get_parent(node_id);
|
||||
let trait_id = tcx.map.local_def_id(trait_id);
|
||||
let default_value = expr_option.as_ref()
|
||||
.map(|expr| (&**expr, tcx.ast_ty_to_prim_ty(ty)));
|
||||
let default_value = default.map(|body| {
|
||||
(&tcx.map.body(body).value,
|
||||
tcx.ast_ty_to_prim_ty(ty))
|
||||
});
|
||||
resolve_trait_associated_const(tcx, def_id, default_value, trait_id, substs)
|
||||
} else {
|
||||
// Technically, without knowing anything about the
|
||||
@ -125,8 +130,9 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_ => None
|
||||
},
|
||||
Some(ast_map::NodeImplItem(ii)) => match ii.node {
|
||||
hir::ImplItemKind::Const(ref ty, ref expr) => {
|
||||
Some((&expr, tcx.ast_ty_to_prim_ty(ty)))
|
||||
hir::ImplItemKind::Const(ref ty, body) => {
|
||||
Some((&tcx.map.body(body).value,
|
||||
tcx.ast_ty_to_prim_ty(ty)))
|
||||
}
|
||||
_ => None
|
||||
},
|
||||
@ -142,8 +148,8 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
let mut used_substs = false;
|
||||
let expr_ty = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) {
|
||||
Some((&InlinedItem { body: ref const_expr, .. }, _)) => {
|
||||
Some((&**const_expr, Some(tcx.sess.cstore.item_type(tcx, def_id))))
|
||||
Some((&InlinedItem { ref body, .. }, _)) => {
|
||||
Some((&body.value, Some(tcx.sess.cstore.item_type(tcx, def_id))))
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
@ -864,18 +870,18 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
Struct(_) => signal!(e, UnimplementedConstVal("tuple struct constructors")),
|
||||
callee => signal!(e, CallOn(callee)),
|
||||
};
|
||||
let (arg_defs, body_id) = match lookup_const_fn_by_id(tcx, did) {
|
||||
Some(ConstFnNode::Inlined(ii)) => (ii.const_fn_args.clone(), ii.body.expr_id()),
|
||||
let (arg_defs, body) = match lookup_const_fn_by_id(tcx, did) {
|
||||
Some(ConstFnNode::Inlined(ii)) => (ii.const_fn_args.clone(), &ii.body),
|
||||
Some(ConstFnNode::Local(fn_like)) =>
|
||||
(fn_like.decl().inputs.iter()
|
||||
.map(|arg| match arg.pat.node {
|
||||
hir::PatKind::Binding(_, def_id, _, _) => Some(def_id),
|
||||
_ => None
|
||||
}).collect(),
|
||||
fn_like.body()),
|
||||
tcx.map.body(fn_like.body())),
|
||||
None => signal!(e, NonConstPath),
|
||||
};
|
||||
let result = tcx.map.expr(body_id);
|
||||
let result = &body.value;
|
||||
assert_eq!(arg_defs.len(), args.len());
|
||||
|
||||
let mut call_args = DefIdMap();
|
||||
@ -893,7 +899,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
debug!("const call({:?})", call_args);
|
||||
eval_const_expr_partial(tcx, &result, ty_hint, Some(&call_args))?
|
||||
eval_const_expr_partial(tcx, result, ty_hint, Some(&call_args))?
|
||||
},
|
||||
hir::ExprLit(ref lit) => match lit_to_const(&lit.node, tcx, ety) {
|
||||
Ok(val) => val,
|
||||
@ -953,11 +959,12 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
hir::ExprArray(ref v) => Array(e.id, v.len() as u64),
|
||||
hir::ExprRepeat(_, ref n) => {
|
||||
hir::ExprRepeat(_, n) => {
|
||||
let len_hint = ty_hint.checked_or(tcx.types.usize);
|
||||
let n = &tcx.map.body(n).value;
|
||||
Repeat(
|
||||
e.id,
|
||||
match eval_const_expr_partial(tcx, &n, len_hint, fn_args)? {
|
||||
match eval_const_expr_partial(tcx, n, len_hint, fn_args)? {
|
||||
Integral(Usize(i)) => i.as_u64(tcx.sess.target.uint_type),
|
||||
Integral(_) => signal!(e, RepeatCountNotNatural),
|
||||
_ => signal!(e, RepeatCountNotInt),
|
||||
|
@ -702,8 +702,8 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
|
||||
let cfg = match code {
|
||||
blocks::Code::Expr(expr) => cfg::CFG::new(tcx, expr),
|
||||
blocks::Code::FnLike(fn_like) => {
|
||||
let body = tcx.map.expr(fn_like.body());
|
||||
cfg::CFG::new(tcx, body)
|
||||
let body = tcx.map.body(fn_like.body());
|
||||
cfg::CFG::new(tcx, &body.value)
|
||||
},
|
||||
};
|
||||
let labelled_edges = mode != PpFlowGraphMode::UnlabelledEdges;
|
||||
|
@ -188,7 +188,7 @@ enum SawAbiComponent<'a> {
|
||||
SawTraitItem(SawTraitOrImplItemComponent),
|
||||
SawImplItem(SawTraitOrImplItemComponent),
|
||||
SawStructField,
|
||||
SawVariant,
|
||||
SawVariant(bool),
|
||||
SawQPath,
|
||||
SawPathSegment,
|
||||
SawPathParameters,
|
||||
@ -584,7 +584,7 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has
|
||||
g: &'tcx Generics,
|
||||
item_id: NodeId) {
|
||||
debug!("visit_variant: st={:?}", self.st);
|
||||
SawVariant.hash(self.st);
|
||||
SawVariant(v.node.disr_expr.is_some()).hash(self.st);
|
||||
hash_attrs!(self, &v.node.attrs);
|
||||
visit::walk_variant(self, v, g, item_id)
|
||||
}
|
||||
@ -616,7 +616,12 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has
|
||||
// implicitly hashing the discriminant of SawExprComponent.
|
||||
hash_span!(self, ex.span, force_span);
|
||||
hash_attrs!(self, &ex.attrs);
|
||||
visit::walk_expr(self, ex)
|
||||
|
||||
// Always hash nested constant bodies (e.g. n in `[x; n]`).
|
||||
let hash_bodies = self.hash_bodies;
|
||||
self.hash_bodies = true;
|
||||
visit::walk_expr(self, ex);
|
||||
self.hash_bodies = hash_bodies;
|
||||
}
|
||||
|
||||
fn visit_stmt(&mut self, s: &'tcx Stmt) {
|
||||
@ -686,7 +691,12 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has
|
||||
debug!("visit_ty: st={:?}", self.st);
|
||||
SawTy(saw_ty(&t.node)).hash(self.st);
|
||||
hash_span!(self, t.span);
|
||||
visit::walk_ty(self, t)
|
||||
|
||||
// Always hash nested constant bodies (e.g. N in `[T; N]`).
|
||||
let hash_bodies = self.hash_bodies;
|
||||
self.hash_bodies = true;
|
||||
visit::walk_ty(self, t);
|
||||
self.hash_bodies = hash_bodies;
|
||||
}
|
||||
|
||||
fn visit_generics(&mut self, g: &'tcx Generics) {
|
||||
@ -1159,7 +1169,7 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
|
||||
items: _,
|
||||
trait_items: _,
|
||||
impl_items: _,
|
||||
exprs: _,
|
||||
bodies: _,
|
||||
} = *krate;
|
||||
|
||||
visit::Visitor::visit_mod(self, module, span, ast::CRATE_NODE_ID);
|
||||
|
@ -243,7 +243,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase {
|
||||
cx: &LateContext,
|
||||
fk: FnKind,
|
||||
_: &hir::FnDecl,
|
||||
_: &hir::Expr,
|
||||
_: &hir::Body,
|
||||
span: Span,
|
||||
id: ast::NodeId) {
|
||||
match fk {
|
||||
|
@ -222,7 +222,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
|
||||
cx: &LateContext,
|
||||
fk: FnKind<'tcx>,
|
||||
_: &hir::FnDecl,
|
||||
_: &hir::Expr,
|
||||
_: &hir::Body,
|
||||
span: Span,
|
||||
_: ast::NodeId) {
|
||||
match fk {
|
||||
@ -674,7 +674,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
|
||||
cx: &LateContext,
|
||||
fn_kind: FnKind,
|
||||
_: &hir::FnDecl,
|
||||
blk: &hir::Expr,
|
||||
body: &hir::Body,
|
||||
sp: Span,
|
||||
id: ast::NodeId) {
|
||||
let method = match fn_kind {
|
||||
@ -712,7 +712,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
|
||||
// to have behaviour like the above, rather than
|
||||
// e.g. accidentally recurring after an assert.
|
||||
|
||||
let cfg = cfg::CFG::new(cx.tcx, blk);
|
||||
let cfg = cfg::CFG::new(cx.tcx, &body.value);
|
||||
|
||||
let mut work_queue = vec![cfg.entry];
|
||||
let mut reached_exit_without_self_call = false;
|
||||
|
@ -98,7 +98,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedMut {
|
||||
cx: &LateContext,
|
||||
_: FnKind,
|
||||
decl: &hir::FnDecl,
|
||||
_: &hir::Expr,
|
||||
_: &hir::Body,
|
||||
_: Span,
|
||||
_: ast::NodeId) {
|
||||
for a in &decl.inputs {
|
||||
|
@ -485,7 +485,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
||||
.insert(def_id, None);
|
||||
}
|
||||
Some(&InlinedItem { ref body, .. }) => {
|
||||
let inlined_root_node_id = find_inlined_item_root(body.id);
|
||||
let inlined_root_node_id = find_inlined_item_root(body.value.id);
|
||||
cache_inlined_item(def_id, inlined_root_node_id, inlined_root_node_id);
|
||||
}
|
||||
}
|
||||
|
@ -802,7 +802,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
_ => None,
|
||||
},
|
||||
mir: match item.node {
|
||||
hir::ItemStatic(..) |
|
||||
hir::ItemStatic(..) if self.tcx.sess.opts.debugging_opts.always_encode_mir => {
|
||||
self.encode_mir(def_id)
|
||||
}
|
||||
hir::ItemConst(..) => self.encode_mir(def_id),
|
||||
hir::ItemFn(_, _, constness, _, ref generics, _) => {
|
||||
let tps_len = generics.ty_params.len();
|
||||
|
@ -126,7 +126,7 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
|
||||
arguments: A,
|
||||
abi: Abi,
|
||||
return_ty: Ty<'gcx>,
|
||||
ast_body: &'gcx hir::Expr)
|
||||
body_id: hir::BodyId)
|
||||
-> Mir<'tcx>
|
||||
where A: Iterator<Item=(Ty<'gcx>, Option<&'gcx hir::Pat>)>
|
||||
{
|
||||
@ -136,17 +136,17 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
|
||||
let span = tcx.map.span(fn_id);
|
||||
let mut builder = Builder::new(hir, span, arguments.len(), return_ty);
|
||||
|
||||
let body_id = ast_body.id;
|
||||
let call_site_extent =
|
||||
tcx.region_maps.lookup_code_extent(
|
||||
CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id });
|
||||
CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id.node_id });
|
||||
let arg_extent =
|
||||
tcx.region_maps.lookup_code_extent(
|
||||
CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body_id });
|
||||
CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body_id.node_id });
|
||||
let mut block = START_BLOCK;
|
||||
unpack!(block = builder.in_scope(call_site_extent, block, |builder| {
|
||||
unpack!(block = builder.in_scope(arg_extent, block, |builder| {
|
||||
builder.args_and_body(block, &arguments, arg_extent, ast_body)
|
||||
let ast_expr = &tcx.map.body(body_id).value;
|
||||
builder.args_and_body(block, &arguments, arg_extent, ast_expr)
|
||||
}));
|
||||
// Attribute epilogue to function's closing brace
|
||||
let fn_end = Span { lo: span.hi, ..span };
|
||||
@ -197,9 +197,10 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
|
||||
|
||||
pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
|
||||
item_id: ast::NodeId,
|
||||
ast_expr: &'tcx hir::Expr)
|
||||
body_id: hir::BodyId)
|
||||
-> Mir<'tcx> {
|
||||
let tcx = hir.tcx();
|
||||
let ast_expr = &tcx.map.body(body_id).value;
|
||||
let ty = tcx.tables().expr_ty_adjusted(ast_expr);
|
||||
let span = tcx.map.span(item_id);
|
||||
let mut builder = Builder::new(hir, span, 0, ty);
|
||||
|
@ -575,7 +575,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
|
||||
// Now comes the rote stuff:
|
||||
hir::ExprRepeat(ref v, ref c) => {
|
||||
hir::ExprRepeat(ref v, c) => {
|
||||
let c = &cx.tcx.map.body(c).value;
|
||||
ExprKind::Repeat {
|
||||
value: v.to_ref(),
|
||||
count: TypedConstVal {
|
||||
@ -585,7 +586,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
ConstVal::Integral(ConstInt::Usize(u)) => u,
|
||||
other => bug!("constant evaluation of repeat count yielded {:?}", other),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::ExprRet(ref v) => ExprKind::Return { value: v.to_ref() },
|
||||
@ -780,7 +781,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
let body_id = match cx.tcx.map.find(closure_expr_id) {
|
||||
Some(map::NodeExpr(expr)) => {
|
||||
match expr.node {
|
||||
hir::ExprClosure(.., body_id, _) => body_id.node_id(),
|
||||
hir::ExprClosure(.., body, _) => body.node_id,
|
||||
_ => {
|
||||
span_bug!(expr.span, "closure expr is not a closure expr");
|
||||
}
|
||||
|
@ -129,16 +129,17 @@ impl<'a, 'gcx, 'tcx> CxBuilder<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'a, 'gcx> BuildMir<'a, 'gcx> {
|
||||
fn build_const_integer(&mut self, expr: &'gcx hir::Expr) {
|
||||
fn build_const_integer(&mut self, body: hir::BodyId) {
|
||||
let body = self.tcx.map.body(body);
|
||||
// FIXME(eddyb) Closures should have separate
|
||||
// function definition IDs and expression IDs.
|
||||
// Type-checking should not let closures get
|
||||
// this far in an integer constant position.
|
||||
if let hir::ExprClosure(..) = expr.node {
|
||||
if let hir::ExprClosure(..) = body.value.node {
|
||||
return;
|
||||
}
|
||||
self.cx(MirSource::Const(expr.id)).build(|cx| {
|
||||
build::construct_const(cx, expr.id, expr)
|
||||
self.cx(MirSource::Const(body.value.id)).build(|cx| {
|
||||
build::construct_const(cx, body.value.id, body.id())
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -151,12 +152,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
|
||||
// Const and static items.
|
||||
fn visit_item(&mut self, item: &'tcx hir::Item) {
|
||||
match item.node {
|
||||
hir::ItemConst(_, ref expr) => {
|
||||
hir::ItemConst(_, expr) => {
|
||||
self.cx(MirSource::Const(item.id)).build(|cx| {
|
||||
build::construct_const(cx, item.id, expr)
|
||||
});
|
||||
}
|
||||
hir::ItemStatic(_, m, ref expr) => {
|
||||
hir::ItemStatic(_, m, expr) => {
|
||||
self.cx(MirSource::Static(item.id, m)).build(|cx| {
|
||||
build::construct_const(cx, item.id, expr)
|
||||
});
|
||||
@ -168,7 +169,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
|
||||
|
||||
// Trait associated const defaults.
|
||||
fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) {
|
||||
if let hir::TraitItemKind::Const(_, Some(ref expr)) = item.node {
|
||||
if let hir::TraitItemKind::Const(_, Some(expr)) = item.node {
|
||||
self.cx(MirSource::Const(item.id)).build(|cx| {
|
||||
build::construct_const(cx, item.id, expr)
|
||||
});
|
||||
@ -178,7 +179,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
|
||||
|
||||
// Impl associated const.
|
||||
fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem) {
|
||||
if let hir::ImplItemKind::Const(_, ref expr) = item.node {
|
||||
if let hir::ImplItemKind::Const(_, expr) = item.node {
|
||||
self.cx(MirSource::Const(item.id)).build(|cx| {
|
||||
build::construct_const(cx, item.id, expr)
|
||||
});
|
||||
@ -188,7 +189,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
|
||||
|
||||
// Repeat counts, i.e. [expr; constant].
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
||||
if let hir::ExprRepeat(_, ref count) = expr.node {
|
||||
if let hir::ExprRepeat(_, count) = expr.node {
|
||||
self.build_const_integer(count);
|
||||
}
|
||||
intravisit::walk_expr(self, expr);
|
||||
@ -196,7 +197,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
|
||||
|
||||
// Array lengths, i.e. [T; constant].
|
||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
|
||||
if let hir::TyArray(_, ref length) = ty.node {
|
||||
if let hir::TyArray(_, length) = ty.node {
|
||||
self.build_const_integer(length);
|
||||
}
|
||||
intravisit::walk_ty(self, ty);
|
||||
@ -205,7 +206,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
|
||||
// Enum variant discriminant values.
|
||||
fn visit_variant(&mut self, v: &'tcx hir::Variant,
|
||||
g: &'tcx hir::Generics, item_id: ast::NodeId) {
|
||||
if let Some(ref expr) = v.node.disr_expr {
|
||||
if let Some(expr) = v.node.disr_expr {
|
||||
self.build_const_integer(expr);
|
||||
}
|
||||
intravisit::walk_variant(self, v, g, item_id);
|
||||
@ -214,7 +215,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
|
||||
fn visit_fn(&mut self,
|
||||
fk: FnKind<'tcx>,
|
||||
decl: &'tcx hir::FnDecl,
|
||||
body_id: hir::ExprId,
|
||||
body_id: hir::BodyId,
|
||||
span: Span,
|
||||
id: ast::NodeId) {
|
||||
// fetch the fully liberated fn signature (that is, all bound
|
||||
@ -227,7 +228,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
|
||||
};
|
||||
|
||||
let (abi, implicit_argument) = if let FnKind::Closure(..) = fk {
|
||||
(Abi::Rust, Some((closure_self_ty(self.tcx, id, body_id.node_id()), None)))
|
||||
(Abi::Rust, Some((closure_self_ty(self.tcx, id, body_id.node_id), None)))
|
||||
} else {
|
||||
let def_id = self.tcx.map.local_def_id(id);
|
||||
(self.tcx.item_type(def_id).fn_abi(), None)
|
||||
@ -241,11 +242,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
|
||||
(fn_sig.inputs()[index], Some(&*arg.pat))
|
||||
});
|
||||
|
||||
let body = self.tcx.map.expr(body_id);
|
||||
|
||||
let arguments = implicit_argument.into_iter().chain(explicit_arguments);
|
||||
self.cx(MirSource::Fn(id)).build(|cx| {
|
||||
build::construct_fn(cx, id, arguments, abi, fn_sig.output(), body)
|
||||
build::construct_fn(cx, id, arguments, abi, fn_sig.output(), body_id)
|
||||
});
|
||||
|
||||
intravisit::walk_fn(self, fk, decl, body_id, span, id);
|
||||
|
@ -100,6 +100,11 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
|
||||
.enter(|infcx| f(&mut euv::ExprUseVisitor::new(self, &infcx)))
|
||||
}
|
||||
|
||||
fn global_body(&mut self, mode: Mode, body: hir::BodyId) -> ConstQualif {
|
||||
let expr = &self.tcx.map.body(body).value;
|
||||
self.global_expr(mode, expr)
|
||||
}
|
||||
|
||||
fn global_expr(&mut self, mode: Mode, expr: &'gcx hir::Expr) -> ConstQualif {
|
||||
assert!(mode != Mode::Var);
|
||||
match self.tcx.const_qualif_map.borrow_mut().entry(expr.id) {
|
||||
@ -134,7 +139,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
|
||||
fn fn_like(&mut self,
|
||||
fk: FnKind<'gcx>,
|
||||
fd: &'gcx hir::FnDecl,
|
||||
b: hir::ExprId,
|
||||
b: hir::BodyId,
|
||||
s: Span,
|
||||
fn_id: ast::NodeId)
|
||||
-> ConstQualif {
|
||||
@ -160,7 +165,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
|
||||
};
|
||||
|
||||
let qualif = self.with_mode(mode, |this| {
|
||||
let body = this.tcx.map.expr(b);
|
||||
let body = this.tcx.map.body(b);
|
||||
this.with_euv(Some(fn_id), |euv| euv.walk_fn(fd, body));
|
||||
intravisit::walk_fn(this, fk, fd, b, s, fn_id);
|
||||
this.qualif
|
||||
@ -197,7 +202,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
|
||||
true
|
||||
},
|
||||
Some(ConstFnNode::Inlined(ii)) => {
|
||||
let node_id = ii.body.id;
|
||||
let node_id = ii.body.value.id;
|
||||
|
||||
let qualif = match self.tcx.const_qualif_map.borrow_mut().entry(node_id) {
|
||||
Entry::Occupied(entry) => *entry.get(),
|
||||
@ -241,19 +246,19 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
|
||||
debug!("visit_item(item={})", self.tcx.map.node_to_string(i.id));
|
||||
assert_eq!(self.mode, Mode::Var);
|
||||
match i.node {
|
||||
hir::ItemStatic(_, hir::MutImmutable, ref expr) => {
|
||||
self.global_expr(Mode::Static, &expr);
|
||||
hir::ItemStatic(_, hir::MutImmutable, expr) => {
|
||||
self.global_body(Mode::Static, expr);
|
||||
}
|
||||
hir::ItemStatic(_, hir::MutMutable, ref expr) => {
|
||||
self.global_expr(Mode::StaticMut, &expr);
|
||||
hir::ItemStatic(_, hir::MutMutable, expr) => {
|
||||
self.global_body(Mode::StaticMut, expr);
|
||||
}
|
||||
hir::ItemConst(_, ref expr) => {
|
||||
self.global_expr(Mode::Const, &expr);
|
||||
hir::ItemConst(_, expr) => {
|
||||
self.global_body(Mode::Const, expr);
|
||||
}
|
||||
hir::ItemEnum(ref enum_definition, _) => {
|
||||
for var in &enum_definition.variants {
|
||||
if let Some(ref ex) = var.node.disr_expr {
|
||||
self.global_expr(Mode::Const, &ex);
|
||||
if let Some(ex) = var.node.disr_expr {
|
||||
self.global_body(Mode::Const, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -265,9 +270,9 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
|
||||
|
||||
fn visit_trait_item(&mut self, t: &'tcx hir::TraitItem) {
|
||||
match t.node {
|
||||
hir::TraitItemKind::Const(_, ref default) => {
|
||||
if let Some(ref expr) = *default {
|
||||
self.global_expr(Mode::Const, &expr);
|
||||
hir::TraitItemKind::Const(_, default) => {
|
||||
if let Some(expr) = default {
|
||||
self.global_body(Mode::Const, expr);
|
||||
} else {
|
||||
intravisit::walk_trait_item(self, t);
|
||||
}
|
||||
@ -278,8 +283,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
|
||||
|
||||
fn visit_impl_item(&mut self, i: &'tcx hir::ImplItem) {
|
||||
match i.node {
|
||||
hir::ImplItemKind::Const(_, ref expr) => {
|
||||
self.global_expr(Mode::Const, &expr);
|
||||
hir::ImplItemKind::Const(_, expr) => {
|
||||
self.global_body(Mode::Const, expr);
|
||||
}
|
||||
_ => self.with_mode(Mode::Var, |v| intravisit::walk_impl_item(v, i)),
|
||||
}
|
||||
@ -288,7 +293,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
|
||||
fn visit_fn(&mut self,
|
||||
fk: FnKind<'tcx>,
|
||||
fd: &'tcx hir::FnDecl,
|
||||
b: hir::ExprId,
|
||||
b: hir::BodyId,
|
||||
s: Span,
|
||||
fn_id: ast::NodeId) {
|
||||
self.fn_like(fk, fd, b, s, fn_id);
|
||||
|
@ -177,7 +177,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
||||
fn visit_fn(&mut self,
|
||||
fk: hir_visit::FnKind<'v>,
|
||||
fd: &'v hir::FnDecl,
|
||||
b: hir::ExprId,
|
||||
b: hir::BodyId,
|
||||
s: Span,
|
||||
id: NodeId) {
|
||||
self.record("FnDecl", Id::None, fd);
|
||||
|
@ -84,7 +84,7 @@ impl<'a, 'ast> Visitor<'ast> for CheckLoopVisitor<'a, 'ast> {
|
||||
self.with_context(Loop(LoopKind::Loop(source)), |v| v.visit_block(&b));
|
||||
}
|
||||
hir::ExprClosure(.., b, _) => {
|
||||
self.with_context(Closure, |v| v.visit_body(b));
|
||||
self.with_context(Closure, |v| v.visit_nested_body(b));
|
||||
}
|
||||
hir::ExprBreak(label, ref opt_expr) => {
|
||||
if opt_expr.is_some() {
|
||||
|
@ -39,7 +39,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RvalueContext<'a, 'tcx> {
|
||||
fn visit_fn(&mut self,
|
||||
fk: intravisit::FnKind<'tcx>,
|
||||
fd: &'tcx hir::FnDecl,
|
||||
b: hir::ExprId,
|
||||
b: hir::BodyId,
|
||||
s: Span,
|
||||
fn_id: ast::NodeId) {
|
||||
// FIXME (@jroesch) change this to be an inference context
|
||||
@ -50,7 +50,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RvalueContext<'a, 'tcx> {
|
||||
tcx: infcx.tcx,
|
||||
param_env: ¶m_env
|
||||
};
|
||||
let body = infcx.tcx.map.expr(b);
|
||||
let body = infcx.tcx.map.body(b);
|
||||
let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx);
|
||||
euv.walk_fn(fd, body);
|
||||
});
|
||||
|
@ -30,7 +30,7 @@ struct CheckCrateVisitor<'a, 'ast: 'a> {
|
||||
// variant definitions with the discriminant expression that applies to
|
||||
// each one. If the variant uses the default values (starting from `0`),
|
||||
// then `None` is stored.
|
||||
discriminant_map: NodeMap<Option<&'ast hir::Expr>>,
|
||||
discriminant_map: NodeMap<Option<hir::BodyId>>,
|
||||
detected_recursive_ids: NodeSet,
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ struct CheckItemRecursionVisitor<'a, 'b: 'a, 'ast: 'b> {
|
||||
root_span: &'b Span,
|
||||
sess: &'b Session,
|
||||
ast_map: &'b ast_map::Map<'ast>,
|
||||
discriminant_map: &'a mut NodeMap<Option<&'ast hir::Expr>>,
|
||||
discriminant_map: &'a mut NodeMap<Option<hir::BodyId>>,
|
||||
idstack: Vec<ast::NodeId>,
|
||||
detected_recursive_ids: &'a mut NodeSet,
|
||||
}
|
||||
@ -189,7 +189,7 @@ impl<'a, 'b: 'a, 'ast: 'b> CheckItemRecursionVisitor<'a, 'b, 'ast> {
|
||||
variant_stack.push(variant.node.data.id());
|
||||
// When we find an expression, every variant currently on the stack
|
||||
// is affected by that expression.
|
||||
if let Some(ref expr) = variant.node.disr_expr {
|
||||
if let Some(expr) = variant.node.disr_expr {
|
||||
for id in &variant_stack {
|
||||
self.discriminant_map.insert(*id, Some(expr));
|
||||
}
|
||||
@ -226,19 +226,15 @@ impl<'a, 'b: 'a, 'ast: 'b> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'b, '
|
||||
_: &'ast hir::Generics,
|
||||
_: ast::NodeId) {
|
||||
let variant_id = variant.node.data.id();
|
||||
let maybe_expr;
|
||||
if let Some(get_expr) = self.discriminant_map.get(&variant_id) {
|
||||
// This is necessary because we need to let the `discriminant_map`
|
||||
// borrow fall out of scope, so that we can reborrow farther down.
|
||||
maybe_expr = (*get_expr).clone();
|
||||
} else {
|
||||
let maybe_expr = *self.discriminant_map.get(&variant_id).unwrap_or_else(|| {
|
||||
span_bug!(variant.span,
|
||||
"`check_static_recursion` attempted to visit \
|
||||
variant with unknown discriminant")
|
||||
}
|
||||
});
|
||||
// If `maybe_expr` is `None`, that's because no discriminant is
|
||||
// specified that affects this variant. Thus, no risk of recursion.
|
||||
if let Some(expr) = maybe_expr {
|
||||
let expr = &self.ast_map.body(expr).value;
|
||||
self.with_item_id_pushed(expr.id, |v| intravisit::walk_expr(v, expr), expr.span);
|
||||
}
|
||||
}
|
||||
|
@ -576,6 +576,12 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
|
||||
let def = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.span))
|
||||
.map_or(Def::Err, |d| d.def());
|
||||
self.record_def(ty.id, PathResolution::new(def));
|
||||
} else if let TyKind::Array(ref element, ref length) = ty.node {
|
||||
self.visit_ty(element);
|
||||
self.with_constant_rib(|this| {
|
||||
this.visit_expr(length);
|
||||
});
|
||||
return;
|
||||
}
|
||||
visit::walk_ty(self, ty);
|
||||
}
|
||||
@ -2733,6 +2739,13 @@ impl<'a> Resolver<'a> {
|
||||
self.visit_ty(ty);
|
||||
}
|
||||
}
|
||||
|
||||
ExprKind::Repeat(ref element, ref count) => {
|
||||
self.visit_expr(element);
|
||||
self.with_constant_rib(|this| {
|
||||
this.visit_expr(count);
|
||||
});
|
||||
}
|
||||
ExprKind::Call(ref callee, ref arguments) => {
|
||||
self.resolve_expr(callee, Some(&expr.node));
|
||||
for argument in arguments {
|
||||
|
@ -1664,8 +1664,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
};
|
||||
self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0
|
||||
}
|
||||
hir::TyArray(ref ty, ref e) => {
|
||||
if let Ok(length) = eval_length(tcx.global_tcx(), &e, "array length") {
|
||||
hir::TyArray(ref ty, length) => {
|
||||
let e = &tcx.map.body(length).value;
|
||||
if let Ok(length) = eval_length(tcx.global_tcx(), e, "array length") {
|
||||
tcx.mk_array(self.ast_ty_to_ty(rscope, &ty), length)
|
||||
} else {
|
||||
self.tcx().types.err
|
||||
|
@ -25,7 +25,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
expr: &hir::Expr,
|
||||
_capture: hir::CaptureClause,
|
||||
decl: &'gcx hir::FnDecl,
|
||||
body_id: hir::ExprId,
|
||||
body_id: hir::BodyId,
|
||||
expected: Expectation<'tcx>)
|
||||
-> Ty<'tcx> {
|
||||
debug!("check_expr_closure(expr={:?},expected={:?})",
|
||||
@ -39,7 +39,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
Some(ty) => self.deduce_expectations_from_expected_type(ty),
|
||||
None => (None, None),
|
||||
};
|
||||
let body = self.tcx.map.expr(body_id);
|
||||
let body = self.tcx.map.body(body_id);
|
||||
self.check_closure(expr, expected_kind, decl, body, expected_sig)
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
expr: &hir::Expr,
|
||||
opt_kind: Option<ty::ClosureKind>,
|
||||
decl: &'gcx hir::FnDecl,
|
||||
body: &'gcx hir::Expr,
|
||||
body: &'gcx hir::Body,
|
||||
expected_sig: Option<ty::FnSig<'tcx>>)
|
||||
-> Ty<'tcx> {
|
||||
debug!("check_closure opt_kind={:?} expected_sig={:?}",
|
||||
@ -73,10 +73,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
debug!("check_closure: expr.id={:?} closure_type={:?}", expr.id, closure_type);
|
||||
|
||||
let fn_sig = self.tcx
|
||||
.liberate_late_bound_regions(self.tcx.region_maps.call_site_extent(expr.id, body.id),
|
||||
&fn_ty.sig);
|
||||
let fn_sig = (**self).normalize_associated_types_in(body.span, body.id, &fn_sig);
|
||||
let extent = self.tcx.region_maps.call_site_extent(expr.id, body.value.id);
|
||||
let fn_sig = self.tcx.liberate_late_bound_regions(extent, &fn_ty.sig);
|
||||
let fn_sig = self.inh.normalize_associated_types_in(body.value.span,
|
||||
body.value.id, &fn_sig);
|
||||
|
||||
check_fn(self,
|
||||
hir::Unsafety::Normal,
|
||||
@ -84,7 +84,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
&fn_sig,
|
||||
decl,
|
||||
expr.id,
|
||||
&body);
|
||||
body);
|
||||
|
||||
// Tuple up the arguments and insert the resulting function type into
|
||||
// the `closures` table.
|
||||
|
@ -550,14 +550,25 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
|
||||
|
||||
fn visit_ty(&mut self, t: &'tcx hir::Ty) {
|
||||
match t.node {
|
||||
hir::TyArray(_, ref expr) => {
|
||||
check_const_with_type(self.ccx, &expr, self.ccx.tcx.types.usize, expr.id);
|
||||
hir::TyArray(_, length) => {
|
||||
check_const_with_type(self.ccx, length, self.ccx.tcx.types.usize, length.node_id);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
intravisit::walk_ty(self, t);
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, e: &'tcx hir::Expr) {
|
||||
match e.node {
|
||||
hir::ExprRepeat(_, count) => {
|
||||
check_const_with_type(self.ccx, count, self.ccx.tcx.types.usize, count.node_id);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
intravisit::walk_expr(self, e);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
|
||||
@ -639,28 +650,28 @@ pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult {
|
||||
|
||||
fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
decl: &'tcx hir::FnDecl,
|
||||
body_id: hir::ExprId,
|
||||
body_id: hir::BodyId,
|
||||
fn_id: ast::NodeId,
|
||||
span: Span) {
|
||||
let body = ccx.tcx.map.expr(body_id);
|
||||
let body = ccx.tcx.map.body(body_id);
|
||||
|
||||
let raw_fty = ccx.tcx.item_type(ccx.tcx.map.local_def_id(fn_id));
|
||||
let fn_ty = match raw_fty.sty {
|
||||
ty::TyFnDef(.., f) => f,
|
||||
_ => span_bug!(body.span, "check_bare_fn: function type expected")
|
||||
_ => span_bug!(body.value.span, "check_bare_fn: function type expected")
|
||||
};
|
||||
|
||||
check_abi(ccx, span, fn_ty.abi);
|
||||
|
||||
ccx.inherited(fn_id).enter(|inh| {
|
||||
// Compute the fty from point of view of inside fn.
|
||||
let fn_scope = inh.tcx.region_maps.call_site_extent(fn_id, body_id.node_id());
|
||||
let fn_scope = inh.tcx.region_maps.call_site_extent(fn_id, body_id.node_id);
|
||||
let fn_sig =
|
||||
fn_ty.sig.subst(inh.tcx, &inh.parameter_environment.free_substs);
|
||||
let fn_sig =
|
||||
inh.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
|
||||
let fn_sig =
|
||||
inh.normalize_associated_types_in(body.span, body_id.node_id(), &fn_sig);
|
||||
inh.normalize_associated_types_in(body.value.span, body_id.node_id, &fn_sig);
|
||||
|
||||
let fcx = check_fn(&inh, fn_ty.unsafety, fn_id, &fn_sig, decl, fn_id, body);
|
||||
|
||||
@ -670,7 +681,7 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
fcx.check_casts();
|
||||
fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
|
||||
|
||||
fcx.regionck_fn(fn_id, decl, body_id);
|
||||
fcx.regionck_fn(fn_id, decl, body);
|
||||
fcx.resolve_type_vars_in_fn(decl, body, fn_id);
|
||||
});
|
||||
}
|
||||
@ -740,21 +751,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
|
||||
intravisit::walk_pat(self, p);
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, b: &'gcx hir::Block) {
|
||||
// non-obvious: the `blk` variable maps to region lb, so
|
||||
// we have to keep this up-to-date. This
|
||||
// is... unfortunate. It'd be nice to not need this.
|
||||
intravisit::walk_block(self, b);
|
||||
}
|
||||
|
||||
// Since an expr occurs as part of the type fixed size arrays we
|
||||
// need to record the type for that node
|
||||
fn visit_ty(&mut self, t: &'gcx hir::Ty) {
|
||||
match t.node {
|
||||
hir::TyArray(ref ty, ref count_expr) => {
|
||||
self.visit_ty(&ty);
|
||||
self.fcx.check_expr_with_hint(&count_expr, self.fcx.tcx.types.usize);
|
||||
}
|
||||
hir::TyBareFn(ref function_declaration) => {
|
||||
intravisit::walk_fn_decl_nopat(self, &function_declaration.decl);
|
||||
walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
|
||||
@ -765,7 +763,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
|
||||
|
||||
// Don't descend into the bodies of nested closures
|
||||
fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
|
||||
_: hir::ExprId, _: Span, _: ast::NodeId) { }
|
||||
_: hir::BodyId, _: Span, _: ast::NodeId) { }
|
||||
}
|
||||
|
||||
/// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
|
||||
@ -780,7 +778,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
|
||||
fn_sig: &ty::FnSig<'tcx>,
|
||||
decl: &'gcx hir::FnDecl,
|
||||
fn_id: ast::NodeId,
|
||||
body: &'gcx hir::Expr)
|
||||
body: &'gcx hir::Body)
|
||||
-> FnCtxt<'a, 'gcx, 'tcx>
|
||||
{
|
||||
let mut fn_sig = fn_sig.clone();
|
||||
@ -789,7 +787,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
|
||||
|
||||
// Create the function context. This is either derived from scratch or,
|
||||
// in the case of function expressions, based on the outer context.
|
||||
let mut fcx = FnCtxt::new(inherited, None, body.id);
|
||||
let mut fcx = FnCtxt::new(inherited, None, body.value.id);
|
||||
let ret_ty = fn_sig.output();
|
||||
*fcx.ps.borrow_mut() = UnsafetyState::function(unsafety, unsafety_id);
|
||||
|
||||
@ -822,12 +820,12 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
|
||||
fcx.write_ty(input.id, arg_ty);
|
||||
}
|
||||
|
||||
visit.visit_expr(body);
|
||||
visit.visit_body(body);
|
||||
}
|
||||
|
||||
inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig);
|
||||
|
||||
fcx.check_expr_coercable_to_type(body, fcx.ret_ty.unwrap());
|
||||
fcx.check_expr_coercable_to_type(&body.value, fcx.ret_ty.unwrap());
|
||||
|
||||
fcx
|
||||
}
|
||||
@ -852,8 +850,8 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
|
||||
let _indenter = indenter();
|
||||
match it.node {
|
||||
// Consts can play a role in type-checking, so they are included here.
|
||||
hir::ItemStatic(.., ref e) |
|
||||
hir::ItemConst(_, ref e) => check_const(ccx, &e, it.id),
|
||||
hir::ItemStatic(.., e) |
|
||||
hir::ItemConst(_, e) => check_const(ccx, e, it.id),
|
||||
hir::ItemEnum(ref enum_definition, _) => {
|
||||
check_enum_variants(ccx,
|
||||
it.span,
|
||||
@ -937,8 +935,8 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
|
||||
for impl_item_ref in impl_item_refs {
|
||||
let impl_item = ccx.tcx.map.impl_item(impl_item_ref.id);
|
||||
match impl_item.node {
|
||||
hir::ImplItemKind::Const(_, ref expr) => {
|
||||
check_const(ccx, &expr, impl_item.id)
|
||||
hir::ImplItemKind::Const(_, expr) => {
|
||||
check_const(ccx, expr, impl_item.id)
|
||||
}
|
||||
hir::ImplItemKind::Method(ref sig, body_id) => {
|
||||
check_bare_fn(ccx, &sig.decl, body_id, impl_item.id, impl_item.span);
|
||||
@ -953,8 +951,8 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
|
||||
for trait_item_ref in trait_item_refs {
|
||||
let trait_item = ccx.tcx.map.trait_item(trait_item_ref.id);
|
||||
match trait_item.node {
|
||||
hir::TraitItemKind::Const(_, Some(ref expr)) => {
|
||||
check_const(ccx, &expr, trait_item.id)
|
||||
hir::TraitItemKind::Const(_, Some(expr)) => {
|
||||
check_const(ccx, expr, trait_item.id)
|
||||
}
|
||||
hir::TraitItemKind::Method(ref sig, Some(body_id)) => {
|
||||
check_bare_fn(ccx, &sig.decl, body_id, trait_item.id, trait_item.span);
|
||||
@ -1127,7 +1125,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
compare_impl_method(ccx,
|
||||
&ty_impl_item,
|
||||
impl_item.span,
|
||||
body_id.node_id(),
|
||||
body_id.node_id,
|
||||
&ty_trait_item,
|
||||
impl_trait_ref,
|
||||
trait_span,
|
||||
@ -1137,7 +1135,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
compare_impl_method(ccx,
|
||||
&ty_impl_item,
|
||||
impl_item.span,
|
||||
body_id.node_id(),
|
||||
body_id.node_id,
|
||||
&ty_trait_item,
|
||||
impl_trait_ref,
|
||||
trait_span,
|
||||
@ -1248,37 +1246,38 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
|
||||
/// Checks a constant with a given type.
|
||||
fn check_const_with_type<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
|
||||
expr: &'tcx hir::Expr,
|
||||
body: hir::BodyId,
|
||||
expected_type: Ty<'tcx>,
|
||||
id: ast::NodeId) {
|
||||
let body = ccx.tcx.map.body(body);
|
||||
ccx.inherited(id).enter(|inh| {
|
||||
let fcx = FnCtxt::new(&inh, None, expr.id);
|
||||
fcx.require_type_is_sized(expected_type, expr.span, traits::ConstSized);
|
||||
let fcx = FnCtxt::new(&inh, None, body.value.id);
|
||||
fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
|
||||
|
||||
// Gather locals in statics (because of block expressions).
|
||||
// This is technically unnecessary because locals in static items are forbidden,
|
||||
// but prevents type checking from blowing up before const checking can properly
|
||||
// emit an error.
|
||||
GatherLocalsVisitor { fcx: &fcx }.visit_expr(expr);
|
||||
GatherLocalsVisitor { fcx: &fcx }.visit_body(body);
|
||||
|
||||
fcx.check_expr_coercable_to_type(expr, expected_type);
|
||||
fcx.check_expr_coercable_to_type(&body.value, expected_type);
|
||||
|
||||
fcx.select_all_obligations_and_apply_defaults();
|
||||
fcx.closure_analyze(expr);
|
||||
fcx.closure_analyze(body);
|
||||
fcx.select_obligations_where_possible();
|
||||
fcx.check_casts();
|
||||
fcx.select_all_obligations_or_error();
|
||||
|
||||
fcx.regionck_expr(expr);
|
||||
fcx.resolve_type_vars_in_expr(expr, id);
|
||||
fcx.regionck_expr(body);
|
||||
fcx.resolve_type_vars_in_expr(body, id);
|
||||
});
|
||||
}
|
||||
|
||||
fn check_const<'a, 'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
expr: &'tcx hir::Expr,
|
||||
body: hir::BodyId,
|
||||
id: ast::NodeId) {
|
||||
let decl_ty = ccx.tcx.item_type(ccx.tcx.map.local_def_id(id));
|
||||
check_const_with_type(ccx, expr, decl_ty, id);
|
||||
check_const_with_type(ccx, body, decl_ty, id);
|
||||
}
|
||||
|
||||
/// Checks whether a type can be represented in memory. In particular, it
|
||||
@ -1353,8 +1352,8 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
|
||||
let repr_type_ty = ccx.tcx.enum_repr_type(Some(&hint)).to_ty(ccx.tcx);
|
||||
for v in vs {
|
||||
if let Some(ref e) = v.node.disr_expr {
|
||||
check_const_with_type(ccx, e, repr_type_ty, e.id);
|
||||
if let Some(e) = v.node.disr_expr {
|
||||
check_const_with_type(ccx, e, repr_type_ty, e.node_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1370,11 +1369,11 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
|
||||
let variant_i = ccx.tcx.map.expect_variant(variant_i_node_id);
|
||||
let i_span = match variant_i.node.disr_expr {
|
||||
Some(ref expr) => expr.span,
|
||||
Some(expr) => ccx.tcx.map.span(expr.node_id),
|
||||
None => ccx.tcx.map.span(variant_i_node_id)
|
||||
};
|
||||
let span = match v.node.disr_expr {
|
||||
Some(ref expr) => expr.span,
|
||||
Some(expr) => ccx.tcx.map.span(expr.node_id),
|
||||
None => v.span
|
||||
};
|
||||
struct_span_err!(ccx.tcx.sess, span, E0081,
|
||||
@ -1648,12 +1647,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
match self.locals.borrow().get(&nid) {
|
||||
Some(&t) => t,
|
||||
None => {
|
||||
struct_span_err!(self.tcx.sess, span, E0513,
|
||||
"no type for local variable {}",
|
||||
self.tcx.map.node_to_string(nid))
|
||||
.span_label(span, &"no type for variable")
|
||||
.emit();
|
||||
self.tcx.types.err
|
||||
span_bug!(span, "no type for local variable {}",
|
||||
self.tcx.map.node_to_string(nid));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3826,10 +3821,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
self.check_method_call(expr, name, args, &tps[..], expected, lvalue_pref)
|
||||
}
|
||||
hir::ExprCast(ref e, ref t) => {
|
||||
if let hir::TyArray(_, ref count_expr) = t.node {
|
||||
self.check_expr_with_hint(&count_expr, tcx.types.usize);
|
||||
}
|
||||
|
||||
// Find the type of `e`. Supply hints based on the type we are casting to,
|
||||
// if appropriate.
|
||||
let t_cast = self.to_ty(t);
|
||||
@ -3891,9 +3882,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
tcx.mk_array(unified, args.len())
|
||||
}
|
||||
hir::ExprRepeat(ref element, ref count_expr) => {
|
||||
self.check_expr_has_type(&count_expr, tcx.types.usize);
|
||||
let count = eval_length(self.tcx.global_tcx(), &count_expr, "repeat count")
|
||||
hir::ExprRepeat(ref element, count) => {
|
||||
let count_expr = &tcx.map.body(count).value;
|
||||
let count = eval_length(self.tcx.global_tcx(), count_expr, "repeat count")
|
||||
.unwrap_or(0);
|
||||
|
||||
let uty = match expected {
|
||||
|
@ -113,12 +113,13 @@ macro_rules! ignore_err {
|
||||
// PUBLIC ENTRY POINTS
|
||||
|
||||
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn regionck_expr(&self, e: &'gcx hir::Expr) {
|
||||
let mut rcx = RegionCtxt::new(self, RepeatingScope(e.id), e.id, Subject(e.id));
|
||||
pub fn regionck_expr(&self, body: &'gcx hir::Body) {
|
||||
let id = body.value.id;
|
||||
let mut rcx = RegionCtxt::new(self, RepeatingScope(id), id, Subject(id));
|
||||
if self.err_count_since_creation() == 0 {
|
||||
// regionck assumes typeck succeeded
|
||||
rcx.visit_expr(e);
|
||||
rcx.visit_region_obligations(e.id);
|
||||
rcx.visit_body(body);
|
||||
rcx.visit_region_obligations(id);
|
||||
}
|
||||
rcx.resolve_regions_and_report_errors();
|
||||
}
|
||||
@ -141,14 +142,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn regionck_fn(&self,
|
||||
fn_id: ast::NodeId,
|
||||
decl: &hir::FnDecl,
|
||||
body_id: hir::ExprId) {
|
||||
body: &'gcx hir::Body) {
|
||||
debug!("regionck_fn(id={})", fn_id);
|
||||
let node_id = body_id.node_id();
|
||||
let node_id = body.value.id;
|
||||
let mut rcx = RegionCtxt::new(self, RepeatingScope(node_id), node_id, Subject(fn_id));
|
||||
|
||||
if self.err_count_since_creation() == 0 {
|
||||
// regionck assumes typeck succeeded
|
||||
rcx.visit_fn_body(fn_id, decl, body_id, self.tcx.map.span(fn_id));
|
||||
rcx.visit_fn_body(fn_id, decl, body, self.tcx.map.span(fn_id));
|
||||
}
|
||||
|
||||
rcx.free_region_map.relate_free_regions_from_predicates(
|
||||
@ -268,14 +269,16 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
fn visit_fn_body(&mut self,
|
||||
id: ast::NodeId, // the id of the fn itself
|
||||
fn_decl: &hir::FnDecl,
|
||||
body_id: hir::ExprId,
|
||||
body: &'gcx hir::Body,
|
||||
span: Span)
|
||||
{
|
||||
// When we enter a function, we can derive
|
||||
debug!("visit_fn_body(id={})", id);
|
||||
|
||||
let body_id = body.id();
|
||||
|
||||
let call_site = self.tcx.region_maps.lookup_code_extent(
|
||||
region::CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id() });
|
||||
region::CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id });
|
||||
let old_call_site_scope = self.set_call_site_scope(Some(call_site));
|
||||
|
||||
let fn_sig = {
|
||||
@ -298,20 +301,19 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
let fn_sig_tys: Vec<_> =
|
||||
fn_sig.inputs().iter().cloned().chain(Some(fn_sig.output())).collect();
|
||||
|
||||
let old_body_id = self.set_body_id(body_id.node_id());
|
||||
self.relate_free_regions(&fn_sig_tys[..], body_id.node_id(), span);
|
||||
self.link_fn_args(self.tcx.region_maps.node_extent(body_id.node_id()),
|
||||
let old_body_id = self.set_body_id(body_id.node_id);
|
||||
self.relate_free_regions(&fn_sig_tys[..], body_id.node_id, span);
|
||||
self.link_fn_args(self.tcx.region_maps.node_extent(body_id.node_id),
|
||||
&fn_decl.inputs[..]);
|
||||
let body = self.tcx.map.expr(body_id);
|
||||
self.visit_expr(body);
|
||||
self.visit_region_obligations(body_id.node_id());
|
||||
self.visit_body(body);
|
||||
self.visit_region_obligations(body_id.node_id);
|
||||
|
||||
let call_site_scope = self.call_site_scope.unwrap();
|
||||
debug!("visit_fn_body body.id {} call_site_scope: {:?}",
|
||||
body.id, call_site_scope);
|
||||
debug!("visit_fn_body body.id {:?} call_site_scope: {:?}",
|
||||
body.id(), call_site_scope);
|
||||
let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope));
|
||||
self.type_of_node_must_outlive(infer::CallReturn(span),
|
||||
body_id.node_id(),
|
||||
body_id.node_id,
|
||||
call_site_region);
|
||||
|
||||
self.region_bound_pairs.truncate(old_region_bounds_pairs_len);
|
||||
@ -478,12 +480,13 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
// regions, until regionck, as described in #3238.
|
||||
|
||||
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
|
||||
NestedVisitorMap::OnlyBodies(&self.tcx.map)
|
||||
NestedVisitorMap::None
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, _fk: intravisit::FnKind<'gcx>, fd: &'gcx hir::FnDecl,
|
||||
b: hir::ExprId, span: Span, id: ast::NodeId) {
|
||||
self.visit_fn_body(id, fd, b, span)
|
||||
b: hir::BodyId, span: Span, id: ast::NodeId) {
|
||||
let body = self.tcx.map.body(b);
|
||||
self.visit_fn_body(id, fd, body, span)
|
||||
}
|
||||
|
||||
//visit_pat: visit_pat, // (..) see above
|
||||
@ -826,8 +829,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
fn check_expr_fn_block(&mut self,
|
||||
expr: &'gcx hir::Expr,
|
||||
body_id: hir::ExprId) {
|
||||
let repeating_scope = self.set_repeating_scope(body_id.node_id());
|
||||
body_id: hir::BodyId) {
|
||||
let repeating_scope = self.set_repeating_scope(body_id.node_id);
|
||||
intravisit::walk_expr(self, expr);
|
||||
self.set_repeating_scope(repeating_scope);
|
||||
}
|
||||
|
@ -57,12 +57,12 @@ use rustc::util::nodemap::NodeMap;
|
||||
// PUBLIC ENTRY POINTS
|
||||
|
||||
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn closure_analyze(&self, body: &'gcx hir::Expr) {
|
||||
pub fn closure_analyze(&self, body: &'gcx hir::Body) {
|
||||
let mut seed = SeedBorrowKind::new(self);
|
||||
seed.visit_expr(body);
|
||||
seed.visit_body(body);
|
||||
|
||||
let mut adjust = AdjustBorrowKind::new(self, seed.temp_closure_kinds);
|
||||
adjust.visit_expr(body);
|
||||
adjust.visit_body(body);
|
||||
|
||||
// it's our job to process these.
|
||||
assert!(self.deferred_call_resolutions.borrow().is_empty());
|
||||
@ -79,13 +79,15 @@ struct SeedBorrowKind<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Visitor<'gcx> for SeedBorrowKind<'a, 'gcx, 'tcx> {
|
||||
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
|
||||
NestedVisitorMap::OnlyBodies(&self.fcx.tcx.map)
|
||||
NestedVisitorMap::None
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'gcx hir::Expr) {
|
||||
match expr.node {
|
||||
hir::ExprClosure(cc, _, body_id, _) => {
|
||||
self.check_closure(expr, cc, body_id);
|
||||
let body = self.fcx.tcx.map.body(body_id);
|
||||
self.visit_body(body);
|
||||
self.check_closure(expr, cc);
|
||||
}
|
||||
|
||||
_ => { }
|
||||
@ -102,8 +104,7 @@ impl<'a, 'gcx, 'tcx> SeedBorrowKind<'a, 'gcx, 'tcx> {
|
||||
|
||||
fn check_closure(&mut self,
|
||||
expr: &hir::Expr,
|
||||
capture_clause: hir::CaptureClause,
|
||||
_body_id: hir::ExprId)
|
||||
capture_clause: hir::CaptureClause)
|
||||
{
|
||||
let closure_def_id = self.fcx.tcx.map.local_def_id(expr.id);
|
||||
if !self.fcx.tables.borrow().closure_kinds.contains_key(&closure_def_id) {
|
||||
@ -157,15 +158,14 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
|
||||
id: ast::NodeId,
|
||||
span: Span,
|
||||
decl: &hir::FnDecl,
|
||||
body_id: hir::ExprId) {
|
||||
body: &hir::Body) {
|
||||
/*!
|
||||
* Analysis starting point.
|
||||
*/
|
||||
|
||||
debug!("analyze_closure(id={:?}, body.id={:?})", id, body_id);
|
||||
debug!("analyze_closure(id={:?}, body.id={:?})", id, body.id());
|
||||
|
||||
{
|
||||
let body = self.fcx.tcx.map.expr(body_id);
|
||||
let mut euv =
|
||||
euv::ExprUseVisitor::with_options(self,
|
||||
self.fcx,
|
||||
@ -491,17 +491,20 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Visitor<'gcx> for AdjustBorrowKind<'a, 'gcx, 'tcx> {
|
||||
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
|
||||
NestedVisitorMap::OnlyBodies(&self.fcx.tcx.map)
|
||||
NestedVisitorMap::None
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self,
|
||||
fn_kind: intravisit::FnKind<'gcx>,
|
||||
decl: &'gcx hir::FnDecl,
|
||||
body: hir::ExprId,
|
||||
body: hir::BodyId,
|
||||
span: Span,
|
||||
id: ast::NodeId)
|
||||
{
|
||||
intravisit::walk_fn(self, fn_kind, decl, body, span, id);
|
||||
|
||||
let body = self.fcx.tcx.map.body(body);
|
||||
self.visit_body(body);
|
||||
self.analyze_closure(id, span, decl, body);
|
||||
}
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
||||
|
||||
fn check_item_fn(&mut self,
|
||||
item: &hir::Item,
|
||||
body_id: hir::ExprId)
|
||||
body_id: hir::BodyId)
|
||||
{
|
||||
self.for_item(item).with_fcx(|fcx, this| {
|
||||
let free_substs = &fcx.parameter_environment.free_substs;
|
||||
@ -354,7 +354,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
||||
let predicates = fcx.instantiate_bounds(item.span, def_id, free_substs);
|
||||
|
||||
let mut implied_bounds = vec![];
|
||||
let free_id_outlive = fcx.tcx.region_maps.call_site_extent(item.id, body_id.node_id());
|
||||
let free_id_outlive = fcx.tcx.region_maps.call_site_extent(item.id, body_id.node_id);
|
||||
this.check_fn_or_method(fcx, item.span, bare_fn_ty, &predicates,
|
||||
free_id_outlive, &mut implied_bounds);
|
||||
implied_bounds
|
||||
|
@ -34,10 +34,10 @@ use rustc::hir::{self, PatKind};
|
||||
// Entry point functions
|
||||
|
||||
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn resolve_type_vars_in_expr(&self, e: &'gcx hir::Expr, item_id: ast::NodeId) {
|
||||
pub fn resolve_type_vars_in_expr(&self, body: &'gcx hir::Body, item_id: ast::NodeId) {
|
||||
assert_eq!(self.writeback_errors.get(), false);
|
||||
let mut wbcx = WritebackCx::new(self);
|
||||
wbcx.visit_expr(e);
|
||||
wbcx.visit_body(body);
|
||||
wbcx.visit_upvar_borrow_map();
|
||||
wbcx.visit_closures();
|
||||
wbcx.visit_liberated_fn_sigs();
|
||||
@ -48,11 +48,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
pub fn resolve_type_vars_in_fn(&self,
|
||||
decl: &'gcx hir::FnDecl,
|
||||
body: &'gcx hir::Expr,
|
||||
body: &'gcx hir::Body,
|
||||
item_id: ast::NodeId) {
|
||||
assert_eq!(self.writeback_errors.get(), false);
|
||||
let mut wbcx = WritebackCx::new(self);
|
||||
wbcx.visit_expr(body);
|
||||
wbcx.visit_body(body);
|
||||
for arg in &decl.inputs {
|
||||
wbcx.visit_node_id(ResolvingPattern(arg.pat.span), arg.id);
|
||||
wbcx.visit_pat(&arg.pat);
|
||||
@ -188,7 +188,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
||||
|
||||
impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
|
||||
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
|
||||
NestedVisitorMap::OnlyBodies(&self.fcx.tcx.map)
|
||||
NestedVisitorMap::None
|
||||
}
|
||||
|
||||
fn visit_stmt(&mut self, s: &'gcx hir::Stmt) {
|
||||
@ -211,10 +211,13 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
|
||||
self.visit_method_map_entry(ResolvingExpr(e.span),
|
||||
MethodCall::expr(e.id));
|
||||
|
||||
if let hir::ExprClosure(_, ref decl, ..) = e.node {
|
||||
if let hir::ExprClosure(_, ref decl, body, _) = e.node {
|
||||
for input in &decl.inputs {
|
||||
self.visit_node_id(ResolvingExpr(e.span), input.id);
|
||||
}
|
||||
|
||||
let body = self.fcx.tcx.map.body(body);
|
||||
self.visit_body(body);
|
||||
}
|
||||
|
||||
intravisit::walk_expr(self, e);
|
||||
@ -257,10 +260,6 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
|
||||
|
||||
fn visit_ty(&mut self, t: &'gcx hir::Ty) {
|
||||
match t.node {
|
||||
hir::TyArray(ref ty, ref count_expr) => {
|
||||
self.visit_ty(&ty);
|
||||
self.write_ty_to_tcx(count_expr.id, self.tcx().types.usize);
|
||||
}
|
||||
hir::TyBareFn(ref function_declaration) => {
|
||||
intravisit::walk_fn_decl_nopat(self, &function_declaration.decl);
|
||||
walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
|
||||
|
@ -1095,7 +1095,8 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
let mut prev_disr = None::<ty::Disr>;
|
||||
let variants = def.variants.iter().map(|v| {
|
||||
let wrapped_disr = prev_disr.map_or(initial, |d| d.wrap_incr());
|
||||
let disr = if let Some(ref e) = v.node.disr_expr {
|
||||
let disr = if let Some(e) = v.node.disr_expr {
|
||||
let e = &tcx.map.body(e).value;
|
||||
evaluate_disr_expr(ccx, repr_type, e)
|
||||
} else if let Some(disr) = repr_type.disr_incr(tcx, prev_disr) {
|
||||
Some(disr)
|
||||
|
@ -3866,45 +3866,6 @@ extern "platform-intrinsic" {
|
||||
```
|
||||
"##,
|
||||
|
||||
E0513: r##"
|
||||
The type of the variable couldn't be found out.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0513
|
||||
use std::mem;
|
||||
|
||||
unsafe {
|
||||
let size = mem::size_of::<u32>();
|
||||
mem::transmute_copy::<u32, [u8; size]>(&8_8);
|
||||
// error: no type for local variable
|
||||
}
|
||||
```
|
||||
|
||||
To fix this error, please use a constant size instead of `size`. To make
|
||||
this error more obvious, you could run:
|
||||
|
||||
```compile_fail,E0080
|
||||
use std::mem;
|
||||
|
||||
unsafe {
|
||||
mem::transmute_copy::<u32, [u8; mem::size_of::<u32>()]>(&8_8);
|
||||
// error: constant evaluation error
|
||||
}
|
||||
```
|
||||
|
||||
So now, you can fix your code by setting the size directly:
|
||||
|
||||
```
|
||||
use std::mem;
|
||||
|
||||
unsafe {
|
||||
mem::transmute_copy::<u32, [u8; 4]>(&8_8);
|
||||
// `u32` is 4 bytes so we replace the `mem::size_of` call with its size
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0516: r##"
|
||||
The `typeof` keyword is currently reserved but unimplemented.
|
||||
Erroneous code example:
|
||||
|
@ -1270,9 +1270,9 @@ impl Clean<PolyTrait> for hir::PolyTraitRef {
|
||||
impl Clean<Item> for hir::TraitItem {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
let inner = match self.node {
|
||||
hir::TraitItemKind::Const(ref ty, ref default) => {
|
||||
hir::TraitItemKind::Const(ref ty, default) => {
|
||||
AssociatedConstItem(ty.clean(cx),
|
||||
default.as_ref().map(|e| pprust::expr_to_string(&e)))
|
||||
default.map(|e| print_const_expr(cx, e)))
|
||||
}
|
||||
hir::TraitItemKind::Method(ref sig, Some(_)) => {
|
||||
MethodItem(sig.clean(cx))
|
||||
@ -1300,9 +1300,9 @@ impl Clean<Item> for hir::TraitItem {
|
||||
impl Clean<Item> for hir::ImplItem {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
let inner = match self.node {
|
||||
hir::ImplItemKind::Const(ref ty, ref expr) => {
|
||||
hir::ImplItemKind::Const(ref ty, expr) => {
|
||||
AssociatedConstItem(ty.clean(cx),
|
||||
Some(pprust::expr_to_string(expr)))
|
||||
Some(print_const_expr(cx, expr)))
|
||||
}
|
||||
hir::ImplItemKind::Method(ref sig, _) => {
|
||||
MethodItem(sig.clean(cx))
|
||||
@ -1687,11 +1687,12 @@ impl Clean<Type> for hir::Ty {
|
||||
BorrowedRef {lifetime: l.clean(cx), mutability: m.mutbl.clean(cx),
|
||||
type_: box m.ty.clean(cx)},
|
||||
TySlice(ref ty) => Vector(box ty.clean(cx)),
|
||||
TyArray(ref ty, ref e) => {
|
||||
TyArray(ref ty, e) => {
|
||||
use rustc_const_math::{ConstInt, ConstUsize};
|
||||
use rustc_const_eval::eval_const_expr;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
|
||||
let e = &cx.tcx.map.body(e).value;
|
||||
let n = match eval_const_expr(cx.tcx, e) {
|
||||
ConstVal::Integral(ConstInt::Usize(u)) => match u {
|
||||
ConstUsize::Us16(u) => u.to_string(),
|
||||
@ -2372,7 +2373,7 @@ impl Clean<Item> for doctree::Static {
|
||||
inner: StaticItem(Static {
|
||||
type_: self.type_.clean(cx),
|
||||
mutability: self.mutability.clean(cx),
|
||||
expr: pprust::expr_to_string(&self.expr),
|
||||
expr: print_const_expr(cx, self.expr),
|
||||
}),
|
||||
}
|
||||
}
|
||||
@ -2396,7 +2397,7 @@ impl Clean<Item> for doctree::Constant {
|
||||
deprecation: self.depr.clean(cx),
|
||||
inner: ConstantItem(Constant {
|
||||
type_: self.type_.clean(cx),
|
||||
expr: pprust::expr_to_string(&self.expr),
|
||||
expr: print_const_expr(cx, self.expr),
|
||||
}),
|
||||
}
|
||||
}
|
||||
@ -2724,6 +2725,10 @@ fn name_from_pat(p: &hir::Pat) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
fn print_const_expr(cx: &DocContext, body: hir::BodyId) -> String {
|
||||
pprust::expr_to_string(&cx.tcx.map.body(body).value)
|
||||
}
|
||||
|
||||
/// Given a type Path, resolve it to a Type using the TyCtxt
|
||||
fn resolve_type(cx: &DocContext,
|
||||
path: Path,
|
||||
|
@ -174,7 +174,7 @@ pub struct Typedef {
|
||||
pub struct Static {
|
||||
pub type_: P<hir::Ty>,
|
||||
pub mutability: hir::Mutability,
|
||||
pub expr: P<hir::Expr>,
|
||||
pub expr: hir::BodyId,
|
||||
pub name: Name,
|
||||
pub attrs: hir::HirVec<ast::Attribute>,
|
||||
pub vis: hir::Visibility,
|
||||
@ -186,7 +186,7 @@ pub struct Static {
|
||||
|
||||
pub struct Constant {
|
||||
pub type_: P<hir::Ty>,
|
||||
pub expr: P<hir::Expr>,
|
||||
pub expr: hir::BodyId,
|
||||
pub name: Name,
|
||||
pub attrs: hir::HirVec<ast::Attribute>,
|
||||
pub vis: hir::Visibility,
|
||||
|
@ -1,19 +0,0 @@
|
||||
// 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.
|
||||
|
||||
use std::mem;
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let size = mem::size_of::<u32>();
|
||||
mem::transmute_copy::<u32, [u8; size]>(&8_8); //~ ERROR E0513
|
||||
//~| NOTE no type for variable
|
||||
}
|
||||
}
|
@ -25,8 +25,10 @@ impl Foo for Def {
|
||||
}
|
||||
|
||||
pub fn test<A: Foo, B: Foo>() {
|
||||
let _array = [4; <A as Foo>::Y]; //~ ERROR E0080
|
||||
//~| non-constant path in constant
|
||||
let _array = [4; <A as Foo>::Y];
|
||||
//~^ ERROR cannot use an outer type parameter in this context [E0402]
|
||||
//~| ERROR constant evaluation error [E0080]
|
||||
//~| non-constant path in constant
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -26,7 +26,9 @@ impl Foo for Def {
|
||||
|
||||
pub fn test<A: Foo, B: Foo>() {
|
||||
let _array: [u32; <A as Foo>::Y];
|
||||
//~^ ERROR the trait bound `A: Foo` is not satisfied
|
||||
//~^ ERROR cannot use an outer type parameter in this context [E0402]
|
||||
//~| ERROR constant evaluation error [E0080]
|
||||
//~| non-constant path in constant
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -16,6 +16,4 @@ fn main() {
|
||||
//~| expected type `usize`
|
||||
//~| found type `S`
|
||||
//~| expected usize, found struct `S`
|
||||
//~| ERROR expected `usize` for repeat count, found struct [E0306]
|
||||
//~| expected `usize`
|
||||
}
|
||||
|
@ -12,8 +12,8 @@
|
||||
|
||||
fn main() {
|
||||
fn bar(n: isize) {
|
||||
// FIXME (#24414): This error message needs improvement.
|
||||
let _x: [isize; n];
|
||||
//~^ ERROR no type for local variable
|
||||
//~^ ERROR attempt to use a non-constant value in a constant [E0435]
|
||||
//~| ERROR constant evaluation error [E0080]
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,9 @@
|
||||
fn main() {
|
||||
fn bar(n: usize) {
|
||||
let _x = [0; n];
|
||||
//~^ ERROR constant evaluation error
|
||||
//~| non-constant path in constant expression
|
||||
//~| NOTE `n` is a variable
|
||||
//~^ ERROR attempt to use a non-constant value in a constant [E0435]
|
||||
//~| NOTE non-constant used with constant
|
||||
//~| NOTE unresolved path in constant expression
|
||||
//~| ERROR constant evaluation error [E0080]
|
||||
}
|
||||
}
|
||||
|
@ -13,43 +13,30 @@
|
||||
fn main() {
|
||||
let n = 1;
|
||||
let a = [0; n];
|
||||
//~^ ERROR constant evaluation error
|
||||
//~| non-constant path in constant expression
|
||||
//~^ ERROR attempt to use a non-constant value in a constant [E0435]
|
||||
let b = [0; ()];
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected type `usize`
|
||||
//~| found type `()`
|
||||
//~| expected usize, found ()
|
||||
//~| ERROR expected `usize` for repeat count, found tuple [E0306]
|
||||
//~| expected `usize`
|
||||
let c = [0; true];
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected usize, found bool
|
||||
//~| ERROR expected `usize` for repeat count, found boolean [E0306]
|
||||
//~| expected `usize`
|
||||
let d = [0; 0.5];
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected type `usize`
|
||||
//~| found type `{float}`
|
||||
//~| expected usize, found floating-point variable
|
||||
//~| ERROR expected `usize` for repeat count, found float [E0306]
|
||||
//~| expected `usize`
|
||||
let e = [0; "foo"];
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected type `usize`
|
||||
//~| found type `&'static str`
|
||||
//~| expected usize, found reference
|
||||
//~| ERROR expected `usize` for repeat count, found string literal [E0306]
|
||||
//~| expected `usize`
|
||||
let f = [0; -4_isize];
|
||||
//~^ ERROR constant evaluation error
|
||||
//~| expected usize, found isize
|
||||
//~| ERROR mismatched types
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected usize, found isize
|
||||
let f = [0_usize; -1_isize];
|
||||
//~^ ERROR constant evaluation error
|
||||
//~| expected usize, found isize
|
||||
//~| ERROR mismatched types
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected usize, found isize
|
||||
struct G {
|
||||
g: (),
|
||||
@ -59,6 +46,4 @@ fn main() {
|
||||
//~| expected type `usize`
|
||||
//~| found type `main::G`
|
||||
//~| expected usize, found struct `main::G`
|
||||
//~| ERROR expected `usize` for repeat count, found struct [E0306]
|
||||
//~| expected `usize`
|
||||
}
|
||||
|
@ -66,8 +66,10 @@ const CONST_CHANGE_TYPE_2: Option<u64> = None;
|
||||
const CONST_CHANGE_VALUE_1: i16 = 1;
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
const CONST_CHANGE_VALUE_1: i16 = 2;
|
||||
@ -78,8 +80,10 @@ const CONST_CHANGE_VALUE_1: i16 = 2;
|
||||
const CONST_CHANGE_VALUE_2: i16 = 1 + 1;
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
const CONST_CHANGE_VALUE_2: i16 = 1 + 2;
|
||||
@ -89,8 +93,10 @@ const CONST_CHANGE_VALUE_2: i16 = 1 + 2;
|
||||
const CONST_CHANGE_VALUE_3: i16 = 2 + 3;
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
const CONST_CHANGE_VALUE_3: i16 = 2 * 3;
|
||||
@ -100,8 +106,10 @@ const CONST_CHANGE_VALUE_3: i16 = 2 * 3;
|
||||
const CONST_CHANGE_VALUE_4: i16 = 1 + 2 * 3;
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
const CONST_CHANGE_VALUE_4: i16 = 1 + 2 * 4;
|
||||
|
@ -108,8 +108,10 @@ enum EnumChangeValueCStyleVariant0 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
enum EnumChangeValueCStyleVariant0 {
|
||||
@ -126,6 +128,8 @@ enum EnumChangeValueCStyleVariant1 {
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
enum EnumChangeValueCStyleVariant1 {
|
||||
|
@ -119,9 +119,11 @@ static STATIC_CHANGE_TYPE_2: Option<u16> = None;
|
||||
static STATIC_CHANGE_VALUE_1: i16 = 1;
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
static STATIC_CHANGE_VALUE_1: i16 = 2;
|
||||
|
||||
@ -131,9 +133,11 @@ static STATIC_CHANGE_VALUE_1: i16 = 2;
|
||||
static STATIC_CHANGE_VALUE_2: i16 = 1 + 1;
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
static STATIC_CHANGE_VALUE_2: i16 = 1 + 2;
|
||||
|
||||
@ -142,9 +146,11 @@ static STATIC_CHANGE_VALUE_2: i16 = 1 + 2;
|
||||
static STATIC_CHANGE_VALUE_3: i16 = 2 + 3;
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
static STATIC_CHANGE_VALUE_3: i16 = 2 * 3;
|
||||
|
||||
@ -153,9 +159,11 @@ static STATIC_CHANGE_VALUE_3: i16 = 2 * 3;
|
||||
static STATIC_CHANGE_VALUE_4: i16 = 1 + 2 * 3;
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
static STATIC_CHANGE_VALUE_4: i16 = 1 + 2 * 4;
|
||||
|
||||
|
@ -23,14 +23,14 @@ fn main() { }
|
||||
mod x {
|
||||
#[cfg(rpass1)]
|
||||
pub fn x() {
|
||||
println!("1");
|
||||
println!("{}", "1");
|
||||
}
|
||||
|
||||
#[cfg(rpass2)]
|
||||
#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")]
|
||||
#[rustc_dirty(label="TransCrateItem", cfg="rpass2")]
|
||||
pub fn x() {
|
||||
println!("2");
|
||||
println!("{}", "2");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,12 +41,12 @@ impl LintPass for Pass {
|
||||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||
fn check_fn(&mut self, cx: &LateContext,
|
||||
fk: FnKind, _: &hir::FnDecl, expr: &hir::Expr,
|
||||
fk: FnKind, _: &hir::FnDecl, body: &hir::Body,
|
||||
span: Span, node: ast::NodeId)
|
||||
{
|
||||
if let FnKind::Closure(..) = fk { return }
|
||||
|
||||
let mut extent = cx.tcx.region_maps.node_extent(expr.id);
|
||||
let mut extent = cx.tcx.region_maps.node_extent(body.value.id);
|
||||
while let Some(parent) = cx.tcx.region_maps.opt_encl_scope(extent) {
|
||||
extent = parent;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user