Auto merge of #37918 - flodiebold:separate-bodies, r=nikomatsakis

Separate function bodies from their signatures in HIR

Also give them their own dep map node.

I'm still unhappy with the handling of inlined items (1452edc1), but maybe you have a suggestion how to improve it.

Fixes #35078.

r? @nikomatsakis
This commit is contained in:
bors 2016-11-29 08:50:38 -06:00 committed by GitHub
commit f50dbd580f
81 changed files with 1807 additions and 908 deletions

View file

@ -42,6 +42,10 @@ pub enum DepNode<D: Clone + Debug> {
// Represents the HIR node with the given node-id
Hir(D),
// Represents the body of a function or method. The def-id is that of the
// function/method.
HirBody(D),
// Represents the metadata for a given HIR node, typically found
// in an extern crate.
MetaData(D),
@ -59,6 +63,7 @@ pub enum DepNode<D: Clone + Debug> {
PluginRegistrar,
StabilityIndex,
CollectItem(D),
CollectItemSig(D),
Coherence,
EffectCheck,
Liveness,
@ -150,6 +155,7 @@ impl<D: Clone + Debug> DepNode<D> {
CollectItem,
BorrowCheck,
Hir,
HirBody,
TransCrateItem,
TypeckItemType,
TypeckItemBody,
@ -199,8 +205,10 @@ impl<D: Clone + Debug> DepNode<D> {
WorkProduct(ref id) => Some(WorkProduct(id.clone())),
Hir(ref d) => op(d).map(Hir),
HirBody(ref d) => op(d).map(HirBody),
MetaData(ref d) => op(d).map(MetaData),
CollectItem(ref d) => op(d).map(CollectItem),
CollectItemSig(ref d) => op(d).map(CollectItemSig),
CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl),
CoherenceOverlapCheck(ref d) => op(d).map(CoherenceOverlapCheck),
CoherenceOverlapCheckSpecial(ref d) => op(d).map(CoherenceOverlapCheckSpecial),

View file

@ -67,6 +67,62 @@ impl<'a> FnKind<'a> {
}
}
/// Specifies what nested things a visitor wants to visit. The most
/// common choice is `OnlyBodies`, which will cause the visitor to
/// visit fn bodies for fns that it encounters, but skip over nested
/// item-like things.
///
/// See the comments on `ItemLikeVisitor` for more details on the overall
/// visit strategy.
pub enum NestedVisitorMap<'this, 'tcx: 'this> {
/// Do not visit any nested things. When you add a new
/// "non-nested" thing, you will want to audit such uses to see if
/// they remain valid.
///
/// Use this if you are only walking some particular kind of tree
/// (i.e., a type, or fn signature) and you don't want to thread a
/// HIR map around.
None,
/// Do not visit nested item-like things, but visit nested things
/// that are inside of an item-like.
///
/// **This is the most common choice.** A very commmon pattern is
/// to use `tcx.visit_all_item_likes_in_krate()` as an outer loop,
/// and to have the visitor that visits the contents of each item
/// using this setting.
OnlyBodies(&'this Map<'tcx>),
/// Visit all nested things, including item-likes.
///
/// **This is an unusual choice.** It is used when you want to
/// process everything within their lexical context. Typically you
/// kick off the visit by doing `walk_krate()`.
All(&'this Map<'tcx>),
}
impl<'this, 'tcx> NestedVisitorMap<'this, 'tcx> {
/// Returns the map to use for an "intra item-like" thing (if any).
/// e.g., function body.
pub fn intra(self) -> Option<&'this Map<'tcx>> {
match self {
NestedVisitorMap::None => None,
NestedVisitorMap::OnlyBodies(map) => Some(map),
NestedVisitorMap::All(map) => Some(map),
}
}
/// Returns the map to use for an "item-like" thing (if any).
/// e.g., item, impl-item.
pub fn inter(self) -> Option<&'this Map<'tcx>> {
match self {
NestedVisitorMap::None => None,
NestedVisitorMap::OnlyBodies(_) => None,
NestedVisitorMap::All(map) => Some(map),
}
}
}
/// Each method of the Visitor trait is a hook to be potentially
/// overridden. Each method's default implementation recursively visits
/// the substructure of the input via the corresponding `walk` method;
@ -88,13 +144,14 @@ pub trait Visitor<'v> : Sized {
// Nested items.
/// The default versions of the `visit_nested_XXX` routines invoke
/// this method to get a map to use; if they get back `None`, they
/// just skip nested things. Otherwise, they will lookup the
/// nested item-like things in the map and visit it. So the best
/// way to implement a nested visitor is to override this method
/// to return a `Map`; one advantage of this is that if we add
/// more types of nested things in the future, they will
/// automatically work.
/// this method to get a map to use. By selecting an enum variant,
/// you control which kinds of nested HIR are visited; see
/// `NestedVisitorMap` for details. By "nested HIR", we are
/// referring to bits of HIR that are not directly embedded within
/// one another but rather indirectly, through a table in the
/// crate. This is done to control dependencies during incremental
/// compilation: the non-inline bits of HIR can be tracked and
/// hashed separately.
///
/// **If for some reason you want the nested behavior, but don't
/// have a `Map` are your disposal:** then you should override the
@ -102,9 +159,7 @@ pub trait Visitor<'v> : Sized {
/// `panic!()`. This way, if a new `visit_nested_XXX` variant is
/// added in the future, we will see the panic in your code and
/// fix it appropriately.
fn nested_visit_map(&mut self) -> Option<&Map<'v>> {
None
}
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v>;
/// Invoked when a nested item is encountered. By default does
/// nothing unless you override `nested_visit_map` to return
@ -116,8 +171,7 @@ pub trait Visitor<'v> : Sized {
/// but cannot supply a `Map`; see `nested_visit_map` for advice.
#[allow(unused_variables)]
fn visit_nested_item(&mut self, id: ItemId) {
let opt_item = self.nested_visit_map()
.map(|map| map.expect_item(id.id));
let opt_item = self.nested_visit_map().inter().map(|map| map.expect_item(id.id));
if let Some(item) = opt_item {
self.visit_item(item);
}
@ -128,13 +182,23 @@ pub trait Visitor<'v> : Sized {
/// method.
#[allow(unused_variables)]
fn visit_nested_impl_item(&mut self, id: ImplItemId) {
let opt_item = self.nested_visit_map()
.map(|map| map.impl_item(id));
let opt_item = self.nested_visit_map().inter().map(|map| map.impl_item(id));
if let Some(item) = opt_item {
self.visit_impl_item(item);
}
}
/// Invoked to visit the body of a function, method or closure. Like
/// 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);
}
}
/// Visit the top-level item and (optionally) nested items / impl items. See
/// `visit_nested_item` for details.
fn visit_item(&mut self, i: &'v Item) {
@ -200,7 +264,7 @@ pub trait Visitor<'v> : Sized {
fn visit_where_predicate(&mut self, predicate: &'v WherePredicate) {
walk_where_predicate(self, predicate)
}
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Expr, s: Span, id: NodeId) {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: ExprId, s: Span, id: NodeId) {
walk_fn(self, fk, fd, b, s, id)
}
fn visit_trait_item(&mut self, ti: &'v TraitItem) {
@ -363,7 +427,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_ty(typ);
visitor.visit_expr(expr);
}
ItemFn(ref declaration, unsafety, constness, abi, ref generics, ref body) => {
ItemFn(ref declaration, unsafety, constness, abi, ref generics, body_id) => {
visitor.visit_fn(FnKind::ItemFn(item.name,
generics,
unsafety,
@ -372,7 +436,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
&item.vis,
&item.attrs),
declaration,
body,
body_id,
item.span,
item.id)
}
@ -697,13 +761,25 @@ 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,
function_body: &'v Expr,
body_id: ExprId,
_span: Span,
id: NodeId) {
visitor.visit_id(id);
walk_fn_decl(visitor, function_declaration);
walk_fn_kind(visitor, function_kind);
visitor.visit_expr(function_body)
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);
walk_fn_decl(visitor, function_declaration);
walk_fn_kind(visitor, function_kind);
visitor.visit_expr(body)
}
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) {
@ -720,13 +796,13 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
visitor.visit_generics(&sig.generics);
walk_fn_decl(visitor, &sig.decl);
}
MethodTraitItem(ref sig, Some(ref body)) => {
MethodTraitItem(ref sig, Some(body_id)) => {
visitor.visit_fn(FnKind::Method(trait_item.name,
sig,
None,
&trait_item.attrs),
&sig.decl,
body,
body_id,
trait_item.span,
trait_item.id);
}
@ -752,13 +828,13 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
visitor.visit_ty(ty);
visitor.visit_expr(expr);
}
ImplItemKind::Method(ref sig, ref body) => {
ImplItemKind::Method(ref sig, body_id) => {
visitor.visit_fn(FnKind::Method(impl_item.name,
sig,
Some(&impl_item.vis),
&impl_item.attrs),
&sig.decl,
body,
body_id,
impl_item.span,
impl_item.id);
}
@ -883,7 +959,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
visitor.visit_expr(subexpression);
walk_list!(visitor, visit_arm, arms);
}
ExprClosure(_, ref function_declaration, ref body, _fn_decl_span) => {
ExprClosure(_, ref function_declaration, body, _fn_decl_span) => {
visitor.visit_fn(FnKind::Closure(&expression.attrs),
function_declaration,
body,
@ -998,13 +1074,14 @@ impl IdRange {
}
pub struct IdRangeComputingVisitor {
pub result: IdRange,
pub struct IdRangeComputingVisitor<'a, 'ast: 'a> {
result: IdRange,
map: &'a map::Map<'ast>,
}
impl IdRangeComputingVisitor {
pub fn new() -> IdRangeComputingVisitor {
IdRangeComputingVisitor { result: IdRange::max() }
impl<'a, 'ast> IdRangeComputingVisitor<'a, 'ast> {
pub fn new(map: &'a map::Map<'ast>) -> IdRangeComputingVisitor<'a, 'ast> {
IdRangeComputingVisitor { result: IdRange::max(), map: map }
}
pub fn result(&self) -> IdRange {
@ -1012,20 +1089,25 @@ impl IdRangeComputingVisitor {
}
}
impl<'v> Visitor<'v> for IdRangeComputingVisitor {
impl<'a, 'ast> Visitor<'ast> for IdRangeComputingVisitor<'a, 'ast> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> {
NestedVisitorMap::OnlyBodies(&self.map)
}
fn visit_id(&mut self, id: NodeId) {
self.result.add(id);
}
}
/// Computes the id range for a single fn body, ignoring nested items.
pub fn compute_id_range_for_fn_body(fk: FnKind,
decl: &FnDecl,
body: &Expr,
sp: Span,
id: NodeId)
-> IdRange {
let mut visitor = IdRangeComputingVisitor::new();
visitor.visit_fn(fk, decl, body, sp, id);
pub fn compute_id_range_for_fn_body<'v>(fk: FnKind<'v>,
decl: &'v FnDecl,
body: &'v Expr,
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.result()
}

View file

@ -41,8 +41,10 @@ use super::intravisit::Visitor;
/// item-like things.
/// - Example: Lifetime resolution, which wants to bring lifetimes declared on the
/// impl into scope while visiting the impl-items, and then back out again.
/// - How: Implement `intravisit::Visitor` and override the `visit_nested_foo()` foo methods
/// as needed. Walk your crate with `intravisit::walk_crate()` invoked on `tcx.map.krate()`.
/// - How: Implement `intravisit::Visitor` and override the
/// `visit_nested_map()` methods to return
/// `NestedVisitorMap::All`. Walk your crate with
/// `intravisit::walk_crate()` invoked on `tcx.map.krate()`.
/// - Pro: Visitor methods for any kind of HIR node, not just item-like things.
/// - Pro: Preserves nesting information
/// - Con: Does not integrate well into dependency tracking.

View file

@ -47,9 +47,12 @@ 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 std::collections::BTreeMap;
use std::iter;
use std::mem;
use syntax::ast::*;
use syntax::errors;
use syntax::ptr::P;
@ -68,6 +71,7 @@ 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.
@ -104,6 +108,7 @@ 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(),
impl_items: BTreeMap::new(),
@ -120,6 +125,23 @@ enum ParamMode {
impl<'a> LoweringContext<'a> {
fn lower_crate(mut self, c: &Crate) -> hir::Crate {
self.lower_items(c);
let module = self.lower_mod(&c.module);
let attrs = self.lower_attrs(&c.attrs);
let exported_macros = c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect();
hir::Crate {
module: module,
attrs: attrs,
span: c.span,
exported_macros: exported_macros,
items: self.items,
impl_items: self.impl_items,
exprs: mem::replace(&mut self.exprs, FnvHashMap()),
}
}
fn lower_items(&mut self, c: &Crate) {
struct ItemLowerer<'lcx, 'interner: 'lcx> {
lctx: &'lcx mut LoweringContext<'interner>,
}
@ -139,16 +161,14 @@ impl<'a> LoweringContext<'a> {
}
}
visit::walk_crate(&mut ItemLowerer { lctx: &mut self }, c);
let mut item_lowerer = ItemLowerer { lctx: self };
visit::walk_crate(&mut item_lowerer, c);
}
hir::Crate {
module: self.lower_mod(&c.module),
attrs: self.lower_attrs(&c.attrs),
span: c.span,
exported_macros: c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect(),
items: self.items,
impl_items: self.impl_items,
}
fn record_expr(&mut self, expr: hir::Expr) -> hir::ExprId {
let id = hir::ExprId(expr.id);
self.exprs.insert(id, expr);
id
}
fn next_id(&self) -> NodeId {
@ -825,12 +845,14 @@ impl<'a> LoweringContext<'a> {
}
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);
hir::ItemFn(self.lower_fn_decl(decl),
self.lower_unsafety(unsafety),
self.lower_constness(constness),
abi,
self.lower_generics(generics),
P(self.expr_block(body, ThinVec::new())))
body_id)
}
ItemKind::Mod(ref m) => hir::ItemMod(self.lower_mod(m)),
ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(self.lower_foreign_mod(nm)),
@ -897,7 +919,8 @@ impl<'a> LoweringContext<'a> {
hir::MethodTraitItem(this.lower_method_sig(sig),
body.as_ref().map(|x| {
let body = this.lower_block(x);
P(this.expr_block(body, ThinVec::new()))
let expr = this.expr_block(body, ThinVec::new());
this.record_expr(expr)
}))
}
TraitItemKind::Type(ref bounds, ref default) => {
@ -925,8 +948,9 @@ impl<'a> LoweringContext<'a> {
}
ImplItemKind::Method(ref sig, ref body) => {
let body = this.lower_block(body);
hir::ImplItemKind::Method(this.lower_method_sig(sig),
P(this.expr_block(body, ThinVec::new())))
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)
}
ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)),
ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
@ -1375,9 +1399,10 @@ impl<'a> LoweringContext<'a> {
}
ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => {
self.with_parent_def(e.id, |this| {
let expr = this.lower_expr(body);
hir::ExprClosure(this.lower_capture_clause(capture_clause),
this.lower_fn_decl(decl),
P(this.lower_expr(body)),
this.record_expr(expr),
fn_decl_span)
})
}

View file

@ -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: &'a Expr,
pub body: ast::ExprId,
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: &'a Expr,
body: ast::ExprId,
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: &'a Expr,
body: ast::ExprId,
id: NodeId,
span: Span,
attrs: &'a [Attribute],
}
impl<'a> ClosureParts<'a> {
fn new(d: &'a FnDecl, b: &'a Expr, id: NodeId, s: Span, attrs: &'a [Attribute]) -> Self {
fn new(d: &'a FnDecl, b: ast::ExprId, 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) -> &'a Expr {
self.handle(|i: ItemFnParts<'a>| &*i.body,
|_, _, _: &'a ast::MethodSig, _, body: &'a ast::Expr, _, _| body,
pub fn body(self) -> ast::ExprId {
self.handle(|i: ItemFnParts<'a>| i.body,
|_, _, _: &'a ast::MethodSig, _, body: ast::ExprId, _, _| body,
|c: ClosureParts<'a>| c.body)
}
@ -196,6 +196,18 @@ impl<'a> FnLikeNode<'a> {
|c: ClosureParts| c.id)
}
pub fn constness(self) -> ast::Constness {
match self.kind() {
FnKind::ItemFn(_, _, _, constness, ..) => {
constness
}
FnKind::Method(_, m, ..) => {
m.constness
}
_ => ast::Constness::NotConst
}
}
pub fn kind(self) -> FnKind<'a> {
let item = |p: ItemFnParts<'a>| -> FnKind<'a> {
FnKind::ItemFn(p.name, p.generics, p.unsafety, p.constness, p.abi, p.vis, p.attrs)
@ -215,7 +227,7 @@ impl<'a> FnLikeNode<'a> {
Name,
&'a ast::MethodSig,
Option<&'a ast::Visibility>,
&'a ast::Expr,
ast::ExprId,
Span,
&'a [Attribute])
-> A,
@ -223,13 +235,13 @@ impl<'a> FnLikeNode<'a> {
{
match self.node {
map::NodeItem(i) => match i.node {
ast::ItemFn(ref decl, unsafety, constness, abi, ref generics, ref block) =>
ast::ItemFn(ref decl, unsafety, constness, abi, ref generics, block) =>
item_fn(ItemFnParts {
id: i.id,
name: i.name,
decl: &decl,
unsafety: unsafety,
body: &block,
body: block,
generics: generics,
abi: abi,
vis: &i.vis,
@ -240,24 +252,24 @@ impl<'a> FnLikeNode<'a> {
_ => bug!("item FnLikeNode that is not fn-like"),
},
map::NodeTraitItem(ti) => match ti.node {
ast::MethodTraitItem(ref sig, Some(ref body)) => {
ast::MethodTraitItem(ref sig, Some(body)) => {
method(ti.id, ti.name, sig, None, body, ti.span, &ti.attrs)
}
_ => bug!("trait method FnLikeNode that is not fn-like"),
},
map::NodeImplItem(ii) => {
match ii.node {
ast::ImplItemKind::Method(ref sig, ref body) => {
ast::ImplItemKind::Method(ref sig, body) => {
method(ii.id, ii.name, sig, Some(&ii.vis), body, ii.span, &ii.attrs)
}
_ => {
bug!("impl method FnLikeNode that is not fn-like")
}
}
}
},
map::NodeExpr(e) => match e.node {
ast::ExprClosure(_, ref decl, ref block, _fn_decl_span) =>
closure(ClosureParts::new(&decl, &block, e.id, e.span, &e.attrs)),
ast::ExprClosure(_, ref decl, block, _fn_decl_span) =>
closure(ClosureParts::new(&decl, block, e.id, e.span, &e.attrs)),
_ => bug!("expr FnLikeNode that is not fn-like"),
},
_ => bug!("other FnLikeNode that is not fn-like"),

View file

@ -10,7 +10,7 @@
use super::*;
use hir::intravisit::Visitor;
use hir::intravisit::{Visitor, NestedVisitorMap};
use hir::def_id::DefId;
use middle::cstore::InlinedItem;
use std::iter::repeat;
@ -91,7 +91,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
/// deep walking so that we walk nested items in the context of
/// their outer items.
fn nested_visit_map(&mut self) -> Option<&map::Map<'ast>> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> {
panic!("visit_nested_xxx must be manually implemented in this visitor")
}
@ -106,6 +106,10 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
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_item(&mut self, i: &'ast Item) {
debug!("visit_item: {:?}", i);
@ -209,7 +213,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
}
fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl,
b: &'ast Expr, s: Span, id: NodeId) {
b: ExprId, s: Span, id: NodeId) {
assert_eq!(self.parent_node, id);
intravisit::walk_fn(self, fk, fd, b, s, id);
}

View file

@ -11,7 +11,7 @@
use hir::map::definitions::*;
use hir;
use hir::intravisit;
use hir::intravisit::{self, Visitor, NestedVisitorMap};
use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
use middle::cstore::InlinedItem;
@ -326,7 +326,18 @@ impl<'a> visit::Visitor for DefCollector<'a> {
}
// We walk the HIR rather than the AST when reading items from metadata.
impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> {
impl<'ast> Visitor<'ast> for DefCollector<'ast> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> {
// note however that we override `visit_body` below
NestedVisitorMap::None
}
fn visit_body(&mut self, id: hir::ExprId) {
if let Some(krate) = self.hir_crate {
self.visit_expr(krate.expr(id));
}
}
fn visit_item(&mut self, i: &'ast hir::Item) {
debug!("visit_item: {:?}", i);

View file

@ -18,7 +18,6 @@ pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData,
use dep_graph::{DepGraph, DepNode};
use middle::cstore::InlinedItem;
use middle::cstore::InlinedItem as II;
use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
use syntax::abi::Abi;
@ -61,6 +60,8 @@ pub enum Node<'ast> {
NodeLifetime(&'ast Lifetime),
NodeTyParam(&'ast TyParam),
NodeVisibility(&'ast Visibility),
NodeInlinedItem(&'ast InlinedItem),
}
/// Represents an entry and its parent NodeID.
@ -120,6 +121,8 @@ impl<'ast> MapEntry<'ast> {
NodeLifetime(n) => EntryLifetime(p, n),
NodeTyParam(n) => EntryTyParam(p, n),
NodeVisibility(n) => EntryVisibility(p, n),
NodeInlinedItem(n) => RootInlinedParent(n),
}
}
@ -168,6 +171,7 @@ impl<'ast> MapEntry<'ast> {
EntryLifetime(_, n) => NodeLifetime(n),
EntryTyParam(_, n) => NodeTyParam(n),
EntryVisibility(_, n) => NodeVisibility(n),
RootInlinedParent(n) => NodeInlinedItem(n),
_ => return None
})
}
@ -252,18 +256,36 @@ impl<'ast> Map<'ast> {
let map = self.map.borrow();
let mut id = id0;
if !self.is_inlined_node_id(id) {
let mut last_expr = None;
loop {
match map[id.as_usize()] {
EntryItem(_, item) => {
assert_eq!(id, item.id);
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
// (Note that trait items don't currently have
// their own dep node, so there's also just one
// HirBody node for all the items)
if self.is_body(last_id, item) {
return DepNode::HirBody(def_id);
}
}
return DepNode::Hir(def_id);
}
EntryImplItem(..) => {
EntryImplItem(_, 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
if self.is_impl_item_body(last_id, item) {
return DepNode::HirBody(def_id);
}
}
return DepNode::Hir(def_id);
}
@ -271,7 +293,6 @@ impl<'ast> Map<'ast> {
EntryTraitItem(p, _) |
EntryVariant(p, _) |
EntryField(p, _) |
EntryExpr(p, _) |
EntryStmt(p, _) |
EntryTy(p, _) |
EntryTraitRef(p, _) |
@ -284,6 +305,11 @@ impl<'ast> Map<'ast> {
EntryVisibility(p, _) =>
id = p,
EntryExpr(p, _) => {
last_expr = Some(id);
id = p;
}
RootCrate =>
return DepNode::Krate,
@ -328,12 +354,8 @@ impl<'ast> Map<'ast> {
EntryVisibility(p, _) =>
id = p,
RootInlinedParent(parent) => match *parent {
InlinedItem::Item(def_id, _) |
InlinedItem::TraitItem(def_id, _) |
InlinedItem::ImplItem(def_id, _) =>
return DepNode::MetaData(def_id)
},
RootInlinedParent(parent) =>
return DepNode::MetaData(parent.def_id),
RootCrate =>
bug!("node {} has crate ancestor but is inlined", id0),
@ -345,6 +367,29 @@ impl<'ast> Map<'ast> {
}
}
fn is_body(&self, node_id: NodeId, item: &Item) -> bool {
match item.node {
ItemFn(_, _, _, _, _, body) => body.node_id() == node_id,
// Since trait items currently don't get their own dep nodes,
// we check here whether node_id is the body of any of the items.
// If they get their own dep nodes, this can go away
ItemTrait(_, _, _, ref trait_items) => {
trait_items.iter().any(|trait_item| { match trait_item.node {
MethodTraitItem(_, Some(body)) => body.node_id() == node_id,
_ => false
}})
}
_ => false
}
}
fn is_impl_item_body(&self, node_id: NodeId, item: &ImplItem) -> bool {
match item.node {
ImplItemKind::Method(_, body) => body.node_id() == node_id,
_ => false
}
}
pub fn num_local_def_ids(&self) -> usize {
self.definitions.borrow().len()
}
@ -556,8 +601,7 @@ impl<'ast> Map<'ast> {
pub fn get_parent_did(&self, id: NodeId) -> DefId {
let parent = self.get_parent(id);
match self.find_entry(parent) {
Some(RootInlinedParent(&II::TraitItem(did, _))) |
Some(RootInlinedParent(&II::ImplItem(did, _))) => did,
Some(RootInlinedParent(ii)) => ii.def_id,
_ => self.local_def_id(parent)
}
}
@ -655,6 +699,10 @@ 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) {
@ -958,6 +1006,8 @@ impl<'a> NodePrinter for pprust::State<'a> {
// printing.
NodeLocal(_) => bug!("cannot print isolated Local"),
NodeStructCtor(_) => bug!("cannot print isolated StructCtor"),
NodeInlinedItem(_) => bug!("cannot print inlined item"),
}
}
}
@ -1071,6 +1121,9 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
Some(NodeVisibility(ref vis)) => {
format!("visibility {:?}{}", vis, id_str)
}
Some(NodeInlinedItem(_)) => {
format!("inlined item {}", id_str)
}
None => {
format!("unknown node{}", id_str)
}

View file

@ -33,6 +33,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 syntax_pos::{mk_sp, Span, ExpnId, DUMMY_SP};
use syntax::codemap::{self, respan, Spanned};
@ -428,6 +429,7 @@ pub struct Crate {
pub items: BTreeMap<NodeId, Item>,
pub impl_items: BTreeMap<ImplItemId, ImplItem>,
pub exprs: FnvHashMap<ExprId, Expr>,
}
impl Crate {
@ -458,6 +460,10 @@ impl Crate {
visitor.visit_impl_item(impl_item);
}
}
pub fn expr(&self, id: ExprId) -> &Expr {
&self.exprs[&id]
}
}
/// A macro definition, in this crate or imported from another.
@ -846,6 +852,15 @@ pub enum UnsafeSource {
UserProvided,
}
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct ExprId(NodeId);
impl ExprId {
pub fn node_id(self) -> NodeId {
self.0
}
}
/// An expression
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub struct Expr {
@ -855,6 +870,12 @@ 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))
@ -914,7 +935,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>, P<Expr>, Span),
ExprClosure(CaptureClause, P<FnDecl>, ExprId, Span),
/// A block (`{ ... }`)
ExprBlock(P<Block>),
@ -1068,7 +1089,7 @@ pub enum TraitItem_ {
/// must contain a value)
ConstTraitItem(P<Ty>, Option<P<Expr>>),
/// A method with an optional body
MethodTraitItem(MethodSig, Option<P<Expr>>),
MethodTraitItem(MethodSig, Option<ExprId>),
/// An associated type with (possibly empty) bounds and optional concrete
/// type
TypeTraitItem(TyParamBounds, Option<P<Ty>>),
@ -1101,7 +1122,7 @@ pub enum ImplItemKind {
/// of the expression
Const(P<Ty>, P<Expr>),
/// A method implementation with the given signature and body
Method(MethodSig, P<Expr>),
Method(MethodSig, ExprId),
/// An associated type
Type(P<Ty>),
}
@ -1546,7 +1567,7 @@ pub enum Item_ {
/// A `const` item
ItemConst(P<Ty>, P<Expr>),
/// A function declaration
ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Expr>),
ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, ExprId),
/// A module
ItemMod(Mod),
/// An external module

View file

@ -644,6 +644,15 @@ impl<'a> State<'a> {
}
}
pub fn print_expr_id(&mut self, expr_id: &hir::ExprId) -> io::Result<()> {
if let Some(krate) = self.krate {
let expr = &krate.exprs[expr_id];
self.print_expr(expr)
} else {
Ok(())
}
}
/// Pretty-print an item
pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> {
self.hardbreak_if_not_bol()?;
@ -729,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(&body)?;
self.print_expr_id(body)?;
}
hir::ItemMod(ref _mod) => {
self.head(&visibility_qualified(&item.vis, "mod"))?;
@ -1020,7 +1029,7 @@ impl<'a> State<'a> {
self.nbsp()?;
self.end()?; // need to close a box
self.end()?; // need to close a box
self.print_expr(body)?;
self.print_expr_id(body)?;
} else {
word(&mut self.s, ";")?;
}
@ -1065,7 +1074,7 @@ impl<'a> State<'a> {
self.nbsp()?;
self.end()?; // need to close a box
self.end()?; // need to close a box
self.print_expr(body)?;
self.print_expr_id(body)?;
}
hir::ImplItemKind::Type(ref ty) => {
self.print_associated_type(ii.name, None, Some(ty))?;
@ -1432,7 +1441,7 @@ impl<'a> State<'a> {
space(&mut self.s)?;
// this is a bare expression
self.print_expr(body)?;
self.print_expr_id(body)?;
self.end()?; // need to close a box
// a box will be closed by print_expr, but we didn't want an overall

View file

@ -719,10 +719,10 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
}
}
fn visit_ids<F>(&mut self, f: F)
where F: FnOnce(&mut IdVisitor)
fn visit_ids<'b, F: 'b>(&'b mut self, f: F)
where F: FnOnce(&mut IdVisitor<'b, 'a, 'tcx>)
{
let mut v = IdVisitor {
let mut v = IdVisitor::<'b, 'a, 'tcx> {
cx: self
};
f(&mut v);
@ -791,8 +791,8 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
/// Because lints are scoped lexically, we want to walk nested
/// items in the context of the outer item, so enable
/// deep-walking.
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
Some(&self.tcx.map)
fn nested_visit_map<'this>(&'this mut self) -> hir_visit::NestedVisitorMap<'this, 'tcx> {
hir_visit::NestedVisitorMap::All(&self.tcx.map)
}
fn visit_item(&mut self, it: &'tcx hir::Item) {
@ -835,9 +835,10 @@ 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: &'tcx hir::Expr, span: Span, id: ast::NodeId) {
body_id: hir::ExprId, span: Span, id: ast::NodeId) {
let body = self.tcx.map.expr(body_id);
run_lints!(self, check_fn, late_passes, fk, decl, body, span, id);
hir_visit::walk_fn(self, 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);
}
@ -1107,7 +1108,11 @@ struct IdVisitor<'a, 'b: 'a, 'tcx: 'a+'b> {
}
// Output any lints that were previously added to the session.
impl<'a, 'b, 'tcx, 'v> hir_visit::Visitor<'v> for IdVisitor<'a, 'b, 'tcx> {
impl<'a, 'b, 'tcx> hir_visit::Visitor<'tcx> for IdVisitor<'a, 'b, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> hir_visit::NestedVisitorMap<'this, 'tcx> {
hir_visit::NestedVisitorMap::OnlyBodies(&self.cx.tcx.map)
}
fn visit_id(&mut self, id: ast::NodeId) {
if let Some(lints) = self.cx.sess().lints.borrow_mut().remove(&id) {
debug!("LateContext::visit_id: id={:?} lints={:?}", id, lints);
@ -1117,12 +1122,12 @@ impl<'a, 'b, 'tcx, 'v> hir_visit::Visitor<'v> for IdVisitor<'a, 'b, 'tcx> {
}
}
fn visit_trait_item(&mut self, _ti: &hir::TraitItem) {
fn visit_trait_item(&mut self, _ti: &'tcx hir::TraitItem) {
// Do not recurse into trait or impl items automatically. These are
// processed separately by calling hir_visit::walk_trait_item()
}
fn visit_impl_item(&mut self, _ii: &hir::ImplItem) {
fn visit_impl_item(&mut self, _ii: &'tcx hir::ImplItem) {
// See visit_trait_item()
}
}

View file

@ -137,18 +137,96 @@ pub struct NativeLibrary {
/// part of the AST that we parse from a file, but it becomes part of the tree
/// that we trans.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum InlinedItem {
Item(DefId /* def-id in source crate */, P<hir::Item>),
TraitItem(DefId /* impl id */, P<hir::TraitItem>),
ImplItem(DefId /* impl id */, P<hir::ImplItem>)
pub struct InlinedItem {
pub def_id: DefId,
pub body: P<hir::Expr>,
pub const_fn_args: Vec<Option<DefId>>,
}
/// A borrowed version of `hir::InlinedItem`.
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, Hash, Debug)]
pub enum InlinedItemRef<'a> {
Item(DefId, &'a hir::Item),
TraitItem(DefId, &'a hir::TraitItem),
ImplItem(DefId, &'a hir::ImplItem)
/// A borrowed version of `hir::InlinedItem`. This is what's encoded when saving
/// a crate; it then gets read as an InlinedItem.
#[derive(Clone, PartialEq, Eq, RustcEncodable, Hash, Debug)]
pub struct InlinedItemRef<'a> {
pub def_id: DefId,
pub body: &'a hir::Expr,
pub const_fn_args: Vec<Option<DefId>>,
}
fn get_fn_args(decl: &hir::FnDecl) -> Vec<Option<DefId>> {
decl.inputs.iter().map(|arg| match arg.pat.node {
hir::PatKind::Binding(_, def_id, _, _) => Some(def_id),
_ => None
}).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 {
hir::ItemFn(ref decl, _, _, _, _, body_id) =>
(tcx.map.expr(body_id), get_fn_args(decl)),
hir::ItemConst(_, ref body) => (&**body, Vec::new()),
_ => bug!("InlinedItemRef::from_item wrong kind")
};
InlinedItemRef {
def_id: def_id,
body: body,
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::ConstTraitItem(_, Some(ref body)) =>
(&**body, Vec::new()),
hir::ConstTraitItem(_, None) => {
bug!("InlinedItemRef::from_trait_item called for const without body")
},
_ => bug!("InlinedItemRef::from_trait_item wrong kind")
};
InlinedItemRef {
def_id: def_id,
body: body,
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 {
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()),
_ => bug!("InlinedItemRef::from_impl_item wrong kind")
};
InlinedItemRef {
def_id: def_id,
body: body,
const_fn_args: args
}
}
pub fn visit<V>(&self, visitor: &mut V)
where V: Visitor<'a>
{
visitor.visit_expr(&self.body);
}
}
impl InlinedItem {
pub fn visit<'ast,V>(&'ast self, visitor: &mut V)
where V: Visitor<'ast>
{
visitor.visit_expr(&self.body);
}
}
pub enum LoadedMacro {
@ -292,18 +370,6 @@ pub trait CrateStore<'tcx> {
fn metadata_encoding_version(&self) -> &[u8];
}
impl InlinedItem {
pub fn visit<'ast,V>(&'ast self, visitor: &mut V)
where V: Visitor<'ast>
{
match *self {
InlinedItem::Item(_, ref i) => visitor.visit_item(&i),
InlinedItem::TraitItem(_, ref ti) => visitor.visit_trait_item(ti),
InlinedItem::ImplItem(_, ref ii) => visitor.visit_impl_item(ii),
}
}
}
// FIXME: find a better place for this?
pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
let mut err_count = 0;

View file

@ -193,6 +193,10 @@ fn build_nodeid_to_index(decl: Option<&hir::FnDecl>,
let mut formals = Formals { entry: entry, index: index };
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")
}
fn visit_pat(&mut self, p: &hir::Pat) {
self.index.entry(p.id).or_insert(vec![]).push(self.entry);
intravisit::walk_pat(self, p)

View file

@ -15,7 +15,7 @@
use dep_graph::DepNode;
use hir::map as ast_map;
use hir::{self, PatKind};
use hir::intravisit::{self, Visitor};
use hir::intravisit::{self, Visitor, NestedVisitorMap};
use hir::itemlikevisit::ItemLikeVisitor;
use middle::privacy;
@ -175,7 +175,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
}
}
fn visit_node(&mut self, node: &ast_map::Node) {
fn visit_node(&mut self, node: &ast_map::Node<'tcx>) {
let had_extern_repr = self.struct_has_extern_repr;
self.struct_has_extern_repr = false;
let had_inherited_pub_visibility = self.inherited_pub_visibility;
@ -220,9 +220,12 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
}
}
impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.tcx.map)
}
fn visit_variant_data(&mut self, def: &hir::VariantData, _: ast::Name,
fn visit_variant_data(&mut self, def: &'tcx hir::VariantData, _: ast::Name,
_: &hir::Generics, _: ast::NodeId, _: syntax_pos::Span) {
let has_extern_repr = self.struct_has_extern_repr;
let inherited_pub_visibility = self.inherited_pub_visibility;
@ -234,7 +237,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
intravisit::walk_struct_def(self, def);
}
fn visit_expr(&mut self, expr: &hir::Expr) {
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
match expr.node {
hir::ExprPath(ref qpath @ hir::QPath::TypeRelative(..)) => {
let def = self.tcx.tables().qpath_def(qpath, expr.id);
@ -255,7 +258,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
intravisit::walk_expr(self, expr);
}
fn visit_arm(&mut self, arm: &hir::Arm) {
fn visit_arm(&mut self, arm: &'tcx hir::Arm) {
if arm.pats.len() == 1 {
let variants = arm.pats[0].necessary_variants();
@ -271,7 +274,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
}
}
fn visit_pat(&mut self, pat: &hir::Pat) {
fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
match pat.node {
PatKind::Struct(hir::QPath::Resolved(_, ref path), ref fields, _) => {
self.handle_field_pattern_match(pat, path.def, fields);
@ -288,7 +291,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
self.ignore_non_const_paths = false;
}
fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) {
fn visit_path(&mut self, path: &'tcx hir::Path, id: ast::NodeId) {
self.handle_definition(id, path.def);
intravisit::walk_path(self, path);
}
@ -507,8 +510,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
/// on inner functions when the outer function is already getting
/// an error. We could do this also by checking the parents, but
/// this is how the code is setup and it seems harmless enough.
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
Some(&self.tcx.map)
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::All(&self.tcx.map)
}
fn visit_item(&mut self, item: &'tcx hir::Item) {
@ -562,12 +565,12 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
}
intravisit::walk_expr(self, expr)
}
hir::ImplItemKind::Method(_, ref body) => {
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");
}
intravisit::walk_expr(self, body)
self.visit_body(body_id)
}
hir::ImplItemKind::Type(..) => {}
}
@ -576,10 +579,12 @@ 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::ConstTraitItem(_, Some(ref body))|
hir::MethodTraitItem(_, Some(ref body)) => {
hir::ConstTraitItem(_, Some(ref body)) => {
intravisit::walk_expr(self, body)
}
hir::MethodTraitItem(_, Some(body_id)) => {
self.visit_body(body_id)
}
hir::ConstTraitItem(_, None) |
hir::MethodTraitItem(_, None) |
hir::TypeTraitItem(..) => {}

View file

@ -21,7 +21,7 @@ use syntax::ast;
use syntax_pos::Span;
use hir::{self, PatKind};
use hir::def::Def;
use hir::intravisit::{self, FnKind, Visitor};
use hir::intravisit::{self, FnKind, Visitor, NestedVisitorMap};
#[derive(Copy, Clone)]
struct UnsafeContext {
@ -92,9 +92,13 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
}
}
impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
fn visit_fn(&mut self, fn_kind: FnKind<'v>, fn_decl: &'v hir::FnDecl,
block: &'v hir::Expr, span: Span, id: ast::NodeId) {
impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.tcx.map)
}
fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, fn_decl: &'tcx hir::FnDecl,
body_id: hir::ExprId, span: Span, id: ast::NodeId) {
let (is_item_fn, is_unsafe_fn) = match fn_kind {
FnKind::ItemFn(_, _, unsafety, ..) =>
@ -111,12 +115,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
self.unsafe_context = UnsafeContext::new(SafeContext)
}
intravisit::walk_fn(self, fn_kind, fn_decl, block, span, id);
intravisit::walk_fn(self, fn_kind, fn_decl, body_id, span, id);
self.unsafe_context = old_unsafe_context
}
fn visit_block(&mut self, block: &hir::Block) {
fn visit_block(&mut self, block: &'tcx hir::Block) {
let old_unsafe_context = self.unsafe_context;
match block.rules {
hir::UnsafeBlock(source) => {
@ -155,7 +159,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
self.unsafe_context = old_unsafe_context
}
fn visit_expr(&mut self, expr: &hir::Expr) {
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
match expr.node {
hir::ExprMethodCall(..) => {
let method_call = MethodCall::expr(expr.id);
@ -212,7 +216,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
intravisit::walk_expr(self, expr);
}
fn visit_pat(&mut self, pat: &hir::Pat) {
fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
if let PatKind::Struct(_, ref fields, _) = pat.node {
if let ty::TyAdt(adt, ..) = self.tcx.tables().pat_ty(pat).sty {
if adt.is_union() {

View file

@ -47,6 +47,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
find_item(item, self, at_root);
}
fn visit_impl_item(&mut self, _impl_item: &'tcx ImplItem) {
// entry fn is never an impl item
}

View file

@ -19,7 +19,7 @@ use ty::layout::{LayoutError, Pointer, SizeSkeleton};
use syntax::abi::Abi::RustIntrinsic;
use syntax::ast;
use syntax_pos::Span;
use hir::intravisit::{self, Visitor, FnKind};
use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
use hir;
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
@ -34,7 +34,7 @@ struct ItemVisitor<'a, 'tcx: 'a> {
}
impl<'a, 'tcx> ItemVisitor<'a, 'tcx> {
fn visit_const(&mut self, item_id: ast::NodeId, expr: &hir::Expr) {
fn visit_const(&mut self, item_id: ast::NodeId, expr: &'tcx hir::Expr) {
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 {
@ -116,9 +116,13 @@ impl<'a, 'gcx, 'tcx> ExprVisitor<'a, 'gcx, 'tcx> {
}
}
impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for ItemVisitor<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.tcx.map)
}
// const, static and N in [T; N].
fn visit_expr(&mut self, expr: &hir::Expr) {
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
self.tcx.infer_ctxt(None, None, Reveal::All).enter(|infcx| {
let mut visitor = ExprVisitor {
infcx: &infcx
@ -127,7 +131,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> {
});
}
fn visit_trait_item(&mut self, item: &hir::TraitItem) {
fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) {
if let hir::ConstTraitItem(_, Some(ref expr)) = item.node {
self.visit_const(item.id, expr);
} else {
@ -135,7 +139,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> {
}
}
fn visit_impl_item(&mut self, item: &hir::ImplItem) {
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);
} else {
@ -143,8 +147,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> {
}
}
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
b: &'v hir::Expr, s: Span, id: ast::NodeId) {
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
b: hir::ExprId, s: Span, id: ast::NodeId) {
if let FnKind::Closure(..) = fk {
span_bug!(s, "intrinsicck: closure outside of function")
}
@ -158,8 +162,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> {
}
}
impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for ExprVisitor<'a, 'gcx, 'tcx> {
fn visit_expr(&mut self, expr: &hir::Expr) {
impl<'a, 'gcx, 'tcx> Visitor<'gcx> for ExprVisitor<'a, 'gcx, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
NestedVisitorMap::OnlyBodies(&self.infcx.tcx.map)
}
fn visit_expr(&mut self, expr: &'gcx hir::Expr) {
let def = if let hir::ExprPath(ref qpath) = expr.node {
self.infcx.tcx.tables().qpath_def(qpath, expr.id)
} else {

View file

@ -128,7 +128,7 @@ use syntax_pos::Span;
use hir::Expr;
use hir;
use hir::print::{expr_to_string, block_to_string};
use hir::intravisit::{self, Visitor, FnKind};
use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
/// For use with `propagate_through_loop`.
enum LoopKind<'a> {
@ -182,14 +182,18 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt) -> String {
}
}
impl<'a, 'tcx, 'v> Visitor<'v> for IrMaps<'a, 'tcx> {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
b: &'v hir::Expr, s: Span, id: NodeId) {
impl<'a, 'tcx> Visitor<'tcx> for IrMaps<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.tcx.map)
}
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
b: hir::ExprId, s: Span, id: NodeId) {
visit_fn(self, fk, fd, b, s, id);
}
fn visit_local(&mut self, l: &hir::Local) { visit_local(self, l); }
fn visit_expr(&mut self, ex: &Expr) { visit_expr(self, ex); }
fn visit_arm(&mut self, a: &hir::Arm) { visit_arm(self, a); }
fn visit_local(&mut self, l: &'tcx hir::Local) { visit_local(self, l); }
fn visit_expr(&mut self, ex: &'tcx Expr) { visit_expr(self, ex); }
fn visit_arm(&mut self, a: &'tcx hir::Arm) { visit_arm(self, a); }
}
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
@ -348,28 +352,32 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
}
}
impl<'a, 'tcx, 'v> Visitor<'v> for Liveness<'a, 'tcx> {
fn visit_fn(&mut self, _: FnKind<'v>, _: &'v hir::FnDecl,
_: &'v hir::Expr, _: Span, _: NodeId) {
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)
}
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: &hir::Local) {
fn visit_local(&mut self, l: &'tcx hir::Local) {
check_local(self, l);
}
fn visit_expr(&mut self, ex: &Expr) {
fn visit_expr(&mut self, ex: &'tcx Expr) {
check_expr(self, ex);
}
fn visit_arm(&mut self, a: &hir::Arm) {
fn visit_arm(&mut self, a: &'tcx hir::Arm) {
check_arm(self, a);
}
}
fn visit_fn(ir: &mut IrMaps,
fk: FnKind,
decl: &hir::FnDecl,
body: &hir::Expr,
sp: Span,
id: ast::NodeId) {
fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
fk: FnKind<'tcx>,
decl: &'tcx hir::FnDecl,
body_id: hir::ExprId,
sp: Span,
id: ast::NodeId) {
debug!("visit_fn");
// swap in a new set of IR maps for this function body:
@ -387,7 +395,7 @@ fn visit_fn(ir: &mut IrMaps,
// gather up the various local variables, significant expressions,
// and so forth:
intravisit::walk_fn(&mut fn_maps, fk, decl, body, sp, id);
intravisit::walk_fn(&mut fn_maps, fk, decl, body_id, sp, id);
// Special nodes and variables:
// - exit_ln represents the end of the fn, either by return or panic
@ -400,6 +408,8 @@ fn visit_fn(ir: &mut IrMaps,
clean_exit_var: fn_maps.add_variable(CleanExit)
};
let body = ir.tcx.map.expr(body_id);
// compute liveness
let mut lsets = Liveness::new(&mut fn_maps, specials);
let entry_ln = lsets.compute(body);
@ -410,7 +420,7 @@ fn visit_fn(ir: &mut IrMaps,
lsets.warn_about_unused_args(decl, entry_ln);
}
fn visit_local(ir: &mut IrMaps, local: &hir::Local) {
fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
local.pat.each_binding(|_, p_id, sp, path1| {
debug!("adding local variable {}", p_id);
let name = path1.node;
@ -423,7 +433,7 @@ fn visit_local(ir: &mut IrMaps, local: &hir::Local) {
intravisit::walk_local(ir, local);
}
fn visit_arm(ir: &mut IrMaps, arm: &hir::Arm) {
fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
for pat in &arm.pats {
pat.each_binding(|bm, p_id, sp, path1| {
debug!("adding local variable {} from match with bm {:?}",
@ -439,7 +449,7 @@ fn visit_arm(ir: &mut IrMaps, arm: &hir::Arm) {
intravisit::walk_arm(ir, arm);
}
fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
match expr.node {
// live nodes required for uses or definitions of variables:
hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
@ -923,7 +933,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_expr(&e, succ)
}
hir::ExprClosure(.., ref blk, _) => {
hir::ExprClosure(.., blk_id, _) => {
debug!("{} is an ExprClosure",
expr_to_string(expr));
@ -932,7 +942,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, 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.
@ -1354,7 +1364,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
// _______________________________________________________________________
// Checking for error conditions
fn check_local(this: &mut Liveness, local: &hir::Local) {
fn check_local<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, local: &'tcx hir::Local) {
match local.init {
Some(_) => {
this.warn_about_unused_or_dead_vars_in_pat(&local.pat);
@ -1369,7 +1379,7 @@ fn check_local(this: &mut Liveness, local: &hir::Local) {
intravisit::walk_local(this, local);
}
fn check_arm(this: &mut Liveness, arm: &hir::Arm) {
fn check_arm<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, arm: &'tcx hir::Arm) {
// only consider the first pattern; any later patterns must have
// the same bindings, and we also consider the first pattern to be
// the "authoritative" set of ids
@ -1379,7 +1389,7 @@ fn check_arm(this: &mut Liveness, arm: &hir::Arm) {
intravisit::walk_arm(this, arm);
}
fn check_expr(this: &mut Liveness, expr: &Expr) {
fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) {
match expr.node {
hir::ExprAssign(ref l, _) => {
this.check_lvalue(&l);
@ -1469,7 +1479,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
}
}
fn check_lvalue(&mut self, expr: &Expr) {
fn check_lvalue(&mut self, expr: &'tcx Expr) {
match expr.node {
hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
if let Def::Local(def_id) = path.def {

View file

@ -705,7 +705,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
};
match fn_expr.node {
hir::ExprClosure(.., ref body, _) => body.id,
hir::ExprClosure(.., body_id, _) => body_id.node_id(),
_ => bug!()
}
};

View file

@ -28,7 +28,7 @@ use syntax::abi::Abi;
use syntax::ast;
use syntax::attr;
use hir;
use hir::intravisit::Visitor;
use hir::intravisit::{Visitor, NestedVisitorMap};
use hir::itemlikevisit::ItemLikeVisitor;
use hir::intravisit;
@ -88,8 +88,12 @@ struct ReachableContext<'a, 'tcx: 'a> {
any_library: bool,
}
impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
fn visit_expr(&mut self, expr: &hir::Expr) {
impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.tcx.map)
}
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
let def = match expr.node {
hir::ExprPath(ref qpath) => {
Some(self.tcx.tables().qpath_def(qpath, expr.id))
@ -216,7 +220,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
}
}
fn propagate_node(&mut self, node: &ast_map::Node,
fn propagate_node(&mut self, node: &ast_map::Node<'tcx>,
search_item: ast::NodeId) {
if !self.any_library {
// If we are building an executable, only explicitly extern
@ -244,9 +248,9 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
match *node {
ast_map::NodeItem(item) => {
match item.node {
hir::ItemFn(.., ref body) => {
hir::ItemFn(.., body) => {
if item_might_be_inlined(&item) {
self.visit_expr(body);
self.visit_body(body);
}
}
@ -274,10 +278,12 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
hir::MethodTraitItem(_, None) => {
// Keep going, nothing to get exported
}
hir::ConstTraitItem(_, Some(ref body)) |
hir::MethodTraitItem(_, Some(ref body)) => {
hir::ConstTraitItem(_, Some(ref body)) => {
self.visit_expr(body);
}
hir::MethodTraitItem(_, Some(body_id)) => {
self.visit_body(body_id);
}
hir::TypeTraitItem(..) => {}
}
}
@ -286,10 +292,10 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
hir::ImplItemKind::Const(_, ref expr) => {
self.visit_expr(&expr);
}
hir::ImplItemKind::Method(ref sig, ref 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_expr(body)
self.visit_body(body)
}
}
hir::ImplItemKind::Type(_) => {}

View file

@ -31,7 +31,7 @@ use syntax::ast::{self, NodeId};
use syntax_pos::Span;
use hir;
use hir::intravisit::{self, Visitor, FnKind};
use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
use hir::{Block, Item, FnDecl, Arm, Pat, PatKind, Stmt, Expr, Local};
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable,
@ -302,7 +302,7 @@ pub struct Context {
parent: CodeExtent
}
struct RegionResolutionVisitor<'a> {
struct RegionResolutionVisitor<'ast: 'a, 'a> {
sess: &'a Session,
// Generated maps:
@ -310,6 +310,8 @@ struct RegionResolutionVisitor<'a> {
cx: Context,
map: &'a ast_map::Map<'ast>,
/// `terminating_scopes` is a set containing the ids of each
/// statement, or conditional/repeating expression. These scopes
/// are calling "terminating scopes" because, when attempting to
@ -660,7 +662,7 @@ fn record_var_lifetime(visitor: &mut RegionResolutionVisitor,
}
}
fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &hir::Block) {
fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, blk: &'tcx hir::Block) {
debug!("resolve_block(blk.id={:?})", blk.id);
let prev_cx = visitor.cx;
@ -731,7 +733,7 @@ fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &hir::Block) {
visitor.cx = prev_cx;
}
fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &hir::Arm) {
fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, arm: &'tcx hir::Arm) {
visitor.terminating_scopes.insert(arm.body.id);
if let Some(ref expr) = arm.guard {
@ -741,7 +743,7 @@ fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &hir::Arm) {
intravisit::walk_arm(visitor, arm);
}
fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &hir::Pat) {
fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, pat: &'tcx hir::Pat) {
visitor.new_node_extent(pat.id);
// If this is a binding then record the lifetime of that binding.
@ -752,7 +754,7 @@ fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &hir::Pat) {
intravisit::walk_pat(visitor, pat);
}
fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &hir::Stmt) {
fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, stmt: &'tcx hir::Stmt) {
let stmt_id = stmt.node.id();
debug!("resolve_stmt(stmt.id={:?})", stmt_id);
@ -770,7 +772,7 @@ fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &hir::Stmt) {
visitor.cx.parent = prev_parent;
}
fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &hir::Expr) {
fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, expr: &'tcx hir::Expr) {
debug!("resolve_expr(expr.id={:?})", expr.id);
let expr_extent = visitor.new_node_extent_with_dtor(expr.id);
@ -848,7 +850,8 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &hir::Expr) {
visitor.cx = prev_cx;
}
fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) {
fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
local: &'tcx hir::Local) {
debug!("resolve_local(local.id={:?},local.init={:?})",
local.id,local.init.is_some());
@ -1063,7 +1066,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) {
}
}
fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &hir::Item) {
fn resolve_item<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, item: &'tcx hir::Item) {
// Items create a new outer block scope as far as we're concerned.
let prev_cx = visitor.cx;
let prev_ts = mem::replace(&mut visitor.terminating_scopes, NodeSet());
@ -1078,38 +1081,38 @@ fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &hir::Item) {
visitor.terminating_scopes = prev_ts;
}
fn resolve_fn(visitor: &mut RegionResolutionVisitor,
kind: FnKind,
decl: &hir::FnDecl,
body: &hir::Expr,
sp: Span,
id: ast::NodeId) {
fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
kind: FnKind<'tcx>,
decl: &'tcx hir::FnDecl,
body_id: hir::ExprId,
sp: Span,
id: ast::NodeId) {
debug!("region::resolve_fn(id={:?}, \
span={:?}, \
body.id={:?}, \
cx.parent={:?})",
id,
visitor.sess.codemap().span_to_string(sp),
body.id,
body_id,
visitor.cx.parent);
visitor.cx.parent = visitor.new_code_extent(
CodeExtentData::CallSiteScope { fn_id: id, body_id: body.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 });
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, 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);
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),
root_id: Some(body_id.node_id()),
parent: ROOT_CODE_EXTENT,
var_parent: fn_decl_scope,
};
@ -1119,18 +1122,18 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
// The body of the every fn is a root scope.
visitor.cx = Context {
root_id: Some(body.id),
root_id: Some(body_id.node_id()),
parent: fn_decl_scope,
var_parent: fn_decl_scope
};
visitor.visit_expr(body);
visitor.visit_body(body_id);
// Restore context we had at the start.
visitor.cx = outer_cx;
visitor.terminating_scopes = outer_ts;
}
impl<'a> RegionResolutionVisitor<'a> {
impl<'ast, 'a> RegionResolutionVisitor<'ast, 'a> {
/// Records the current parent (if any) as the parent of `child_scope`.
fn new_code_extent(&mut self, child_scope: CodeExtentData) -> CodeExtent {
self.region_maps.intern_code_extent(child_scope, self.cx.parent)
@ -1166,42 +1169,46 @@ impl<'a> RegionResolutionVisitor<'a> {
}
}
impl<'a, 'v> Visitor<'v> for RegionResolutionVisitor<'a> {
fn visit_block(&mut self, b: &Block) {
impl<'ast, 'a> Visitor<'ast> for RegionResolutionVisitor<'ast, 'a> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> {
NestedVisitorMap::OnlyBodies(&self.map)
}
fn visit_block(&mut self, b: &'ast Block) {
resolve_block(self, b);
}
fn visit_item(&mut self, i: &Item) {
fn visit_item(&mut self, i: &'ast Item) {
resolve_item(self, i);
}
fn visit_impl_item(&mut self, ii: &hir::ImplItem) {
fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) {
intravisit::walk_impl_item(self, ii);
self.create_item_scope_if_needed(ii.id);
}
fn visit_trait_item(&mut self, ti: &hir::TraitItem) {
fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) {
intravisit::walk_trait_item(self, ti);
self.create_item_scope_if_needed(ti.id);
}
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl,
b: &'v Expr, s: Span, n: NodeId) {
fn visit_fn(&mut self, fk: FnKind<'ast>, fd: &'ast FnDecl,
b: hir::ExprId, s: Span, n: NodeId) {
resolve_fn(self, fk, fd, b, s, n);
}
fn visit_arm(&mut self, a: &Arm) {
fn visit_arm(&mut self, a: &'ast Arm) {
resolve_arm(self, a);
}
fn visit_pat(&mut self, p: &Pat) {
fn visit_pat(&mut self, p: &'ast Pat) {
resolve_pat(self, p);
}
fn visit_stmt(&mut self, s: &Stmt) {
fn visit_stmt(&mut self, s: &'ast Stmt) {
resolve_stmt(self, s);
}
fn visit_expr(&mut self, ex: &Expr) {
fn visit_expr(&mut self, ex: &'ast Expr) {
resolve_expr(self, ex);
}
fn visit_local(&mut self, l: &Local) {
fn visit_local(&mut self, l: &'ast Local) {
resolve_local(self, l);
}
}
@ -1228,6 +1235,7 @@ pub fn resolve_crate(sess: &Session, map: &ast_map::Map) -> RegionMaps {
let mut visitor = RegionResolutionVisitor {
sess: sess,
region_maps: &maps,
map: map,
cx: Context {
root_id: None,
parent: ROOT_CODE_EXTENT,

View file

@ -34,7 +34,7 @@ use util::nodemap::NodeMap;
use rustc_data_structures::fx::FxHashSet;
use hir;
use hir::print::lifetime_to_string;
use hir::intravisit::{self, Visitor, FnKind};
use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
pub enum DefRegion {
@ -132,8 +132,8 @@ pub fn krate(sess: &Session,
impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
// Override the nested functions -- lifetimes follow lexical scope,
// so it's convenient to walk the tree in lexical order.
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
Some(&self.hir_map)
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::All(&self.hir_map)
}
fn visit_item(&mut self, item: &'tcx hir::Item) {
@ -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: &'tcx hir::Expr, s: Span, fn_id: ast::NodeId) {
b: hir::ExprId, 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::Expr) {
fn extract_labels(ctxt: &mut LifetimeContext, b: hir::ExprId) {
struct GatherLabels<'a> {
sess: &'a Session,
scope: Scope<'a>,
@ -419,10 +419,14 @@ fn extract_labels(ctxt: &mut LifetimeContext, b: &hir::Expr) {
scope: ctxt.scope,
labels_in_fn: &mut ctxt.labels_in_fn,
};
gather.visit_expr(b);
gather.visit_expr(ctxt.hir_map.expr(b));
return;
impl<'v, 'a> Visitor<'v> for GatherLabels<'a> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
NestedVisitorMap::None
}
fn visit_expr(&mut self, ex: &'v hir::Expr) {
// do not recurse into closures defined in the block
// since they are treated as separate fns from the POV of
@ -497,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: &'tcx hir::Expr,
fb: hir::ExprId,
_span: Span,
fn_id: ast::NodeId) {
match fk {
@ -518,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.id, s: self.scope },
|_old_scope, this| this.visit_expr(fb))
self.with(FnScope { fn_id: fn_id, body_id: fb.node_id(), s: self.scope },
|_old_scope, this| this.visit_body(fb))
}
// FIXME(#37666) this works around a limitation in the region inferencer
@ -938,6 +942,10 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap,
}
impl<'v> Visitor<'v> for ConstrainedCollector {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
NestedVisitorMap::None
}
fn visit_ty(&mut self, ty: &'v hir::Ty) {
match ty.node {
hir::TyPath(hir::QPath::Resolved(Some(_), _)) |
@ -975,6 +983,10 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap,
}
impl<'v> Visitor<'v> for AllCollector {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
NestedVisitorMap::None
}
fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
self.regions.insert(lifetime_ref.name);
}

View file

@ -30,8 +30,7 @@ use util::nodemap::{DefIdMap, FxHashSet, FxHashMap};
use hir;
use hir::{Item, Generics, StructField, Variant};
use hir::intravisit::{self, Visitor};
use hir::itemlikevisit::DeepVisitor;
use hir::intravisit::{self, Visitor, NestedVisitorMap};
use std::mem::replace;
use std::cmp::Ordering;
@ -234,8 +233,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
/// Because stability levels are scoped lexically, we want to walk
/// nested items in the context of the outer item, so enable
/// deep-walking.
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
Some(&self.tcx.map)
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::All(&self.tcx.map)
}
fn visit_item(&mut self, i: &'tcx Item) {
@ -326,8 +325,12 @@ impl<'a, 'tcx: 'a> MissingStabilityAnnotations<'a, 'tcx> {
}
}
impl<'a, 'tcx, 'v> Visitor<'v> for MissingStabilityAnnotations<'a, 'tcx> {
fn visit_item(&mut self, i: &Item) {
impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.tcx.map)
}
fn visit_item(&mut self, i: &'tcx Item) {
match i.node {
// Inherent impls and foreign modules serve only as containers for other items,
// they don't have their own stability. They still can be annotated as unstable
@ -341,12 +344,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MissingStabilityAnnotations<'a, 'tcx> {
intravisit::walk_item(self, i)
}
fn visit_trait_item(&mut self, ti: &hir::TraitItem) {
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
self.check_missing_stability(ti.id, ti.span);
intravisit::walk_trait_item(self, ti);
}
fn visit_impl_item(&mut self, ii: &hir::ImplItem) {
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
let impl_def_id = self.tcx.map.local_def_id(self.tcx.map.get_parent(ii.id));
if self.tcx.impl_trait_ref(impl_def_id).is_none() {
self.check_missing_stability(ii.id, ii.span);
@ -354,22 +357,22 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MissingStabilityAnnotations<'a, 'tcx> {
intravisit::walk_impl_item(self, ii);
}
fn visit_variant(&mut self, var: &Variant, g: &Generics, item_id: NodeId) {
fn visit_variant(&mut self, var: &'tcx Variant, g: &'tcx Generics, item_id: NodeId) {
self.check_missing_stability(var.node.data.id(), var.span);
intravisit::walk_variant(self, var, g, item_id);
}
fn visit_struct_field(&mut self, s: &StructField) {
fn visit_struct_field(&mut self, s: &'tcx StructField) {
self.check_missing_stability(s.id, s.span);
intravisit::walk_struct_field(self, s);
}
fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem) {
self.check_missing_stability(i.id, i.span);
intravisit::walk_foreign_item(self, i);
}
fn visit_macro_def(&mut self, md: &hir::MacroDef) {
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) {
if md.imported_from.is_none() {
self.check_missing_stability(md.id, md.span);
}
@ -425,8 +428,7 @@ impl<'a, 'tcx> Index<'tcx> {
/// features and possibly prints errors.
pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let mut checker = Checker { tcx: tcx };
tcx.visit_all_item_likes_in_krate(DepNode::StabilityCheck,
&mut DeepVisitor::new(&mut checker));
tcx.visit_all_item_likes_in_krate(DepNode::StabilityCheck, &mut checker.as_deep_visitor());
}
struct Checker<'a, 'tcx: 'a> {
@ -534,6 +536,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
/// Because stability levels are scoped lexically, we want to walk
/// nested items in the context of the outer item, so enable
/// deep-walking.
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.tcx.map)
}
fn visit_item(&mut self, item: &'tcx hir::Item) {
match item.node {
hir::ItemExternCrate(_) => {
@ -641,7 +650,7 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
};
missing.check_missing_stability(ast::CRATE_NODE_ID, krate.span);
intravisit::walk_crate(&mut missing, krate);
krate.visit_all_item_likes(&mut DeepVisitor::new(&mut missing));
krate.visit_all_item_likes(&mut missing.as_deep_visitor());
}
let ref declared_lib_features = sess.features.borrow().declared_lib_features;

View file

@ -18,7 +18,7 @@ use rustc_back::PanicStrategy;
use syntax::ast;
use syntax::symbol::Symbol;
use syntax_pos::Span;
use hir::intravisit::Visitor;
use hir::intravisit::{Visitor, NestedVisitorMap};
use hir::intravisit;
use hir;
@ -125,6 +125,10 @@ impl<'a> Context<'a> {
}
impl<'a, 'v> Visitor<'v> for Context<'a> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
NestedVisitorMap::None
}
fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
if let Some(lang_item) = lang_items::extract(&i.attrs) {
self.register(&lang_item.as_str(), i.span);

View file

@ -1208,7 +1208,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.id))
tcx.region_maps.call_site_extent(id, body.node_id()))
}
}
}
@ -1227,9 +1227,9 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
// Use call-site for extent (unless this is a
// trait method with no default; then fallback
// to the method id).
let extent = if let Some(ref body) = *body {
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)
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)
@ -1243,14 +1243,14 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
}
Some(ast_map::NodeItem(item)) => {
match item.node {
hir::ItemFn(.., ref body) => {
hir::ItemFn(.., body_id) => {
// We assume this is a function.
let fn_def_id = tcx.map.local_def_id(id);
tcx.construct_parameter_environment(
item.span,
fn_def_id,
tcx.region_maps.call_site_extent(id, body.id))
tcx.region_maps.call_site_extent(id, body_id.node_id()))
}
hir::ItemEnum(..) |
hir::ItemStruct(..) |
@ -1280,13 +1280,13 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
}
Some(ast_map::NodeExpr(expr)) => {
// This is a convenience to allow closures to work.
if let hir::ExprClosure(.., ref body, _) = expr.node {
if let hir::ExprClosure(.., body, _) = expr.node {
let def_id = tcx.map.local_def_id(id);
let base_def_id = tcx.closure_base_def_id(def_id);
tcx.construct_parameter_environment(
expr.span,
base_def_id,
tcx.region_maps.call_site_extent(id, body.id))
tcx.region_maps.call_site_extent(id, body.node_id()))
} else {
tcx.empty_parameter_environment()
}

View file

@ -30,7 +30,7 @@ use syntax_pos::Span;
use rustc::hir;
use rustc::hir::Expr;
use rustc::hir::intravisit;
use rustc::hir::intravisit::Visitor;
use rustc::hir::intravisit::{Visitor, NestedVisitorMap};
use self::restrictions::RestrictionResult;
@ -520,8 +520,12 @@ struct StaticInitializerCtxt<'a, 'tcx: 'a> {
item_id: ast::NodeId
}
impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> {
fn visit_expr(&mut self, ex: &Expr) {
impl<'a, 'tcx> Visitor<'tcx> for StaticInitializerCtxt<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.bccx.tcx.map)
}
fn visit_expr(&mut self, ex: &'tcx Expr) {
if let hir::ExprAddrOf(mutbl, ref base) = ex.node {
let param_env = ty::ParameterEnvironment::for_item(self.bccx.tcx,
self.item_id);
@ -542,9 +546,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> {
}
}
pub fn gather_loans_in_static_initializer(bccx: &mut BorrowckCtxt,
item_id: ast::NodeId,
expr: &hir::Expr) {
pub fn gather_loans_in_static_initializer<'a, 'tcx>(bccx: &mut BorrowckCtxt<'a, 'tcx>,
item_id: ast::NodeId,
expr: &'tcx hir::Expr) {
debug!("gather_loans_in_static_initializer(expr={:?})", expr);

View file

@ -47,7 +47,7 @@ use syntax_pos::{MultiSpan, Span};
use errors::DiagnosticBuilder;
use rustc::hir;
use rustc::hir::intravisit::{self, Visitor, FnKind};
use rustc::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
pub mod check_loans;
@ -62,9 +62,13 @@ pub struct LoanDataFlowOperator;
pub type LoanDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, LoanDataFlowOperator>;
impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
b: &'v hir::Expr, s: Span, id: ast::NodeId) {
impl<'a, 'tcx> Visitor<'tcx> for BorrowckCtxt<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.tcx.map)
}
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
b: hir::ExprId, s: Span, id: ast::NodeId) {
match fk {
FnKind::ItemFn(..) |
FnKind::Method(..) => {
@ -79,18 +83,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> {
}
}
fn visit_item(&mut self, item: &hir::Item) {
fn visit_item(&mut self, item: &'tcx hir::Item) {
borrowck_item(self, item);
}
fn visit_trait_item(&mut self, ti: &hir::TraitItem) {
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
if let hir::ConstTraitItem(_, Some(ref 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: &hir::ImplItem) {
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);
}
@ -131,7 +135,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
}
}
fn borrowck_item(this: &mut BorrowckCtxt, item: &hir::Item) {
fn borrowck_item<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, item: &'tcx hir::Item) {
// Gather loans for items. Note that we don't need
// to check loans for single expressions. The check
// loan step is intended for things that have a data
@ -154,15 +158,17 @@ pub struct AnalysisData<'a, 'tcx: 'a> {
pub move_data: move_data::FlowedMoveData<'a, 'tcx>,
}
fn borrowck_fn(this: &mut BorrowckCtxt,
fk: FnKind,
decl: &hir::FnDecl,
body: &hir::Expr,
sp: Span,
id: ast::NodeId,
attributes: &[ast::Attribute]) {
fn borrowck_fn<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
fk: FnKind<'tcx>,
decl: &'tcx hir::FnDecl,
body_id: hir::ExprId,
sp: Span,
id: ast::NodeId,
attributes: &[ast::Attribute]) {
debug!("borrowck_fn(id={})", id);
let body = this.tcx.map.expr(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)
@ -191,21 +197,21 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
decl,
body);
intravisit::walk_fn(this, fk, decl, body, sp, id);
intravisit::walk_fn(this, fk, decl, body_id, sp, id);
}
fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
fk: FnKind,
decl: &hir::FnDecl,
fk: FnKind<'tcx>,
decl: &'tcx hir::FnDecl,
cfg: &cfg::CFG,
body: &hir::Expr,
body: &'tcx hir::Expr,
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);
let id_range = intravisit::compute_id_range_for_fn_body(fk, decl, body, sp, id, &tcx.map);
let (all_loans, move_data) =
gather_loans::gather_loans_in_fn(this, id, decl, body);
@ -241,7 +247,7 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
/// the `BorrowckCtxt` itself , e.g. the flowgraph visualizer.
pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
fn_parts: FnParts<'a>,
fn_parts: FnParts<'tcx>,
cfg: &cfg::CFG)
-> (BorrowckCtxt<'a, 'tcx>, AnalysisData<'a, 'tcx>)
{
@ -257,11 +263,13 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
}
};
let body = tcx.map.expr(fn_parts.body);
let dataflow_data = build_borrowck_dataflow_data(&mut bccx,
fn_parts.kind,
&fn_parts.decl,
cfg,
&fn_parts.body,
body,
fn_parts.span,
fn_parts.id);
@ -407,8 +415,8 @@ pub fn closure_to_block(closure_id: ast::NodeId,
tcx: TyCtxt) -> ast::NodeId {
match tcx.map.get(closure_id) {
hir_map::NodeExpr(expr) => match expr.node {
hir::ExprClosure(.., ref block, _) => {
block.id
hir::ExprClosure(.., body_id, _) => {
body_id.node_id()
}
_ => {
bug!("encountered non-closure id: {}", closure_id)

View file

@ -29,7 +29,7 @@ use rustc::ty::{self, TyCtxt};
use rustc_errors::DiagnosticBuilder;
use rustc::hir::def::*;
use rustc::hir::intravisit::{self, Visitor, FnKind};
use rustc::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
use rustc::hir::print::pat_to_string;
use rustc::hir::{self, Pat, PatKind};
@ -41,12 +41,16 @@ use syntax_pos::Span;
struct OuterVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
impl<'a, 'v, 'tcx> Visitor<'v> for OuterVisitor<'a, 'tcx> {
fn visit_expr(&mut self, _expr: &hir::Expr) {
impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::None
}
fn visit_expr(&mut self, _expr: &'tcx hir::Expr) {
return // const, static and N in [T; N] - shouldn't contain anything
}
fn visit_trait_item(&mut self, item: &hir::TraitItem) {
fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) {
if let hir::ConstTraitItem(..) = item.node {
return // nothing worth match checking in a constant
} else {
@ -54,7 +58,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for OuterVisitor<'a, 'tcx> {
}
}
fn visit_impl_item(&mut self, item: &hir::ImplItem) {
fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem) {
if let hir::ImplItemKind::Const(..) = item.node {
return // nothing worth match checking in a constant
} else {
@ -62,8 +66,8 @@ impl<'a, 'v, 'tcx> Visitor<'v> for OuterVisitor<'a, 'tcx> {
}
}
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
b: &'v hir::Expr, s: Span, id: ast::NodeId) {
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
b: hir::ExprId, s: Span, id: ast::NodeId) {
if let FnKind::Closure(..) = fk {
span_bug!(s, "check_match: closure outside of function")
}
@ -90,8 +94,12 @@ struct MatchVisitor<'a, 'tcx: 'a> {
param_env: &'a ty::ParameterEnvironment<'tcx>
}
impl<'a, 'tcx, 'v> Visitor<'v> for MatchVisitor<'a, 'tcx> {
fn visit_expr(&mut self, ex: &hir::Expr) {
impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.tcx.map)
}
fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
intravisit::walk_expr(self, ex);
match ex.node {
@ -102,7 +110,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MatchVisitor<'a, 'tcx> {
}
}
fn visit_local(&mut self, loc: &hir::Local) {
fn visit_local(&mut self, loc: &'tcx hir::Local) {
intravisit::walk_local(self, loc);
self.check_irrefutable(&loc.pat, false);
@ -111,8 +119,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MatchVisitor<'a, 'tcx> {
self.check_patterns(false, slice::ref_slice(&loc.pat));
}
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
b: &'v hir::Expr, s: Span, n: ast::NodeId) {
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
b: hir::ExprId, s: Span, n: ast::NodeId) {
intravisit::walk_fn(self, fk, fd, b, s, n);
for input in &fd.inputs {
@ -557,6 +565,10 @@ struct AtBindingPatternVisitor<'a, 'b:'a, 'tcx:'b> {
}
impl<'a, 'b, 'tcx, 'v> Visitor<'v> for AtBindingPatternVisitor<'a, 'b, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
NestedVisitorMap::None
}
fn visit_pat(&mut self, pat: &Pat) {
match pat.node {
PatKind::Binding(.., ref subpat) => {

View file

@ -33,7 +33,6 @@ use graphviz::IntoCow;
use syntax::ast;
use rustc::hir::{Expr, PatKind};
use rustc::hir;
use rustc::hir::intravisit::FnKind;
use syntax::ptr::P;
use syntax::codemap;
use syntax::attr::IntType;
@ -103,14 +102,16 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
_ => None
},
Some(ast_map::NodeTraitItem(ti)) => match ti.node {
hir::ConstTraitItem(..) => {
hir::ConstTraitItem(ref ty, ref expr_option) => {
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);
resolve_trait_associated_const(tcx, ti, trait_id, substs)
let default_value = expr_option.as_ref()
.map(|expr| (&**expr, 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
// expression that generates the obligation, we could
@ -141,33 +142,31 @@ 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::Item(_, ref item), _)) => match item.node {
hir::ItemConst(ref ty, ref const_expr) => {
Some((&**const_expr, tcx.ast_ty_to_prim_ty(ty)))
},
_ => None
},
Some((&InlinedItem::TraitItem(trait_id, ref ti), _)) => match ti.node {
hir::ConstTraitItem(..) => {
Some((&InlinedItem { body: ref const_expr, .. }, _)) => {
Some((&**const_expr, Some(tcx.sess.cstore.item_type(tcx, def_id))))
}
_ => None
};
let expr_ty = match tcx.sess.cstore.describe_def(def_id) {
Some(Def::AssociatedConst(_)) => {
let trait_id = tcx.sess.cstore.trait_of_item(def_id);
// As mentioned in the comments above for in-crate
// constants, we only try to find the expression for a
// trait-associated const if the caller gives us the
// substitutions for the reference to it.
if let Some(trait_id) = trait_id {
used_substs = true;
if let Some(substs) = substs {
// As mentioned in the comments above for in-crate
// constants, we only try to find the expression for
// a trait-associated const if the caller gives us
// the substitutions for the reference to it.
resolve_trait_associated_const(tcx, ti, trait_id, substs)
resolve_trait_associated_const(tcx, def_id, expr_ty, trait_id, substs)
} else {
None
}
} else {
expr_ty
}
_ => None
},
Some((&InlinedItem::ImplItem(_, ref ii), _)) => match ii.node {
hir::ImplItemKind::Const(ref ty, ref expr) => {
Some((&**expr, tcx.ast_ty_to_prim_ty(ty)))
},
_ => None
},
Some(Def::Const(..)) => expr_ty,
_ => None
};
// If we used the substitutions, particularly to choose an impl
@ -196,24 +195,29 @@ fn inline_const_fn_from_external_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
return None;
}
let fn_id = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) {
Some((&InlinedItem::Item(_, ref item), _)) => Some(item.id),
Some((&InlinedItem::ImplItem(_, ref item), _)) => Some(item.id),
_ => None
};
let fn_id = tcx.sess.cstore.maybe_get_item_ast(tcx, def_id).map(|t| t.1);
tcx.extern_const_fns.borrow_mut().insert(def_id,
fn_id.unwrap_or(ast::DUMMY_NODE_ID));
fn_id
}
pub enum ConstFnNode<'tcx> {
Local(FnLikeNode<'tcx>),
Inlined(&'tcx InlinedItem)
}
pub fn lookup_const_fn_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
-> Option<FnLikeNode<'tcx>>
-> Option<ConstFnNode<'tcx>>
{
let fn_id = if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
node_id
} else {
if let Some(fn_id) = inline_const_fn_from_external_crate(tcx, def_id) {
fn_id
if let ast_map::NodeInlinedItem(ii) = tcx.map.get(fn_id) {
return Some(ConstFnNode::Inlined(ii));
} else {
bug!("Got const fn from external crate, but it's not inlined")
}
} else {
return None;
}
@ -224,18 +228,10 @@ pub fn lookup_const_fn_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI
None => return None
};
match fn_like.kind() {
FnKind::ItemFn(_, _, _, hir::Constness::Const, ..) => {
Some(fn_like)
}
FnKind::Method(_, m, ..) => {
if m.constness == hir::Constness::Const {
Some(fn_like)
} else {
None
}
}
_ => None
if fn_like.constness() == hir::Constness::Const {
Some(ConstFnNode::Local(fn_like))
} else {
None
}
}
@ -868,15 +864,22 @@ 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 (decl, result) = if let Some(fn_like) = lookup_const_fn_by_id(tcx, did) {
(fn_like.decl(), fn_like.body())
} else {
signal!(e, NonConstPath)
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()),
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()),
None => signal!(e, NonConstPath),
};
assert_eq!(decl.inputs.len(), args.len());
let result = tcx.map.expr(body_id);
assert_eq!(arg_defs.len(), args.len());
let mut call_args = DefIdMap();
for (arg, arg_expr) in decl.inputs.iter().zip(args.iter()) {
for (arg, arg_expr) in arg_defs.into_iter().zip(args.iter()) {
let arg_hint = ty_hint.erase_hint();
let arg_val = eval_const_expr_partial(
tcx,
@ -885,7 +888,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
fn_args
)?;
debug!("const call arg: {:?}", arg);
if let PatKind::Binding(_, def_id, _, _) = arg.pat.node {
if let Some(def_id) = arg {
assert!(call_args.insert(def_id, arg_val).is_none());
}
}
@ -1068,11 +1071,13 @@ fn infer<'a, 'tcx>(i: ConstInt,
}
}
fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ti: &'tcx hir::TraitItem,
trait_id: DefId,
rcvr_substs: &'tcx Substs<'tcx>)
-> Option<(&'tcx Expr, Option<ty::Ty<'tcx>>)>
fn resolve_trait_associated_const<'a, 'tcx: 'a>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
trait_item_id: DefId,
default_value: Option<(&'tcx Expr, Option<ty::Ty<'tcx>>)>,
trait_id: DefId,
rcvr_substs: &'tcx Substs<'tcx>
) -> Option<(&'tcx Expr, Option<ty::Ty<'tcx>>)>
{
let trait_ref = ty::Binder(ty::TraitRef::new(trait_id, rcvr_substs));
debug!("resolve_trait_associated_const: trait_ref={:?}",
@ -1103,21 +1108,16 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// when constructing the inference context above.
match selection {
traits::VtableImpl(ref impl_data) => {
let name = tcx.associated_item(trait_item_id).name;
let ac = tcx.associated_items(impl_data.impl_def_id)
.find(|item| item.kind == ty::AssociatedKind::Const && item.name == ti.name);
.find(|item| item.kind == ty::AssociatedKind::Const && item.name == name);
match ac {
Some(ic) => lookup_const_by_id(tcx, ic.def_id, None),
None => match ti.node {
hir::ConstTraitItem(ref ty, Some(ref expr)) => {
Some((&*expr, tcx.ast_ty_to_prim_ty(ty)))
},
_ => None,
},
None => default_value,
}
}
_ => {
span_bug!(ti.span,
"resolve_trait_associated_const: unexpected vtable type")
bug!("resolve_trait_associated_const: unexpected vtable type")
}
}
})

View file

@ -696,13 +696,16 @@ impl fold::Folder for ReplaceBodyWithLoop {
fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
code: blocks::Code,
code: blocks::Code<'tcx>,
mode: PpFlowGraphMode,
mut out: W)
-> io::Result<()> {
let cfg = match code {
blocks::Code::Expr(expr) => cfg::CFG::new(tcx, expr),
blocks::Code::FnLike(fn_like) => cfg::CFG::new(tcx, fn_like.body()),
blocks::Code::FnLike(fn_like) => {
let body = tcx.map.expr(fn_like.body());
cfg::CFG::new(tcx, body)
},
};
let labelled_edges = mode != PpFlowGraphMode::UnlabelledEdges;
let lcfg = LabelledCFG {

View file

@ -34,7 +34,7 @@ use rustc::dep_graph::DepNode;
use rustc::hir;
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
use rustc::hir::intravisit as visit;
use rustc::hir::intravisit::Visitor;
use rustc::hir::intravisit::{Visitor, NestedVisitorMap};
use rustc::ty::TyCtxt;
use rustc_data_structures::fx::FxHashMap;
use rustc::util::common::record_time;
@ -149,19 +149,30 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> {
{
assert!(def_id.is_local());
debug!("HashItemsVisitor::calculate(def_id={:?})", def_id);
self.calculate_def_hash(DepNode::Hir(def_id), false, &mut walk_op);
self.calculate_def_hash(DepNode::HirBody(def_id), true, &mut walk_op);
}
fn calculate_def_hash<W>(&mut self,
dep_node: DepNode<DefId>,
hash_bodies: bool,
walk_op: &mut W)
where W: for<'v> FnMut(&mut StrictVersionHashVisitor<'v, 'a, 'tcx>)
{
let mut state = IchHasher::new();
walk_op(&mut StrictVersionHashVisitor::new(&mut state,
self.tcx,
&mut self.def_path_hashes,
&mut self.codemap,
self.hash_spans));
self.hash_spans,
hash_bodies));
let bytes_hashed = state.bytes_hashed();
let item_hash = state.finish();
self.hashes.insert(DepNode::Hir(def_id), item_hash);
debug!("calculate_item_hash: def_id={:?} hash={:?}", def_id, item_hash);
debug!("calculate_def_hash: dep_node={:?} hash={:?}", dep_node, item_hash);
self.hashes.insert(dep_node, item_hash);
let bytes_hashed = self.tcx.sess.perf_stats.incr_comp_bytes_hashed.get() +
bytes_hashed;
bytes_hashed;
self.tcx.sess.perf_stats.incr_comp_bytes_hashed.set(bytes_hashed);
}
@ -200,7 +211,8 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> {
self.tcx,
&mut self.def_path_hashes,
&mut self.codemap,
self.hash_spans);
self.hash_spans,
false);
visitor.hash_attributes(&krate.attrs);
}
@ -212,6 +224,10 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for HashItemsVisitor<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::None
}
fn visit_item(&mut self, item: &'tcx hir::Item) {
self.calculate_node_id(item.id, |v| v.visit_item(item));
visit::walk_item(self, item);

View file

@ -52,6 +52,7 @@ pub struct StrictVersionHashVisitor<'a, 'hash: 'a, 'tcx: 'hash> {
hash_spans: bool,
codemap: &'a mut CachingCodemapView<'tcx>,
overflow_checks_enabled: bool,
hash_bodies: bool,
}
impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
@ -59,7 +60,8 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
tcx: TyCtxt<'hash, 'tcx, 'tcx>,
def_path_hashes: &'a mut DefPathHashes<'hash, 'tcx>,
codemap: &'a mut CachingCodemapView<'tcx>,
hash_spans: bool)
hash_spans: bool,
hash_bodies: bool)
-> Self {
let check_overflow = tcx.sess.opts.debugging_opts.force_overflow_checks
.unwrap_or(tcx.sess.opts.debug_assertions);
@ -71,6 +73,7 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
hash_spans: hash_spans,
codemap: codemap,
overflow_checks_enabled: check_overflow,
hash_bodies: hash_bodies,
}
}
@ -459,15 +462,16 @@ fn saw_ty(node: &Ty_) -> SawTyComponent {
#[derive(Hash)]
enum SawTraitOrImplItemComponent {
SawTraitOrImplItemConst,
SawTraitOrImplItemMethod(Unsafety, Constness, Abi),
// The boolean signifies whether a body is present
SawTraitOrImplItemMethod(Unsafety, Constness, Abi, bool),
SawTraitOrImplItemType
}
fn saw_trait_item(ti: &TraitItem_) -> SawTraitOrImplItemComponent {
match *ti {
ConstTraitItem(..) => SawTraitOrImplItemConst,
MethodTraitItem(ref sig, _) =>
SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi),
MethodTraitItem(ref sig, ref body) =>
SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi, body.is_some()),
TypeTraitItem(..) => SawTraitOrImplItemType
}
}
@ -476,7 +480,7 @@ fn saw_impl_item(ii: &ImplItemKind) -> SawTraitOrImplItemComponent {
match *ii {
ImplItemKind::Const(..) => SawTraitOrImplItemConst,
ImplItemKind::Method(ref sig, _) =>
SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi),
SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi, true),
ImplItemKind::Type(..) => SawTraitOrImplItemType
}
}
@ -509,6 +513,14 @@ macro_rules! hash_span {
}
impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'hash, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> visit::NestedVisitorMap<'this, 'tcx> {
if self.hash_bodies {
visit::NestedVisitorMap::OnlyBodies(&self.tcx.map)
} else {
visit::NestedVisitorMap::None
}
}
fn visit_variant_data(&mut self,
s: &'tcx VariantData,
name: Name,
@ -609,7 +621,8 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has
fn visit_mod(&mut self, m: &'tcx Mod, _s: Span, n: NodeId) {
debug!("visit_mod: st={:?}", self.st);
SawMod.hash(self.st); visit::walk_mod(self, m, n)
SawMod.hash(self.st);
visit::walk_mod(self, m, n)
}
fn visit_ty(&mut self, t: &'tcx Ty) {

View file

@ -114,7 +114,8 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
match dep_node {
DepNode::Krate |
DepNode::Hir(_) => {
DepNode::Hir(_) |
DepNode::HirBody(_) => {
// HIR nodes are inputs, so if we are asserting that the HIR node is
// dirty, we check the dirty input set.
if !self.dirty_inputs.contains(&dep_node) {
@ -143,7 +144,8 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
match dep_node {
DepNode::Krate |
DepNode::Hir(_) => {
DepNode::Hir(_) |
DepNode::HirBody(_) => {
// For HIR nodes, check the inputs.
if self.dirty_inputs.contains(&dep_node) {
let dep_node_str = self.dep_node_str(&dep_node);

View file

@ -45,7 +45,9 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
pub fn is_hashable(dep_node: &DepNode<DefId>) -> bool {
match *dep_node {
DepNode::Krate |
DepNode::Hir(_) => true,
DepNode::Hir(_) |
DepNode::HirBody(_) =>
true,
DepNode::MetaData(def_id) => !def_id.is_local(),
_ => false,
}
@ -58,7 +60,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
}
// HIR nodes (which always come from our crate) are an input:
DepNode::Hir(def_id) => {
DepNode::Hir(def_id) | DepNode::HirBody(def_id) => {
assert!(def_id.is_local(),
"cannot hash HIR for non-local def-id {:?} => {:?}",
def_id,

View file

@ -145,8 +145,8 @@ pub fn encode_dep_graph(preds: &Predecessors,
for (&target, sources) in &preds.inputs {
match *target {
DepNode::MetaData(ref def_id) => {
// Metadata *targets* are always local metadata nodes. We handle
// those in `encode_metadata_hashes`, which comes later.
// Metadata *targets* are always local metadata nodes. We have
// already handled those in `encode_metadata_hashes`.
assert!(def_id.is_local());
continue;
}

View file

@ -10,7 +10,7 @@
use rustc::hir::map as ast_map;
use rustc::hir::intravisit::{Visitor, IdRangeComputingVisitor, IdRange};
use rustc::hir::intravisit::{Visitor, IdRangeComputingVisitor, IdRange, NestedVisitorMap};
use cstore::CrateMetadata;
use encoder::EncodeContext;
@ -43,13 +43,9 @@ enum TableEntry<'tcx> {
}
impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
pub fn encode_inlined_item(&mut self, ii: InlinedItemRef) -> Lazy<Ast<'tcx>> {
let mut id_visitor = IdRangeComputingVisitor::new();
match ii {
InlinedItemRef::Item(_, i) => id_visitor.visit_item(i),
InlinedItemRef::TraitItem(_, ti) => id_visitor.visit_trait_item(ti),
InlinedItemRef::ImplItem(_, ii) => id_visitor.visit_impl_item(ii),
}
pub fn encode_inlined_item(&mut self, ii: InlinedItemRef<'tcx>) -> Lazy<Ast<'tcx>> {
let mut id_visitor = IdRangeComputingVisitor::new(&self.tcx.map);
ii.visit(&mut id_visitor);
let ii_pos = self.position();
ii.encode(self).unwrap();
@ -60,11 +56,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
ecx: self,
count: 0,
};
match ii {
InlinedItemRef::Item(_, i) => visitor.visit_item(i),
InlinedItemRef::TraitItem(_, ti) => visitor.visit_trait_item(ti),
InlinedItemRef::ImplItem(_, ii) => visitor.visit_impl_item(ii),
}
ii.visit(&mut visitor);
visitor.count
};
@ -81,7 +73,11 @@ struct SideTableEncodingIdVisitor<'a, 'b: 'a, 'tcx: 'b> {
count: usize,
}
impl<'a, 'b, 'tcx, 'v> Visitor<'v> for SideTableEncodingIdVisitor<'a, 'b, 'tcx> {
impl<'a, 'b, 'tcx> Visitor<'tcx> for SideTableEncodingIdVisitor<'a, 'b, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.ecx.tcx.map)
}
fn visit_id(&mut self, id: ast::NodeId) {
debug!("Encoding side tables for id {}", id);
@ -122,17 +118,13 @@ pub fn decode_inlined_item<'a, 'tcx>(cdata: &CrateMetadata,
}];
let ii = ast.item.decode((cdata, tcx, id_ranges));
let item_node_id = tcx.sess.next_node_id();
let ii = ast_map::map_decoded_item(&tcx.map,
parent_def_path,
parent_did,
ii,
tcx.sess.next_node_id());
item_node_id);
let item_node_id = match ii {
&InlinedItem::Item(_, ref i) => i.id,
&InlinedItem::TraitItem(_, ref ti) => ti.id,
&InlinedItem::ImplItem(_, ref ii) => ii.id,
};
let inlined_did = tcx.map.local_def_id(item_node_id);
let ty = tcx.item_type(orig_did);
let generics = tcx.item_generics(orig_did);

View file

@ -443,12 +443,10 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
let find_inlined_item_root = |inlined_item_id| {
let mut node = inlined_item_id;
let mut path = Vec::with_capacity(10);
// If we can't find the inline root after a thousand hops, we can
// be pretty sure there's something wrong with the HIR map.
for _ in 0 .. 1000 {
path.push(node);
let parent_node = tcx.map.get_parent_node(node);
if parent_node == node {
return node;
@ -464,27 +462,9 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
.borrow_mut()
.insert(def_id, None);
}
Some(&InlinedItem::Item(d, ref item)) => {
assert_eq!(d, def_id);
let inlined_root_node_id = find_inlined_item_root(item.id);
cache_inlined_item(def_id, item.id, inlined_root_node_id);
}
Some(&InlinedItem::TraitItem(_, ref trait_item)) => {
let inlined_root_node_id = find_inlined_item_root(trait_item.id);
cache_inlined_item(def_id, trait_item.id, inlined_root_node_id);
// Associated consts already have to be evaluated in `typeck`, so
// the logic to do that already exists in `middle`. In order to
// reuse that code, it needs to be able to look up the traits for
// inlined items.
let ty_trait_item = tcx.associated_item(def_id).clone();
let trait_item_def_id = tcx.map.local_def_id(trait_item.id);
tcx.associated_items.borrow_mut()
.insert(trait_item_def_id, ty_trait_item);
}
Some(&InlinedItem::ImplItem(_, ref impl_item)) => {
let inlined_root_node_id = find_inlined_item_root(impl_item.id);
cache_inlined_item(def_id, impl_item.id, inlined_root_node_id);
Some(&InlinedItem { ref body, .. }) => {
let inlined_root_node_id = find_inlined_item_root(body.id);
cache_inlined_item(def_id, inlined_root_node_id, inlined_root_node_id);
}
}

View file

@ -39,7 +39,7 @@ use syntax_pos;
use rustc::hir::{self, PatKind};
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir::intravisit::Visitor;
use rustc::hir::intravisit::{Visitor, NestedVisitorMap};
use rustc::hir::intravisit;
use super::index_builder::{FromId, IndexBuilder, Untracked};
@ -516,9 +516,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
ast: if trait_item.kind == ty::AssociatedKind::Const {
ast: if let hir::ConstTraitItem(_, Some(_)) = ast_item.node {
// We only save the HIR for associated consts with bodies
// (InlinedItemRef::from_trait_item panics otherwise)
let trait_def_id = trait_item.container.id();
Some(self.encode_inlined_item(InlinedItemRef::TraitItem(trait_def_id, ast_item)))
Some(self.encode_inlined_item(
InlinedItemRef::from_trait_item(trait_def_id, ast_item, tcx)
))
} else {
None
},
@ -527,6 +531,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
let tcx = self.tcx;
let node_id = self.tcx.map.as_local_node_id(def_id).unwrap();
let ast_item = self.tcx.map.expect_impl_item(node_id);
let impl_item = self.tcx.associated_item(def_id);
@ -587,7 +593,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
predicates: Some(self.encode_predicates(def_id)),
ast: if ast {
Some(self.encode_inlined_item(InlinedItemRef::ImplItem(impl_def_id, ast_item)))
Some(self.encode_inlined_item(
InlinedItemRef::from_impl_item(impl_def_id, ast_item, tcx)
))
} else {
None
},
@ -630,7 +638,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.tcx.lookup_deprecation(def_id).map(|depr| self.lazy(&depr))
}
fn encode_info_for_item(&mut self, (def_id, item): (DefId, &hir::Item)) -> Entry<'tcx> {
fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) -> Entry<'tcx> {
let tcx = self.tcx;
debug!("encoding info for item at {}",
@ -817,7 +825,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
ast: match item.node {
hir::ItemConst(..) |
hir::ItemFn(_, _, hir::Constness::Const, ..) => {
Some(self.encode_inlined_item(InlinedItemRef::Item(def_id, item)))
Some(self.encode_inlined_item(
InlinedItemRef::from_item(def_id, item, tcx)
))
}
_ => None,
},
@ -973,6 +983,9 @@ struct EncodeVisitor<'a, 'b: 'a, 'tcx: 'b> {
}
impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.index.tcx.map)
}
fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
intravisit::walk_expr(self, ex);
self.index.encode_info_for_expr(ex);

View file

@ -736,7 +736,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(.., ref body, _) => body.id,
hir::ExprClosure(.., body_id, _) => body_id.node_id(),
_ => {
span_bug!(expr.span, "closure expr is not a closure expr");
}

View file

@ -23,7 +23,6 @@ use rustc_const_eval as const_eval;
use rustc_data_structures::indexed_vec::Idx;
use rustc::dep_graph::DepNode;
use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::FnKind;
use rustc::hir::map::blocks::FnLikeNode;
use rustc::infer::InferCtxt;
use rustc::ty::subst::Subst;
@ -51,11 +50,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
MirSource::Static(..) => hir::Constness::Const,
MirSource::Fn(id) => {
let fn_like = FnLikeNode::from_node(infcx.tcx.map.get(id));
match fn_like.map(|f| f.kind()) {
Some(FnKind::ItemFn(_, _, _, c, ..)) => c,
Some(FnKind::Method(_, m, ..)) => m.constness,
_ => hir::Constness::NotConst
}
fn_like.map_or(hir::Constness::NotConst, |f| f.constness())
}
MirSource::Promoted(..) => bug!()
};

View file

@ -30,7 +30,7 @@ use rustc::traits::Reveal;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::subst::Substs;
use rustc::hir;
use rustc::hir::intravisit::{self, FnKind, Visitor};
use rustc::hir::intravisit::{self, FnKind, Visitor, NestedVisitorMap};
use syntax::abi::Abi;
use syntax::ast;
use syntax_pos::Span;
@ -144,6 +144,10 @@ impl<'a, 'gcx> BuildMir<'a, 'gcx> {
}
impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.tcx.map)
}
// Const and static items.
fn visit_item(&mut self, item: &'tcx hir::Item) {
match item.node {
@ -210,7 +214,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
fn visit_fn(&mut self,
fk: FnKind<'tcx>,
decl: &'tcx hir::FnDecl,
body: &'tcx hir::Expr,
body_id: hir::ExprId,
span: Span,
id: ast::NodeId) {
// fetch the fully liberated fn signature (that is, all bound
@ -223,7 +227,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), 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)
@ -237,12 +241,14 @@ 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)
});
intravisit::walk_fn(self, fk, decl, body, span, id);
intravisit::walk_fn(self, fk, decl, body_id, span, id);
}
}

View file

@ -19,7 +19,6 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use rustc::hir;
use rustc::hir::map as hir_map;
use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::FnKind;
use rustc::hir::map::blocks::FnLikeNode;
use rustc::traits::{self, Reveal};
use rustc::ty::{self, TyCtxt, Ty};
@ -116,15 +115,10 @@ impl fmt::Display for Mode {
pub fn is_const_fn(tcx: TyCtxt, def_id: DefId) -> bool {
if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
let fn_like = FnLikeNode::from_node(tcx.map.get(node_id));
match fn_like.map(|f| f.kind()) {
Some(FnKind::ItemFn(_, _, _, c, ..)) => {
c == hir::Constness::Const
}
Some(FnKind::Method(_, m, ..)) => {
m.constness == hir::Constness::Const
}
_ => false
if let Some(fn_like) = FnLikeNode::from_node(tcx.map.get(node_id)) {
fn_like.constness() == hir::Constness::Const
} else {
false
}
} else {
tcx.sess.cstore.is_const_fn(def_id)

View file

@ -27,7 +27,7 @@
use rustc::dep_graph::DepNode;
use rustc::ty::cast::CastKind;
use rustc_const_eval::{ConstEvalErr, lookup_const_fn_by_id, compare_lit_exprs};
use rustc_const_eval::{eval_const_expr_partial, lookup_const_by_id};
use rustc_const_eval::{ConstFnNode, eval_const_expr_partial, lookup_const_by_id};
use rustc_const_eval::ErrKind::{IndexOpFeatureGated, UnimplementedConstVal, MiscCatchAll, Math};
use rustc_const_eval::ErrKind::{ErroneousReferencedConstant, MiscBinaryOp, NonConstPath};
use rustc_const_eval::ErrKind::UnresolvedPath;
@ -48,7 +48,7 @@ use rustc::lint::builtin::CONST_ERR;
use rustc::hir::{self, PatKind};
use syntax::ast;
use syntax_pos::Span;
use rustc::hir::intravisit::{self, FnKind, Visitor};
use rustc::hir::intravisit::{self, FnKind, Visitor, NestedVisitorMap};
use std::collections::hash_map::Entry;
use std::cmp::Ordering;
@ -100,7 +100,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
.enter(|infcx| f(&mut euv::ExprUseVisitor::new(self, &infcx)))
}
fn global_expr(&mut self, mode: Mode, expr: &hir::Expr) -> ConstQualif {
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) {
Entry::Occupied(entry) => return *entry.get(),
@ -132,9 +132,9 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
}
fn fn_like(&mut self,
fk: FnKind,
fd: &hir::FnDecl,
b: &hir::Expr,
fk: FnKind<'gcx>,
fd: &'gcx hir::FnDecl,
b: hir::ExprId,
s: Span,
fn_id: ast::NodeId)
-> ConstQualif {
@ -160,7 +160,8 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
};
let qualif = self.with_mode(mode, |this| {
this.with_euv(Some(fn_id), |euv| euv.walk_fn(fd, b));
let body = this.tcx.map.expr(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
});
@ -179,21 +180,39 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
/// Returns true if the call is to a const fn or method.
fn handle_const_fn_call(&mut self, _expr: &hir::Expr, def_id: DefId, ret_ty: Ty<'gcx>) -> bool {
if let Some(fn_like) = lookup_const_fn_by_id(self.tcx, def_id) {
let qualif = self.fn_like(fn_like.kind(),
fn_like.decl(),
fn_like.body(),
fn_like.span(),
fn_like.id());
self.add_qualif(qualif);
match lookup_const_fn_by_id(self.tcx, def_id) {
Some(ConstFnNode::Local(fn_like)) => {
let qualif = self.fn_like(fn_like.kind(),
fn_like.decl(),
fn_like.body(),
fn_like.span(),
fn_like.id());
if ret_ty.type_contents(self.tcx).interior_unsafe() {
self.add_qualif(ConstQualif::MUTABLE_MEM);
}
self.add_qualif(qualif);
true
} else {
false
if ret_ty.type_contents(self.tcx).interior_unsafe() {
self.add_qualif(ConstQualif::MUTABLE_MEM);
}
true
},
Some(ConstFnNode::Inlined(ii)) => {
let node_id = ii.body.id;
let qualif = match self.tcx.const_qualif_map.borrow_mut().entry(node_id) {
Entry::Occupied(entry) => *entry.get(),
_ => bug!("const qualif entry missing for inlined item")
};
self.add_qualif(qualif);
if ret_ty.type_contents(self.tcx).interior_unsafe() {
self.add_qualif(ConstQualif::MUTABLE_MEM);
}
true
},
None => false
}
}
@ -213,8 +232,12 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
}
}
impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &hir::Item) {
impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.tcx.map)
}
fn visit_item(&mut self, i: &'tcx hir::Item) {
debug!("visit_item(item={})", self.tcx.map.node_to_string(i.id));
assert_eq!(self.mode, Mode::Var);
match i.node {
@ -240,7 +263,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
}
}
fn visit_trait_item(&mut self, t: &'v hir::TraitItem) {
fn visit_trait_item(&mut self, t: &'tcx hir::TraitItem) {
match t.node {
hir::ConstTraitItem(_, ref default) => {
if let Some(ref expr) = *default {
@ -253,7 +276,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
}
}
fn visit_impl_item(&mut self, i: &'v hir::ImplItem) {
fn visit_impl_item(&mut self, i: &'tcx hir::ImplItem) {
match i.node {
hir::ImplItemKind::Const(_, ref expr) => {
self.global_expr(Mode::Const, &expr);
@ -263,15 +286,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
}
fn visit_fn(&mut self,
fk: FnKind<'v>,
fd: &'v hir::FnDecl,
b: &'v hir::Expr,
fk: FnKind<'tcx>,
fd: &'tcx hir::FnDecl,
b: hir::ExprId,
s: Span,
fn_id: ast::NodeId) {
self.fn_like(fk, fd, b, s, fn_id);
}
fn visit_pat(&mut self, p: &hir::Pat) {
fn visit_pat(&mut self, p: &'tcx hir::Pat) {
match p.node {
PatKind::Lit(ref lit) => {
self.global_expr(Mode::Const, &lit);
@ -296,7 +319,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
}
}
fn visit_block(&mut self, block: &hir::Block) {
fn visit_block(&mut self, block: &'tcx hir::Block) {
// Check all statements in the block
for stmt in &block.stmts {
match stmt.node {
@ -315,7 +338,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
intravisit::walk_block(self, block);
}
fn visit_expr(&mut self, ex: &hir::Expr) {
fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
let mut outer = self.qualif;
self.qualif = ConstQualif::empty();

View file

@ -106,7 +106,7 @@ impl<'k> StatCollector<'k> {
}
impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'v>> {
fn nested_visit_map<'this>(&'this mut self) -> hir_visit::NestedVisitorMap<'this, 'v> {
panic!("visit_nested_xxx must be manually implemented in this visitor")
}
@ -172,7 +172,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: &'v hir::Expr,
b: hir::ExprId,
s: Span,
id: NodeId) {
self.record("FnDecl", Id::None, fd);

View file

@ -13,7 +13,7 @@ use rustc::session::Session;
use rustc::dep_graph::DepNode;
use rustc::hir::map::Map;
use rustc::hir::intravisit::{self, Visitor};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir;
use syntax::ast;
use syntax_pos::Span;
@ -59,16 +59,20 @@ pub fn check_crate(sess: &Session, map: &Map) {
}.as_deep_visitor());
}
impl<'a, 'ast, 'v> Visitor<'v> for CheckLoopVisitor<'a, 'ast> {
fn visit_item(&mut self, i: &hir::Item) {
impl<'a, 'ast> Visitor<'ast> for CheckLoopVisitor<'a, 'ast> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> {
NestedVisitorMap::OnlyBodies(&self.hir_map)
}
fn visit_item(&mut self, i: &'ast hir::Item) {
self.with_context(Normal, |v| intravisit::walk_item(v, i));
}
fn visit_impl_item(&mut self, i: &hir::ImplItem) {
fn visit_impl_item(&mut self, i: &'ast hir::ImplItem) {
self.with_context(Normal, |v| intravisit::walk_impl_item(v, i));
}
fn visit_expr(&mut self, e: &hir::Expr) {
fn visit_expr(&mut self, e: &'ast hir::Expr) {
match e.node {
hir::ExprWhile(ref e, ref b, _) => {
self.with_context(Loop(LoopKind::WhileLoop), |v| {
@ -79,8 +83,8 @@ impl<'a, 'ast, 'v> Visitor<'v> for CheckLoopVisitor<'a, 'ast> {
hir::ExprLoop(ref b, _, source) => {
self.with_context(Loop(LoopKind::Loop(source)), |v| v.visit_block(&b));
}
hir::ExprClosure(.., ref b, _) => {
self.with_context(Closure, |v| v.visit_expr(&b));
hir::ExprClosure(.., b, _) => {
self.with_context(Closure, |v| v.visit_body(b));
}
hir::ExprBreak(label, ref opt_expr) => {
if opt_expr.is_some() {

View file

@ -18,7 +18,7 @@ use rustc::ty::{self, TyCtxt, ParameterEnvironment};
use rustc::traits::Reveal;
use rustc::hir;
use rustc::hir::intravisit::{self, Visitor};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use syntax::ast;
use syntax_pos::Span;
@ -31,11 +31,15 @@ struct RvalueContext<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
impl<'a, 'tcx, 'v> Visitor<'v> for RvalueContext<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for RvalueContext<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.tcx.map)
}
fn visit_fn(&mut self,
fk: intravisit::FnKind<'v>,
fd: &'v hir::FnDecl,
b: &'v hir::Expr,
fk: intravisit::FnKind<'tcx>,
fd: &'tcx hir::FnDecl,
b: hir::ExprId,
s: Span,
fn_id: ast::NodeId) {
// FIXME (@jroesch) change this to be an inference context
@ -46,8 +50,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for RvalueContext<'a, 'tcx> {
tcx: infcx.tcx,
param_env: &param_env
};
let body = infcx.tcx.map.expr(b);
let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx);
euv.walk_fn(fd, b);
euv.walk_fn(fd, body);
});
intravisit::walk_fn(self, fk, fd, b, s, fn_id)
}

View file

@ -20,7 +20,7 @@ use rustc::util::nodemap::NodeMap;
use syntax::ast;
use syntax::feature_gate::{GateIssue, emit_feature_err};
use syntax_pos::Span;
use rustc::hir::intravisit::{self, Visitor};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir;
use std::cell::RefCell;
@ -36,6 +36,10 @@ struct CheckCrateVisitor<'a, 'ast: 'a> {
}
impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> {
NestedVisitorMap::None
}
fn visit_item(&mut self, it: &'ast hir::Item) {
match it.node {
hir::ItemStatic(..) |
@ -200,6 +204,10 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
}
impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> {
NestedVisitorMap::OnlyBodies(&self.ast_map)
}
fn visit_item(&mut self, it: &'ast hir::Item) {
self.with_item_id_pushed(it.id, |v| intravisit::walk_item(v, it), it.span);
}

View file

@ -30,7 +30,7 @@ use rustc::dep_graph::DepNode;
use rustc::hir::{self, PatKind};
use rustc::hir::def::{self, Def, CtorKind};
use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::{self, Visitor};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir::itemlikevisit::DeepVisitor;
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
use rustc::lint;
@ -120,8 +120,8 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
/// We want to visit items in the context of their containing
/// module and so forth, so supply a crate for doing a deep walk.
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
Some(&self.tcx.map)
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::All(&self.tcx.map)
}
fn visit_item(&mut self, item: &'tcx hir::Item) {
@ -432,8 +432,8 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for PrivacyVisitor<'a, 'tcx> {
/// We want to visit items in the context of their containing
/// module and so forth, so supply a crate for doing a deep walk.
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
Some(&self.tcx.map)
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::All(&self.tcx.map)
}
fn visit_item(&mut self, item: &'tcx hir::Item) {
@ -615,6 +615,10 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
}
impl<'a, 'b, 'tcx, 'v> Visitor<'v> for ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
NestedVisitorMap::None
}
fn visit_ty(&mut self, ty: &hir::Ty) {
if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = ty.node {
if self.inner.path_is_private_type(path) {
@ -640,8 +644,8 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for ObsoleteCheckTypeForPrivatenessVisitor<'a
impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
/// We want to visit items in the context of their containing
/// module and so forth, so supply a crate for doing a deep walk.
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
Some(&self.tcx.map)
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::All(&self.tcx.map)
}
fn visit_item(&mut self, item: &'tcx hir::Item) {
@ -1059,8 +1063,12 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
}
}
impl<'a, 'tcx, 'v> Visitor<'v> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &hir::Item) {
impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.tcx.map)
}
fn visit_item(&mut self, item: &'tcx hir::Item) {
let tcx = self.tcx;
let min = |vis1: ty::Visibility, vis2| {
if vis1.is_at_least(vis2, &tcx.map) { vis2 } else { vis1 }
@ -1163,11 +1171,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivateItemsInPublicInterfacesVisitor<'a, 'tc
}
}
fn visit_impl_item(&mut self, _impl_item: &'v hir::ImplItem) {
fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem) {
// handled in `visit_item` above
}
fn visit_ty(&mut self, ty: &hir::Ty) {
fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
if let hir::TyImplTrait(..) = ty.node {
// Check the traits being exposed, as they're separate,
// e.g. `impl Iterator<Item=T>` has two predicates,
@ -1181,9 +1189,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivateItemsInPublicInterfacesVisitor<'a, 'tc
}
// Don't recurse into expressions in array sizes or const initializers
fn visit_expr(&mut self, _: &hir::Expr) {}
fn visit_expr(&mut self, _: &'tcx hir::Expr) {}
// Don't recurse into patterns in function arguments
fn visit_pat(&mut self, _: &hir::Pat) {}
fn visit_pat(&mut self, _: &'tcx hir::Pat) {}
}
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

View file

@ -15,7 +15,7 @@
//! paths etc in all kinds of annoying scenarios.
use rustc::hir;
use rustc::hir::intravisit::{self, Visitor};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use syntax::ast;
use common::SharedCrateContext;
@ -67,6 +67,10 @@ impl<'a, 'tcx> SymbolNamesTest<'a, 'tcx> {
}
impl<'a, 'tcx> Visitor<'tcx> for SymbolNamesTest<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::None
}
fn visit_item(&mut self, item: &'tcx hir::Item) {
self.process_attrs(item.id);
intravisit::walk_item(self, item);

View file

@ -23,7 +23,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
expr: &hir::Expr,
_capture: hir::CaptureClause,
decl: &'gcx hir::FnDecl,
body: &'gcx hir::Expr,
body_id: hir::ExprId,
expected: Expectation<'tcx>)
-> Ty<'tcx> {
debug!("check_expr_closure(expr={:?},expected={:?})",
@ -37,6 +37,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);
self.check_closure(expr, expected_kind, decl, body, expected_sig)
}

View file

@ -119,7 +119,7 @@ use syntax::symbol::{Symbol, InternedString, keywords};
use syntax::util::lev_distance::find_best_match_for_name;
use syntax_pos::{self, BytePos, Span};
use rustc::hir::intravisit::{self, Visitor};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir::{self, PatKind};
use rustc::hir::print as pprust;
@ -538,6 +538,10 @@ struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.ccx.tcx.map)
}
fn visit_item(&mut self, i: &'tcx hir::Item) {
check_item_type(self.ccx, i);
intravisit::walk_item(self, i);
@ -630,9 +634,11 @@ pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult {
fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
decl: &'tcx hir::FnDecl,
body: &'tcx hir::Expr,
body_id: hir::ExprId,
fn_id: ast::NodeId,
span: Span) {
let body = ccx.tcx.map.expr(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,
@ -643,13 +649,13 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
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);
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, &fn_sig);
inh.normalize_associated_types_in(body.span, body_id.node_id(), &fn_sig);
let fcx = check_fn(&inh, fn_ty.unsafety, fn_id, &fn_sig, decl, fn_id, body);
@ -659,7 +665,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);
fcx.regionck_fn(fn_id, decl, body_id);
fcx.resolve_type_vars_in_fn(decl, body, fn_id);
});
}
@ -694,6 +700,10 @@ impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> {
}
impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
NestedVisitorMap::None
}
// Add explicitly-declared locals.
fn visit_local(&mut self, local: &'gcx hir::Local) {
let o_ty = match local.ty {
@ -750,7 +760,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,
_: &'gcx hir::Expr, _: Span, _: ast::NodeId) { }
_: hir::ExprId, _: Span, _: ast::NodeId) { }
}
/// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
@ -911,8 +921,8 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
let _indenter = indenter();
match it.node {
hir::ItemFn(ref decl, .., ref body) => {
check_bare_fn(ccx, &decl, &body, it.id, it.span);
hir::ItemFn(ref decl, .., body_id) => {
check_bare_fn(ccx, &decl, body_id, it.id, it.span);
}
hir::ItemImpl(.., ref impl_item_refs) => {
debug!("ItemImpl {} with id {}", it.name, it.id);
@ -923,8 +933,8 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
hir::ImplItemKind::Const(_, ref expr) => {
check_const(ccx, &expr, impl_item.id)
}
hir::ImplItemKind::Method(ref sig, ref body) => {
check_bare_fn(ccx, &sig.decl, body, impl_item.id, impl_item.span);
hir::ImplItemKind::Method(ref sig, body_id) => {
check_bare_fn(ccx, &sig.decl, body_id, impl_item.id, impl_item.span);
}
hir::ImplItemKind::Type(_) => {
// Nothing to do here.
@ -938,8 +948,8 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
hir::ConstTraitItem(_, Some(ref expr)) => {
check_const(ccx, &expr, trait_item.id)
}
hir::MethodTraitItem(ref sig, Some(ref body)) => {
check_bare_fn(ccx, &sig.decl, body, trait_item.id, trait_item.span);
hir::MethodTraitItem(ref sig, Some(body_id)) => {
check_bare_fn(ccx, &sig.decl, body_id, trait_item.id, trait_item.span);
}
hir::MethodTraitItem(_, None) |
hir::ConstTraitItem(_, None) |
@ -1102,14 +1112,14 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
err.emit()
}
}
hir::ImplItemKind::Method(_, ref body) => {
hir::ImplItemKind::Method(_, body_id) => {
let trait_span = tcx.map.span_if_local(ty_trait_item.def_id);
if ty_trait_item.kind == ty::AssociatedKind::Method {
let err_count = tcx.sess.err_count();
compare_impl_method(ccx,
&ty_impl_item,
impl_item.span,
body.id,
body_id.node_id(),
&ty_trait_item,
impl_trait_ref,
trait_span,
@ -1119,7 +1129,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,
body_id.node_id(),
&ty_trait_item,
impl_trait_ref,
trait_span,
@ -3791,8 +3801,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
hir::ExprMatch(ref discrim, ref arms, match_src) => {
self.check_match(expr, &discrim, arms, expected, match_src)
}
hir::ExprClosure(capture, ref decl, ref body, _) => {
self.check_expr_closure(expr, capture, &decl, &body, expected)
hir::ExprClosure(capture, ref decl, body_id, _) => {
self.check_expr_closure(expr, capture, &decl, body_id, expected)
}
hir::ExprBlock(ref b) => {
self.check_block_with_expected(&b, expected)

View file

@ -99,7 +99,7 @@ use std::mem;
use std::ops::Deref;
use syntax::ast;
use syntax_pos::Span;
use rustc::hir::intravisit::{self, Visitor};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir::{self, PatKind};
use self::SubjectNode::Subject;
@ -113,7 +113,7 @@ macro_rules! ignore_err {
// PUBLIC ENTRY POINTS
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
pub fn regionck_expr(&self, e: &hir::Expr) {
pub fn regionck_expr(&self, e: &'gcx hir::Expr) {
let mut rcx = RegionCtxt::new(self, RepeatingScope(e.id), e.id, Subject(e.id));
if self.err_count_since_creation() == 0 {
// regionck assumes typeck succeeded
@ -141,13 +141,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
pub fn regionck_fn(&self,
fn_id: ast::NodeId,
decl: &hir::FnDecl,
body: &hir::Expr) {
body_id: hir::ExprId) {
debug!("regionck_fn(id={})", fn_id);
let mut rcx = RegionCtxt::new(self, RepeatingScope(body.id), body.id, Subject(fn_id));
let node_id = body_id.node_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, self.tcx.map.span(fn_id));
rcx.visit_fn_body(fn_id, decl, body_id, self.tcx.map.span(fn_id));
}
rcx.free_region_map.relate_free_regions_from_predicates(
@ -267,14 +268,14 @@ 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: &hir::Expr,
body_id: hir::ExprId,
span: Span)
{
// When we enter a function, we can derive
debug!("visit_fn_body(id={})", id);
let call_site = self.tcx.region_maps.lookup_code_extent(
region::CodeExtentData::CallSiteScope { fn_id: id, body_id: body.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 = {
@ -300,19 +301,20 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
.chain(Some(fn_sig.output))
.collect();
let old_body_id = self.set_body_id(body.id);
self.relate_free_regions(&fn_sig_tys[..], body.id, span);
self.link_fn_args(self.tcx.region_maps.node_extent(body.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);
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);
let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope));
self.type_of_node_must_outlive(infer::CallReturn(span),
body.id,
body_id.node_id(),
call_site_region);
self.region_bound_pairs.truncate(old_region_bounds_pairs_len);
@ -469,7 +471,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
}
}
impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for RegionCtxt<'a, 'gcx, 'tcx> {
impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
// (..) FIXME(#3238) should use visit_pat, not visit_arm/visit_local,
// However, right now we run into an issue whereby some free
// regions are not properly related if they appear within the
@ -478,14 +480,18 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for RegionCtxt<'a, 'gcx, 'tcx> {
// hierarchy, and in particular the relationships between free
// regions, until regionck, as described in #3238.
fn visit_fn(&mut self, _fk: intravisit::FnKind<'v>, fd: &'v hir::FnDecl,
b: &'v hir::Expr, span: Span, id: ast::NodeId) {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
NestedVisitorMap::OnlyBodies(&self.tcx.map)
}
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)
}
//visit_pat: visit_pat, // (..) see above
fn visit_arm(&mut self, arm: &hir::Arm) {
fn visit_arm(&mut self, arm: &'gcx hir::Arm) {
// see above
for p in &arm.pats {
self.constrain_bindings_in_pat(p);
@ -493,14 +499,14 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for RegionCtxt<'a, 'gcx, 'tcx> {
intravisit::walk_arm(self, arm);
}
fn visit_local(&mut self, l: &hir::Local) {
fn visit_local(&mut self, l: &'gcx hir::Local) {
// see above
self.constrain_bindings_in_pat(&l.pat);
self.link_local(l);
intravisit::walk_local(self, l);
}
fn visit_expr(&mut self, expr: &hir::Expr) {
fn visit_expr(&mut self, expr: &'gcx hir::Expr) {
debug!("regionck::visit_expr(e={:?}, repeating_scope={})",
expr, self.repeating_scope);
@ -737,8 +743,8 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for RegionCtxt<'a, 'gcx, 'tcx> {
intravisit::walk_expr(self, expr);
}
hir::ExprClosure(.., ref body, _) => {
self.check_expr_fn_block(expr, &body);
hir::ExprClosure(.., body_id, _) => {
self.check_expr_fn_block(expr, body_id);
}
hir::ExprLoop(ref body, _, _) => {
@ -823,9 +829,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
}
fn check_expr_fn_block(&mut self,
expr: &hir::Expr,
body: &hir::Expr) {
let repeating_scope = self.set_repeating_scope(body.id);
expr: &'gcx hir::Expr,
body_id: hir::ExprId) {
let repeating_scope = self.set_repeating_scope(body_id.node_id());
intravisit::walk_expr(self, expr);
self.set_repeating_scope(repeating_scope);
}

View file

@ -50,14 +50,14 @@ use rustc::infer::UpvarRegion;
use syntax::ast;
use syntax_pos::Span;
use rustc::hir;
use rustc::hir::intravisit::{self, Visitor};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::util::nodemap::NodeMap;
///////////////////////////////////////////////////////////////////////////
// PUBLIC ENTRY POINTS
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
pub fn closure_analyze(&self, body: &hir::Expr) {
pub fn closure_analyze(&self, body: &'gcx hir::Expr) {
let mut seed = SeedBorrowKind::new(self);
seed.visit_expr(body);
@ -77,11 +77,15 @@ struct SeedBorrowKind<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
temp_closure_kinds: NodeMap<ty::ClosureKind>,
}
impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for SeedBorrowKind<'a, 'gcx, 'tcx> {
fn visit_expr(&mut self, expr: &hir::Expr) {
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)
}
fn visit_expr(&mut self, expr: &'gcx hir::Expr) {
match expr.node {
hir::ExprClosure(cc, _, ref body, _) => {
self.check_closure(expr, cc, &body);
hir::ExprClosure(cc, _, body_id, _) => {
self.check_closure(expr, cc, body_id);
}
_ => { }
@ -99,7 +103,7 @@ impl<'a, 'gcx, 'tcx> SeedBorrowKind<'a, 'gcx, 'tcx> {
fn check_closure(&mut self,
expr: &hir::Expr,
capture_clause: hir::CaptureClause,
_body: &hir::Expr)
_body_id: hir::ExprId)
{
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) {
@ -153,14 +157,15 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
id: ast::NodeId,
span: Span,
decl: &hir::FnDecl,
body: &hir::Expr) {
body_id: hir::ExprId) {
/*!
* 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,
@ -484,11 +489,15 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
}
}
impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for 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)
}
fn visit_fn(&mut self,
fn_kind: intravisit::FnKind<'v>,
decl: &'v hir::FnDecl,
body: &'v hir::Expr,
fn_kind: intravisit::FnKind<'gcx>,
decl: &'gcx hir::FnDecl,
body: hir::ExprId,
span: Span,
id: ast::NodeId)
{

View file

@ -23,7 +23,7 @@ use syntax::ast;
use syntax_pos::Span;
use errors::DiagnosticBuilder;
use rustc::hir::intravisit::{self, Visitor};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir;
pub struct CheckTypeWellFormedVisitor<'ccx, 'tcx:'ccx> {
@ -127,8 +127,8 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
}
}
}
hir::ItemFn(.., ref body) => {
self.check_item_fn(item, body);
hir::ItemFn(.., body_id) => {
self.check_item_fn(item, body_id);
}
hir::ItemStatic(..) => {
self.check_item_type(item);
@ -347,7 +347,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
fn check_item_fn(&mut self,
item: &hir::Item,
body: &hir::Expr)
body_id: hir::ExprId)
{
self.for_item(item).with_fcx(|fcx, this| {
let free_substs = &fcx.parameter_environment.free_substs;
@ -364,7 +364,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);
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
@ -609,6 +609,10 @@ fn reject_shadowing_type_parameters(tcx: TyCtxt, span: Span, def_id: DefId) {
}
impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
NestedVisitorMap::None
}
fn visit_item(&mut self, i: &hir::Item) {
debug!("visit_item: {:?}", i);
self.check_item_well_formed(i);

View file

@ -27,14 +27,14 @@ use syntax::ast;
use syntax_pos::{DUMMY_SP, Span};
use rustc::hir::print::pat_to_string;
use rustc::hir::intravisit::{self, Visitor};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
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: &hir::Expr, item_id: ast::NodeId) {
pub fn resolve_type_vars_in_expr(&self, e: &'gcx hir::Expr, item_id: ast::NodeId) {
assert_eq!(self.writeback_errors.get(), false);
let mut wbcx = WritebackCx::new(self);
wbcx.visit_expr(e);
@ -47,8 +47,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
pub fn resolve_type_vars_in_fn(&self,
decl: &hir::FnDecl,
body: &hir::Expr,
decl: &'gcx hir::FnDecl,
body: &'gcx hir::Expr,
item_id: ast::NodeId) {
assert_eq!(self.writeback_errors.get(), false);
let mut wbcx = WritebackCx::new(self);
@ -186,8 +186,12 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
// below. In general, a function is made into a `visitor` if it must
// traffic in node-ids or update tables in the type context etc.
impl<'cx, 'gcx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'gcx, 'tcx> {
fn visit_stmt(&mut self, s: &hir::Stmt) {
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)
}
fn visit_stmt(&mut self, s: &'gcx hir::Stmt) {
if self.fcx.writeback_errors.get() {
return;
}
@ -196,7 +200,7 @@ impl<'cx, 'gcx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'gcx, 'tcx> {
intravisit::walk_stmt(self, s);
}
fn visit_expr(&mut self, e: &hir::Expr) {
fn visit_expr(&mut self, e: &'gcx hir::Expr) {
if self.fcx.writeback_errors.get() {
return;
}
@ -216,7 +220,7 @@ impl<'cx, 'gcx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'gcx, 'tcx> {
intravisit::walk_expr(self, e);
}
fn visit_block(&mut self, b: &hir::Block) {
fn visit_block(&mut self, b: &'gcx hir::Block) {
if self.fcx.writeback_errors.get() {
return;
}
@ -225,7 +229,7 @@ impl<'cx, 'gcx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'gcx, 'tcx> {
intravisit::walk_block(self, b);
}
fn visit_pat(&mut self, p: &hir::Pat) {
fn visit_pat(&mut self, p: &'gcx hir::Pat) {
if self.fcx.writeback_errors.get() {
return;
}
@ -240,7 +244,7 @@ impl<'cx, 'gcx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'gcx, 'tcx> {
intravisit::walk_pat(self, p);
}
fn visit_local(&mut self, l: &hir::Local) {
fn visit_local(&mut self, l: &'gcx hir::Local) {
if self.fcx.writeback_errors.get() {
return;
}
@ -251,7 +255,7 @@ impl<'cx, 'gcx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'gcx, 'tcx> {
intravisit::walk_local(self, l);
}
fn visit_ty(&mut self, t: &hir::Ty) {
fn visit_ty(&mut self, t: &'gcx hir::Ty) {
match t.node {
hir::TyArray(ref ty, ref count_expr) => {
self.visit_ty(&ty);

View file

@ -385,7 +385,6 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
self.check_item(item);
}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
}
}

View file

@ -83,7 +83,7 @@ use syntax::symbol::{Symbol, keywords};
use syntax_pos::Span;
use rustc::hir::{self, map as hir_map, print as pprust};
use rustc::hir::intravisit::{self, Visitor};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir::def::{Def, CtorKind};
use rustc::hir::def_id::DefId;
@ -128,13 +128,66 @@ struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
ccx: &'a CrateCtxt<'a, 'tcx>
}
impl<'a, 'tcx, 'v> Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &hir::Item) {
convert_item(self.ccx, item);
impl<'a, 'tcx> CollectItemTypesVisitor<'a, 'tcx> {
/// Collect item types is structured into two tasks. The outer
/// task, `CollectItem`, walks the entire content of an item-like
/// thing, including its body. It also spawns an inner task,
/// `CollectItemSig`, which walks only the signature. This inner
/// task is the one that writes the item-type into the various
/// maps. This setup ensures that the item body is never
/// accessible to the task that computes its signature, so that
/// changes to the body don't affect the signature.
///
/// Consider an example function `foo` that also has a closure in its body:
///
/// ```
/// fn foo(<sig>) {
/// ...
/// let bar = || ...; // we'll label this closure as "bar" below
/// }
/// ```
///
/// This results in a dep-graph like so. I've labeled the edges to
/// document where they arise.
///
/// ```
/// [HirBody(foo)] -2--> [CollectItem(foo)] -4-> [ItemSignature(bar)]
/// ^ ^
/// 1 3
/// [Hir(foo)] -----------+-6-> [CollectItemSig(foo)] -5-> [ItemSignature(foo)]
/// ```
///
/// 1. This is added by the `visit_all_item_likes_in_krate`.
/// 2. This is added when we fetch the item body.
/// 3. This is added because `CollectItem` launches `CollectItemSig`.
/// - it is arguably false; if we refactor the `with_task` system;
/// we could get probably rid of it, but it is also harmless enough.
/// 4. This is added by the code in `visit_expr` when we write to `item_types`.
/// 5. This is added by the code in `convert_item` when we write to `item_types`;
/// note that this write occurs inside the `CollectItemSig` task.
/// 6. Added by explicit `read` below
fn with_collect_item_sig<OP>(&self, id: ast::NodeId, op: OP)
where OP: FnOnce()
{
let def_id = self.ccx.tcx.map.local_def_id(id);
self.ccx.tcx.dep_graph.with_task(DepNode::CollectItemSig(def_id), || {
self.ccx.tcx.map.read(id);
op();
});
}
}
impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.ccx.tcx.map)
}
fn visit_item(&mut self, item: &'tcx hir::Item) {
self.with_collect_item_sig(item.id, || convert_item(self.ccx, item));
intravisit::walk_item(self, item);
}
fn visit_expr(&mut self, expr: &hir::Expr) {
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
if let hir::ExprClosure(..) = expr.node {
let def_id = self.ccx.tcx.map.local_def_id(expr.id);
generics_of_def_id(self.ccx, def_id);
@ -143,7 +196,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
intravisit::walk_expr(self, expr);
}
fn visit_ty(&mut self, ty: &hir::Ty) {
fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
if let hir::TyImplTrait(..) = ty.node {
let def_id = self.ccx.tcx.map.local_def_id(ty.id);
generics_of_def_id(self.ccx, def_id);
@ -151,8 +204,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
intravisit::walk_ty(self, ty);
}
fn visit_impl_item(&mut self, impl_item: &hir::ImplItem) {
convert_impl_item(self.ccx, impl_item);
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
self.with_collect_item_sig(impl_item.id, || {
convert_impl_item(self.ccx, impl_item)
});
intravisit::walk_impl_item(self, impl_item);
}
}

View file

@ -489,8 +489,8 @@ impl<'a, 'hir> HirCollector<'a, 'hir> {
}
impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> {
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'hir>> {
Some(self.map)
fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'hir> {
intravisit::NestedVisitorMap::All(&self.map)
}
fn visit_item(&mut self, item: &'hir hir::Item) {

View file

@ -23,9 +23,8 @@
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="rpass2")]
// FIXME(#37720) these two should be reused, but data gets entangled across crates
#![rustc_partition_translated(module="struct_point-fn_calls_methods_in_same_impl", cfg="rpass2")]
#![rustc_partition_translated(module="struct_point-fn_calls_methods_in_another_impl", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_same_impl", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_another_impl", cfg="rpass2")]
extern crate point;
@ -33,8 +32,7 @@ extern crate point;
mod fn_calls_methods_in_same_impl {
use point::Point;
// FIXME(#37720) data gets entangled across crates
#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")]
#[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
pub fn check() {
let x = Point { x: 2.0, y: 2.0 };
x.distance_from_origin();
@ -45,8 +43,7 @@ mod fn_calls_methods_in_same_impl {
mod fn_calls_methods_in_another_impl {
use point::Point;
// FIXME(#37720) data gets entangled across crates
#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")]
#[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
pub fn dirty() {
let mut x = Point { x: 2.0, y: 2.0 };
x.translate(3.0, 3.0);

View file

@ -19,9 +19,7 @@
#![rustc_partition_translated(module="struct_point-point", cfg="rpass2")]
// FIXME(#35078) -- this gets recompiled because we don't separate sig from body
#![rustc_partition_translated(module="struct_point-fn_calls_changed_method", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_changed_method", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_another_method", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="rpass2")]
@ -52,8 +50,7 @@ mod point {
mod fn_calls_changed_method {
use point::Point;
// FIXME(#35078) -- this gets recompiled because we don't separate sig from body
#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")]
#[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
pub fn check() {
let p = Point { x: 2.0, y: 2.0 };
p.distance_from_origin();

View file

@ -36,9 +36,11 @@ pub fn change_callee_function() {
}
#[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")]
pub fn change_callee_function() {
callee2(1, 2)
@ -53,9 +55,11 @@ pub fn change_argument_function() {
}
#[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")]
pub fn change_argument_function() {
callee1(1, 3)
@ -70,9 +74,11 @@ mod change_callee_indirectly_function {
#[cfg(not(cfail1))]
use super::callee2 as callee;
#[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")]
pub fn change_callee_indirectly_function() {
callee(1, 2)
@ -94,9 +100,11 @@ pub fn change_callee_method() {
}
#[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")]
pub fn change_callee_method() {
let s = Struct;
@ -113,9 +121,11 @@ pub fn change_argument_method() {
}
#[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")]
pub fn change_argument_method() {
let s = Struct;
@ -132,9 +142,11 @@ pub fn change_ufcs_callee_method() {
}
#[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")]
pub fn change_ufcs_callee_method() {
let s = Struct;
@ -151,9 +163,11 @@ pub fn change_argument_method_ufcs() {
}
#[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")]
pub fn change_argument_method_ufcs() {
let s = Struct;
@ -170,9 +184,11 @@ pub fn change_to_ufcs() {
}
#[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")]
pub fn change_to_ufcs() {
let s = Struct;
@ -192,9 +208,11 @@ mod change_ufcs_callee_indirectly {
#[cfg(not(cfail1))]
use super::Struct2 as Struct;
#[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")]
pub fn change_ufcs_callee_indirectly() {
let s = Struct;

View file

@ -36,9 +36,11 @@ fn change_loop_body() {
}
#[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")]
fn change_loop_body() {
let mut _x = 0;
@ -61,9 +63,11 @@ fn change_iteration_variable_name() {
}
#[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")]
fn change_iteration_variable_name() {
let mut _x = 0;
@ -86,9 +90,11 @@ fn change_iteration_variable_pattern() {
}
#[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")]
fn change_iteration_variable_pattern() {
let mut _x = 0;
@ -111,9 +117,11 @@ fn change_iterable() {
}
#[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")]
fn change_iterable() {
let mut _x = 0;
@ -135,9 +143,11 @@ fn add_break() {
}
#[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")]
fn add_break() {
let mut _x = 0;
@ -160,9 +170,11 @@ fn add_loop_label() {
}
#[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")]
fn add_loop_label() {
let mut _x = 0;
@ -185,9 +197,11 @@ fn add_loop_label_to_break() {
}
#[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")]
fn add_loop_label_to_break() {
let mut _x = 0;
@ -212,9 +226,11 @@ fn change_break_label() {
}
#[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")]
fn change_break_label() {
let mut _x = 0;
@ -239,9 +255,11 @@ fn add_loop_label_to_continue() {
}
#[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")]
fn add_loop_label_to_continue() {
let mut _x = 0;
@ -266,9 +284,11 @@ fn change_continue_label() {
}
#[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")]
fn change_continue_label() {
let mut _x = 0;
@ -293,9 +313,11 @@ fn change_continue_to_break() {
}
#[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")]
fn change_continue_to_break() {
let mut _x = 0;

View file

@ -36,9 +36,11 @@ pub fn change_condition(x: bool) -> u32 {
}
#[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")]
pub fn change_condition(x: bool) -> u32 {
if !x {
@ -59,9 +61,11 @@ pub fn change_then_branch(x: bool) -> u32 {
}
#[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")]
pub fn change_then_branch(x: bool) -> u32 {
if x {
@ -84,9 +88,11 @@ pub fn change_else_branch(x: bool) -> u32 {
}
#[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")]
pub fn change_else_branch(x: bool) -> u32 {
if x {
@ -111,9 +117,11 @@ pub fn add_else_branch(x: bool) -> u32 {
}
#[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")]
pub fn add_else_branch(x: bool) -> u32 {
let mut ret = 1;
@ -139,9 +147,11 @@ pub fn change_condition_if_let(x: Option<u32>) -> u32 {
}
#[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")]
pub fn change_condition_if_let(x: Option<u32>) -> u32 {
if let Some(_) = x {
@ -164,9 +174,11 @@ pub fn change_then_branch_if_let(x: Option<u32>) -> u32 {
}
#[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")]
pub fn change_then_branch_if_let(x: Option<u32>) -> u32 {
if let Some(x) = x {
@ -189,9 +201,11 @@ pub fn change_else_branch_if_let(x: Option<u32>) -> u32 {
}
#[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")]
pub fn change_else_branch_if_let(x: Option<u32>) -> u32 {
if let Some(x) = x {
@ -216,9 +230,11 @@ pub fn add_else_branch_if_let(x: Option<u32>) -> u32 {
}
#[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")]
pub fn add_else_branch_if_let(x: Option<u32>) -> u32 {
let mut ret = 1;

View file

@ -32,9 +32,11 @@ pub fn change_name() {
}
#[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")]
pub fn change_name() {
let _y = 2u64;
@ -49,9 +51,11 @@ pub fn add_type() {
}
#[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")]
pub fn add_type() {
let _x: u32 = 2u32;
@ -66,9 +70,11 @@ pub fn change_type() {
}
#[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")]
pub fn change_type() {
let _x: u8 = 2;
@ -83,9 +89,11 @@ pub fn change_mutability_of_reference_type() {
}
#[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")]
pub fn change_mutability_of_reference_type() {
let _x: &mut u64;
@ -100,9 +108,11 @@ pub fn change_mutability_of_slot() {
}
#[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")]
pub fn change_mutability_of_slot() {
let _x: u64 = 0;
@ -117,9 +127,11 @@ pub fn change_simple_binding_to_pattern() {
}
#[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")]
pub fn change_simple_binding_to_pattern() {
let (_a, _b) = (0u8, 'x');
@ -134,9 +146,11 @@ pub fn change_name_in_pattern() {
}
#[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")]
pub fn change_name_in_pattern() {
let (_a, _c) = (1u8, 'y');
@ -151,9 +165,11 @@ pub fn add_ref_in_pattern() {
}
#[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")]
pub fn add_ref_in_pattern() {
let (ref _a, _b) = (1u8, 'y');
@ -168,9 +184,11 @@ pub fn add_amp_in_pattern() {
}
#[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")]
pub fn add_amp_in_pattern() {
let (&_a, _b) = (&1u8, 'y');
@ -185,9 +203,11 @@ pub fn change_mutability_of_binding_in_pattern() {
}
#[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")]
pub fn change_mutability_of_binding_in_pattern() {
let (mut _a, _b) = (99u8, 'q');
@ -202,9 +222,11 @@ pub fn add_initializer() {
}
#[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")]
pub fn add_initializer() {
let _x: i16 = 3i16;
@ -219,9 +241,11 @@ pub fn change_initializer() {
}
#[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")]
pub fn change_initializer() {
let _x = 5u16;

View file

@ -36,9 +36,11 @@ fn change_loop_body() {
}
#[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")]
fn change_loop_body() {
let mut _x = 0;
@ -60,9 +62,11 @@ fn add_break() {
}
#[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")]
fn add_break() {
let mut _x = 0;
@ -85,9 +89,11 @@ fn add_loop_label() {
}
#[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")]
fn add_loop_label() {
let mut _x = 0;
@ -110,9 +116,11 @@ fn add_loop_label_to_break() {
}
#[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")]
fn add_loop_label_to_break() {
let mut _x = 0;
@ -137,9 +145,11 @@ fn change_break_label() {
}
#[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")]
fn change_break_label() {
let mut _x = 0;
@ -164,9 +174,11 @@ fn add_loop_label_to_continue() {
}
#[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")]
fn add_loop_label_to_continue() {
let mut _x = 0;
@ -191,9 +203,11 @@ fn change_continue_label() {
}
#[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")]
fn change_continue_label() {
let mut _x = 0;
@ -218,9 +232,11 @@ fn change_continue_to_break() {
}
#[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")]
fn change_continue_to_break() {
let mut _x = 0;

View file

@ -36,9 +36,11 @@ pub fn add_arm(x: u32) -> u32 {
}
#[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")]
pub fn add_arm(x: u32) -> u32 {
match x {
@ -62,9 +64,11 @@ pub fn change_order_of_arms(x: u32) -> u32 {
}
#[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")]
pub fn change_order_of_arms(x: u32) -> u32 {
match x {
@ -87,9 +91,11 @@ pub fn add_guard_clause(x: u32, y: bool) -> u32 {
}
#[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")]
pub fn add_guard_clause(x: u32, y: bool) -> u32 {
match x {
@ -112,9 +118,11 @@ pub fn change_guard_clause(x: u32, y: bool) -> u32 {
}
#[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")]
pub fn change_guard_clause(x: u32, y: bool) -> u32 {
match x {
@ -137,9 +145,11 @@ pub fn add_at_binding(x: u32) -> u32 {
}
#[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")]
pub fn add_at_binding(x: u32) -> u32 {
match x {
@ -162,9 +172,11 @@ pub fn change_name_of_at_binding(x: u32) -> u32 {
}
#[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")]
pub fn change_name_of_at_binding(x: u32) -> u32 {
match x {
@ -186,9 +198,11 @@ pub fn change_simple_name_to_pattern(x: u32) -> u32 {
}
#[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")]
pub fn change_simple_name_to_pattern(x: u32) -> u32 {
match (x, x & 1) {
@ -210,9 +224,11 @@ pub fn change_name_in_pattern(x: u32) -> u32 {
}
#[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")]
pub fn change_name_in_pattern(x: u32) -> u32 {
match (x, x & 1) {
@ -234,9 +250,11 @@ pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
}
#[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")]
pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
match (x, x & 1) {
@ -257,9 +275,11 @@ pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 {
}
#[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")]
pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 {
match (x, x & 1) {
@ -280,9 +300,11 @@ pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 {
}
#[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")]
pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 {
match (&x, x & 1) {
@ -304,9 +326,11 @@ pub fn change_rhs_of_arm(x: u32) -> u32 {
}
#[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")]
pub fn change_rhs_of_arm(x: u32) -> u32 {
match x {
@ -329,9 +353,11 @@ pub fn add_alternative_to_arm(x: u32) -> u32 {
}
#[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")]
pub fn add_alternative_to_arm(x: u32) -> u32 {
match x {

View file

@ -34,9 +34,11 @@ pub fn indexing(slice: &[u8]) -> u8 {
}
#[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")]
pub fn indexing(slice: &[u8]) -> u8 {
slice[100]
@ -50,9 +52,11 @@ pub fn arithmetic_overflow_plus(val: i32) -> i32 {
}
#[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")]
pub fn arithmetic_overflow_plus(val: i32) -> i32 {
val + 1
@ -66,9 +70,11 @@ pub fn arithmetic_overflow_minus(val: i32) -> i32 {
}
#[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")]
pub fn arithmetic_overflow_minus(val: i32) -> i32 {
val - 1
@ -82,9 +88,11 @@ pub fn arithmetic_overflow_mult(val: i32) -> i32 {
}
#[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")]
pub fn arithmetic_overflow_mult(val: i32) -> i32 {
val * 2
@ -98,9 +106,11 @@ pub fn arithmetic_overflow_negation(val: i32) -> i32 {
}
#[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")]
pub fn arithmetic_overflow_negation(val: i32) -> i32 {
-val
@ -114,9 +124,11 @@ pub fn division_by_zero(val: i32) -> i32 {
}
#[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")]
pub fn division_by_zero(val: i32) -> i32 {
2 / val
@ -129,9 +141,11 @@ pub fn mod_by_zero(val: i32) -> i32 {
}
#[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")]
pub fn mod_by_zero(val: i32) -> i32 {
2 % val
@ -150,6 +164,8 @@ pub fn bitwise(val: i32) -> i32 {
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn bitwise(val: i32) -> i32 {
@ -166,6 +182,8 @@ pub fn logical(val1: bool, val2: bool, val3: bool) -> bool {
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn logical(val1: bool, val2: bool, val3: bool) -> bool {

View file

@ -41,9 +41,11 @@ pub fn indexing(slice: &[u8]) -> u8 {
}
#[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")]
pub fn indexing(slice: &[u8]) -> u8 {
slice[100]
@ -58,9 +60,11 @@ pub fn arithmetic_overflow_plus_inherit(val: i32) -> i32 {
}
#[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")]
#[rustc_inherit_overflow_checks]
pub fn arithmetic_overflow_plus_inherit(val: i32) -> i32 {
@ -76,9 +80,11 @@ pub fn arithmetic_overflow_minus_inherit(val: i32) -> i32 {
}
#[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")]
#[rustc_inherit_overflow_checks]
pub fn arithmetic_overflow_minus_inherit(val: i32) -> i32 {
@ -94,9 +100,11 @@ pub fn arithmetic_overflow_mult_inherit(val: i32) -> i32 {
}
#[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")]
#[rustc_inherit_overflow_checks]
pub fn arithmetic_overflow_mult_inherit(val: i32) -> i32 {
@ -112,9 +120,11 @@ pub fn arithmetic_overflow_negation_inherit(val: i32) -> i32 {
}
#[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")]
#[rustc_inherit_overflow_checks]
pub fn arithmetic_overflow_negation_inherit(val: i32) -> i32 {
@ -129,9 +139,11 @@ pub fn division_by_zero(val: i32) -> i32 {
}
#[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")]
pub fn division_by_zero(val: i32) -> i32 {
2 / val
@ -144,9 +156,11 @@ pub fn mod_by_zero(val: i32) -> i32 {
}
#[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")]
pub fn mod_by_zero(val: i32) -> i32 {
2 % val
@ -165,6 +179,8 @@ pub fn bitwise(val: i32) -> i32 {
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn bitwise(val: i32) -> i32 {
@ -181,6 +197,8 @@ pub fn logical(val1: bool, val2: bool, val3: bool) -> bool {
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn logical(val1: bool, val2: bool, val3: bool) -> bool {
@ -196,6 +214,8 @@ pub fn arithmetic_overflow_plus(val: i32) -> i32 {
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn arithmetic_overflow_plus(val: i32) -> i32 {
@ -212,6 +232,8 @@ pub fn arithmetic_overflow_minus(val: i32) -> i32 {
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn arithmetic_overflow_minus(val: i32) -> i32 {
@ -228,6 +250,8 @@ pub fn arithmetic_overflow_mult(val: i32) -> i32 {
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn arithmetic_overflow_mult(val: i32) -> i32 {
@ -244,6 +268,8 @@ pub fn arithmetic_overflow_negation(val: i32) -> i32 {
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn arithmetic_overflow_negation(val: i32) -> i32 {

View file

@ -42,9 +42,11 @@ fn change_field_value_regular_struct() -> RegularStruct {
}
#[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")]
fn change_field_value_regular_struct() -> RegularStruct {
RegularStruct {
@ -67,9 +69,11 @@ fn change_field_order_regular_struct() -> RegularStruct {
}
#[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")]
fn change_field_order_regular_struct() -> RegularStruct {
RegularStruct {
@ -97,9 +101,11 @@ fn add_field_regular_struct() -> RegularStruct {
}
#[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")]
fn add_field_regular_struct() -> RegularStruct {
let struct1 = RegularStruct {
@ -134,9 +140,11 @@ fn change_field_label_regular_struct() -> RegularStruct {
}
#[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")]
fn change_field_label_regular_struct() -> RegularStruct {
let struct1 = RegularStruct {
@ -171,9 +179,11 @@ fn change_constructor_path_regular_struct() {
}
#[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")]
fn change_constructor_path_regular_struct() {
let _ = RegularStruct2 {
@ -212,9 +222,11 @@ fn change_field_value_tuple_struct() -> TupleStruct {
}
#[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")]
fn change_field_value_tuple_struct() -> TupleStruct {
TupleStruct(0, 1, 3)
@ -231,9 +243,11 @@ fn change_constructor_path_tuple_struct() {
}
#[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")]
fn change_constructor_path_tuple_struct() {
let _ = TupleStruct2(0, 1, 2);

View file

@ -32,9 +32,11 @@ pub fn const_negation() -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn const_negation() -> i32 {
-1
@ -49,9 +51,11 @@ pub fn const_bitwise_not() -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn const_bitwise_not() -> i32 {
!99
@ -66,9 +70,11 @@ pub fn var_negation(x: i32, y: i32) -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn var_negation(x: i32, y: i32) -> i32 {
-y
@ -83,9 +89,11 @@ pub fn var_bitwise_not(x: i32, y: i32) -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn var_bitwise_not(x: i32, y: i32) -> i32 {
!y
@ -100,9 +108,11 @@ pub fn var_deref(x: &i32, y: &i32) -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn var_deref(x: &i32, y: &i32) -> i32 {
*y
@ -117,9 +127,11 @@ pub fn first_const_add() -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn first_const_add() -> i32 {
2 + 3
@ -134,9 +146,11 @@ pub fn second_const_add() -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn second_const_add() -> i32 {
1 + 3
@ -151,9 +165,11 @@ pub fn first_var_add(a: i32, b: i32) -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn first_var_add(a: i32, b: i32) -> i32 {
b + 2
@ -168,9 +184,11 @@ pub fn second_var_add(a: i32, b: i32) -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn second_var_add(a: i32, b: i32) -> i32 {
1 + b
@ -185,9 +203,11 @@ pub fn plus_to_minus(a: i32) -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn plus_to_minus(a: i32) -> i32 {
1 - a
@ -202,9 +222,11 @@ pub fn plus_to_mult(a: i32) -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn plus_to_mult(a: i32) -> i32 {
1 * a
@ -219,9 +241,11 @@ pub fn plus_to_div(a: i32) -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn plus_to_div(a: i32) -> i32 {
1 / a
@ -236,9 +260,11 @@ pub fn plus_to_mod(a: i32) -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn plus_to_mod(a: i32) -> i32 {
1 % a
@ -253,9 +279,11 @@ pub fn and_to_or(a: bool, b: bool) -> bool {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn and_to_or(a: bool, b: bool) -> bool {
a || b
@ -270,9 +298,11 @@ pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 {
1 | a
@ -287,9 +317,11 @@ pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 {
1 ^ a
@ -304,9 +336,11 @@ pub fn bitwise_and_to_lshift(a: i32) -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn bitwise_and_to_lshift(a: i32) -> i32 {
a << 1
@ -321,9 +355,11 @@ pub fn bitwise_and_to_rshift(a: i32) -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn bitwise_and_to_rshift(a: i32) -> i32 {
a >> 1
@ -338,9 +374,11 @@ pub fn eq_to_uneq(a: i32) -> bool {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn eq_to_uneq(a: i32) -> bool {
a != 1
@ -355,9 +393,11 @@ pub fn eq_to_lt(a: i32) -> bool {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn eq_to_lt(a: i32) -> bool {
a < 1
@ -372,9 +412,11 @@ pub fn eq_to_gt(a: i32) -> bool {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn eq_to_gt(a: i32) -> bool {
a > 1
@ -389,9 +431,11 @@ pub fn eq_to_le(a: i32) -> bool {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn eq_to_le(a: i32) -> bool {
a <= 1
@ -406,9 +450,11 @@ pub fn eq_to_ge(a: i32) -> bool {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn eq_to_ge(a: i32) -> bool {
a >= 1
@ -425,9 +471,11 @@ pub fn type_cast(a: u8) -> u64 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn type_cast(a: u8) -> u64 {
let b = a as u32;
@ -444,9 +492,11 @@ pub fn value_cast(a: u32) -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn value_cast(a: u32) -> i32 {
2 as i32
@ -464,9 +514,11 @@ pub fn lvalue() -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn lvalue() -> i32 {
let mut x = 10;
@ -486,9 +538,11 @@ pub fn rvalue() -> i32 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn rvalue() -> i32 {
let mut x = 10;
@ -505,9 +559,11 @@ pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 {
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfails2")]
#[rustc_clean(label="Hir", cfg="cfails3")]
#[rustc_metadata_dirty(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_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 {
s[j]

View file

@ -36,9 +36,11 @@ fn change_loop_body() {
}
#[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")]
fn change_loop_body() {
let mut _x = 0;
@ -61,9 +63,11 @@ fn change_loop_condition() {
}
#[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")]
fn change_loop_condition() {
let mut _x = 0;
@ -85,9 +89,11 @@ fn add_break() {
}
#[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")]
fn add_break() {
let mut _x = 0;
@ -110,9 +116,11 @@ fn add_loop_label() {
}
#[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")]
fn add_loop_label() {
let mut _x = 0;
@ -135,9 +143,11 @@ fn add_loop_label_to_break() {
}
#[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")]
fn add_loop_label_to_break() {
let mut _x = 0;
@ -162,9 +172,11 @@ fn change_break_label() {
}
#[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")]
fn change_break_label() {
let mut _x = 0;
@ -189,9 +201,11 @@ fn add_loop_label_to_continue() {
}
#[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")]
fn add_loop_label_to_continue() {
let mut _x = 0;
@ -216,9 +230,11 @@ fn change_continue_label() {
}
#[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")]
fn change_continue_label() {
let mut _x = 0;
@ -243,9 +259,11 @@ fn change_continue_to_break() {
}
#[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")]
fn change_continue_to_break() {
let mut _x = 0;

View file

@ -36,9 +36,11 @@ fn change_loop_body() {
}
#[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")]
fn change_loop_body() {
let mut _x = 0;
@ -61,9 +63,11 @@ fn change_loop_condition() {
}
#[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")]
fn change_loop_condition() {
let mut _x = 0;
@ -85,9 +89,11 @@ fn add_break() {
}
#[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")]
fn add_break() {
let mut _x = 0;
@ -110,9 +116,11 @@ fn add_loop_label() {
}
#[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")]
fn add_loop_label() {
let mut _x = 0;
@ -135,9 +143,11 @@ fn add_loop_label_to_break() {
}
#[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")]
fn add_loop_label_to_break() {
let mut _x = 0;
@ -162,9 +172,11 @@ fn change_break_label() {
}
#[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")]
fn change_break_label() {
let mut _x = 0;
@ -189,9 +201,11 @@ fn add_loop_label_to_continue() {
}
#[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")]
fn add_loop_label_to_continue() {
let mut _x = 0;
@ -216,9 +230,11 @@ fn change_continue_label() {
}
#[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")]
fn change_continue_label() {
let mut _x = 0;
@ -243,9 +259,11 @@ fn change_continue_to_break() {
}
#[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")]
fn change_continue_to_break() {
let mut _x = 0;

View file

@ -18,12 +18,12 @@ fn main() { }
mod x {
#[cfg(rpass1)]
pub fn x() -> i32 {
pub fn xxxx() -> i32 {
1
}
#[cfg(rpass2)]
pub fn x() -> i32 {
pub fn xxxx() -> i32 {
2
}
}
@ -31,9 +31,9 @@ mod x {
mod y {
use x;
#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")]
pub fn y() {
x::x();
#[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
pub fn yyyy() {
x::xxxx();
}
}
@ -42,6 +42,6 @@ mod z {
#[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
pub fn z() {
y::y();
y::yyyy();
}
}

View file

@ -46,12 +46,14 @@ mod mod3 {
mod mod3 {
use Trait2;
#[rustc_dirty(label="Hir", cfg="rpass2")]
#[rustc_clean(label="Hir", cfg="rpass2")]
#[rustc_dirty(label="HirBody", cfg="rpass2")]
fn bar() {
().method();
}
#[rustc_clean(label="Hir", cfg="rpass2")]
#[rustc_clean(label="HirBody", cfg="rpass2")]
fn baz() {
22; // no method call, traits in scope don't matter
}

View file

@ -23,11 +23,14 @@ fn foo() {
#[cfg(rpass2)]
#[rustc_clean(label="Hir", cfg="rpass2")]
#[rustc_clean(label="HirBody", cfg="rpass2")]
fn foo() {
#[rustc_clean(label="Hir", cfg="rpass2")]
#[rustc_clean(label="HirBody", cfg="rpass2")]
fn baz() { } // order is different...
#[rustc_clean(label="Hir", cfg="rpass2")]
#[rustc_clean(label="HirBody", cfg="rpass2")]
fn bar() { } // but that doesn't matter.
fn bap() { } // neither does adding a new item

View file

@ -45,11 +45,13 @@ mod mod3 {
use test;
#[rustc_clean(label="Hir", cfg="rpass2")]
#[rustc_clean(label="HirBody", cfg="rpass2")]
fn in_expr() {
Foo(0);
}
#[rustc_clean(label="Hir", cfg="rpass2")]
#[rustc_clean(label="HirBody", cfg="rpass2")]
fn in_type() {
test::<Foo>();
}
@ -60,12 +62,14 @@ mod mod3 {
use test;
use mod2::Foo; // <-- This changed!
#[rustc_dirty(label="Hir", cfg="rpass3")]
#[rustc_clean(label="Hir", cfg="rpass3")]
#[rustc_dirty(label="HirBody", cfg="rpass3")]
fn in_expr() {
Foo(0);
}
#[rustc_dirty(label="Hir", cfg="rpass3")]
#[rustc_clean(label="Hir", cfg="rpass3")]
#[rustc_dirty(label="HirBody", cfg="rpass3")]
fn in_type() {
test::<Foo>();
}

View file

@ -18,16 +18,19 @@
#![feature(rustc_attrs)]
#[rustc_clean(label="Hir", cfg="rpass2")]
#[rustc_clean(label="HirBody", cfg="rpass2")]
fn line_same() {
let _ = line!();
}
#[rustc_clean(label="Hir", cfg="rpass2")]
#[rustc_clean(label="HirBody", cfg="rpass2")]
fn col_same() {
let _ = column!();
}
#[rustc_clean(label="Hir", cfg="rpass2")]
#[rustc_clean(label="HirBody", cfg="rpass2")]
fn file_same() {
let _ = file!();
}
@ -38,7 +41,8 @@ fn line_different() {
}
#[cfg(rpass2)]
#[rustc_dirty(label="Hir", cfg="rpass2")]
#[rustc_clean(label="Hir", cfg="rpass2")]
#[rustc_dirty(label="HirBody", cfg="rpass2")]
fn line_different() {
let _ = line!();
}
@ -49,7 +53,8 @@ fn col_different() {
}
#[cfg(rpass2)]
#[rustc_dirty(label="Hir", cfg="rpass2")]
#[rustc_clean(label="Hir", cfg="rpass2")]
#[rustc_dirty(label="HirBody", cfg="rpass2")]
fn col_different() {
let _ = column!();
}

View file

@ -22,4 +22,5 @@ pub fn main() {}
#[cfg(rpass2)]
#[rustc_clean(label="Hir", cfg="rpass2")]
#[rustc_clean(label="HirBody", cfg="rpass2")]
pub fn main() {}

View file

@ -22,4 +22,5 @@ pub fn main() {}
#[cfg(rpass2)]
#[rustc_dirty(label="Hir", cfg="rpass2")]
#[rustc_dirty(label="HirBody", cfg="rpass2")]
pub fn main() {}

View file

@ -0,0 +1,30 @@
// Copyright 2015 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.
#![feature(associated_consts)]
trait Foo {
const NUM: usize;
}
impl Foo for i32 {
const NUM: usize = 1;
}
const FOO: usize = <i32 as Foo>::NUM;
fn main() {
assert_eq!(1, FOO);
match 1 {
<i32 as Foo>::NUM => {},
_ => assert!(false)
}
}

View file

@ -0,0 +1,38 @@
// Copyright 2015 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.
// aux-build:associated-const-cc-lib.rs
#![feature(associated_consts)]
extern crate associated_const_cc_lib as foolib;
pub struct LocalFoo;
impl foolib::Foo for LocalFoo {
const BAR: usize = 1;
}
const FOO_1: usize = <foolib::FooNoDefault as foolib::Foo>::BAR;
const FOO_2: usize = <LocalFoo as foolib::Foo>::BAR;
const FOO_3: usize = foolib::InherentBar::BAR;
fn main() {
assert_eq!(0, FOO_1);
assert_eq!(1, FOO_2);
assert_eq!(3, FOO_3);
match 0 {
<foolib::FooNoDefault as foolib::Foo>::BAR => {},
<LocalFoo as foolib::Foo>::BAR => assert!(false),
foolib::InherentBar::BAR => assert!(false),
_ => assert!(false)
}
}