rustc: separate TraitItem from their parent Item, just like ImplItem.

This commit is contained in:
Eduard-Mihai Burtescu 2016-12-04 04:21:06 +02:00
parent 6ebb6fdbee
commit 864928297d
57 changed files with 601 additions and 298 deletions

View file

@ -45,6 +45,17 @@ pub fn visit_all_item_likes_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>
debug!("Ended task {:?}", task_id);
}
fn visit_trait_item(&mut self, i: &'tcx hir::TraitItem) {
let trait_item_def_id = self.tcx.map.local_def_id(i.id);
let task_id = (self.dep_node_fn)(trait_item_def_id);
let _task = self.tcx.dep_graph.in_task(task_id.clone());
debug!("Started task {:?}", task_id);
assert!(!self.tcx.map.is_inlined_def_id(trait_item_def_id));
self.tcx.dep_graph.read(DepNode::Hir(trait_item_def_id));
self.visitor.visit_trait_item(i);
debug!("Ended task {:?}", task_id);
}
fn visit_impl_item(&mut self, i: &'tcx hir::ImplItem) {
let impl_item_def_id = self.tcx.map.local_def_id(i.id);
let task_id = (self.dep_node_fn)(impl_item_def_id);

View file

@ -177,6 +177,17 @@ pub trait Visitor<'v> : Sized {
}
}
/// Like `visit_nested_item()`, but for trait items. See
/// `visit_nested_item()` for advice on when to override this
/// method.
#[allow(unused_variables)]
fn visit_nested_trait_item(&mut self, id: TraitItemId) {
let opt_item = self.nested_visit_map().inter().map(|map| map.trait_item(id));
if let Some(item) = opt_item {
self.visit_trait_item(item);
}
}
/// Like `visit_nested_item()`, but for impl items. See
/// `visit_nested_item()` for advice on when to override this
/// method.
@ -273,6 +284,9 @@ pub trait Visitor<'v> : Sized {
fn visit_trait_item(&mut self, ti: &'v TraitItem) {
walk_trait_item(self, ti)
}
fn visit_trait_item_ref(&mut self, ii: &'v TraitItemRef) {
walk_trait_item_ref(self, ii)
}
fn visit_impl_item(&mut self, ii: &'v ImplItem) {
walk_impl_item(self, ii)
}
@ -469,9 +483,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_generics(type_parameters);
walk_list!(visitor, visit_trait_ref, opt_trait_reference);
visitor.visit_ty(typ);
for impl_item_ref in impl_item_refs {
visitor.visit_impl_item_ref(impl_item_ref);
}
walk_list!(visitor, visit_impl_item_ref, impl_item_refs);
}
ItemStruct(ref struct_definition, ref generics) |
ItemUnion(ref struct_definition, ref generics) => {
@ -479,11 +491,11 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_id(item.id);
visitor.visit_variant_data(struct_definition, item.name, generics, item.id, item.span);
}
ItemTrait(_, ref generics, ref bounds, ref methods) => {
ItemTrait(_, ref generics, ref bounds, ref trait_item_refs) => {
visitor.visit_id(item.id);
visitor.visit_generics(generics);
walk_list!(visitor, visit_ty_param_bound, bounds);
walk_list!(visitor, visit_trait_item, methods);
walk_list!(visitor, visit_trait_item_ref, trait_item_refs);
}
}
walk_list!(visitor, visit_attribute, &item.attrs);
@ -788,17 +800,17 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
visitor.visit_name(trait_item.span, trait_item.name);
walk_list!(visitor, visit_attribute, &trait_item.attrs);
match trait_item.node {
ConstTraitItem(ref ty, ref default) => {
TraitItemKind::Const(ref ty, ref default) => {
visitor.visit_id(trait_item.id);
visitor.visit_ty(ty);
walk_list!(visitor, visit_expr, default);
}
MethodTraitItem(ref sig, None) => {
TraitItemKind::Method(ref sig, None) => {
visitor.visit_id(trait_item.id);
visitor.visit_generics(&sig.generics);
visitor.visit_fn_decl(&sig.decl);
}
MethodTraitItem(ref sig, Some(body_id)) => {
TraitItemKind::Method(ref sig, Some(body_id)) => {
visitor.visit_fn(FnKind::Method(trait_item.name,
sig,
None,
@ -808,7 +820,7 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
trait_item.span,
trait_item.id);
}
TypeTraitItem(ref bounds, ref default) => {
TraitItemKind::Type(ref bounds, ref default) => {
visitor.visit_id(trait_item.id);
walk_list!(visitor, visit_ty_param_bound, bounds);
walk_list!(visitor, visit_ty, default);
@ -816,6 +828,15 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
}
}
pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_item_ref: &'v TraitItemRef) {
// NB: Deliberately force a compilation error if/when new fields are added.
let TraitItemRef { id, name, ref kind, span, ref defaultness } = *trait_item_ref;
visitor.visit_nested_trait_item(id);
visitor.visit_name(span, name);
visitor.visit_associated_item_kind(kind);
visitor.visit_defaultness(defaultness);
}
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
// NB: Deliberately force a compilation error if/when new fields are added.
let ImplItem { id: _, name, ref vis, ref defaultness, ref attrs, ref node, span } = *impl_item;

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use super::{Item, ImplItem};
use super::{Item, ImplItem, TraitItem};
use super::intravisit::Visitor;
/// The "item-like visitor" visitor defines only the top-level methods
@ -58,6 +58,7 @@ use super::intravisit::Visitor;
/// needed.
pub trait ItemLikeVisitor<'hir> {
fn visit_item(&mut self, item: &'hir Item);
fn visit_trait_item(&mut self, trait_item: &'hir TraitItem);
fn visit_impl_item(&mut self, impl_item: &'hir ImplItem);
}
@ -80,6 +81,10 @@ impl<'v, 'hir, V> ItemLikeVisitor<'hir> for DeepVisitor<'v, V>
self.visitor.visit_item(item);
}
fn visit_trait_item(&mut self, trait_item: &'hir TraitItem) {
self.visitor.visit_trait_item(trait_item);
}
fn visit_impl_item(&mut self, impl_item: &'hir ImplItem) {
self.visitor.visit_impl_item(impl_item);
}

View file

@ -51,7 +51,6 @@ use rustc_data_structures::fnv::FnvHashMap;
use std::collections::BTreeMap;
use std::iter;
use std::mem;
use syntax::ast::*;
use syntax::errors;
@ -77,6 +76,7 @@ pub struct LoweringContext<'a> {
/// The items being lowered are collected here.
items: BTreeMap<NodeId, hir::Item>,
trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem>,
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
}
@ -108,6 +108,7 @@ pub fn lower_crate(sess: &Session,
exprs: FnvHashMap(),
resolver: resolver,
items: BTreeMap::new(),
trait_items: BTreeMap::new(),
impl_items: BTreeMap::new(),
}.lower_crate(krate)
}
@ -133,8 +134,9 @@ impl<'a> LoweringContext<'a> {
span: c.span,
exported_macros: exported_macros,
items: self.items,
trait_items: self.trait_items,
impl_items: self.impl_items,
exprs: mem::replace(&mut self.exprs, FnvHashMap()),
exprs: self.exprs,
}
}
@ -150,8 +152,15 @@ impl<'a> LoweringContext<'a> {
visit::walk_item(self, item);
}
fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
let id = hir::TraitItemId { node_id: item.id };
let hir_item = self.lctx.lower_trait_item(item);
self.lctx.trait_items.insert(id, hir_item);
visit::walk_trait_item(self, item);
}
fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
let id = self.lctx.lower_impl_item_ref(item).id;
let id = hir::ImplItemId { node_id: item.id };
let hir_item = self.lctx.lower_impl_item(item);
self.lctx.impl_items.insert(id, hir_item);
visit::walk_impl_item(self, item);
@ -907,7 +916,7 @@ impl<'a> LoweringContext<'a> {
}
ItemKind::Trait(unsafety, ref generics, ref bounds, ref items) => {
let bounds = self.lower_bounds(bounds);
let items = items.iter().map(|item| self.lower_trait_item(item)).collect();
let items = items.iter().map(|item| self.lower_trait_item_ref(item)).collect();
hir::ItemTrait(self.lower_unsafety(unsafety),
self.lower_generics(generics),
bounds,
@ -925,20 +934,20 @@ impl<'a> LoweringContext<'a> {
attrs: this.lower_attrs(&i.attrs),
node: match i.node {
TraitItemKind::Const(ref ty, ref default) => {
hir::ConstTraitItem(this.lower_ty(ty),
default.as_ref().map(|x| P(this.lower_expr(x))))
hir::TraitItemKind::Const(this.lower_ty(ty),
default.as_ref().map(|x| P(this.lower_expr(x))))
}
TraitItemKind::Method(ref sig, ref body) => {
hir::MethodTraitItem(this.lower_method_sig(sig),
body.as_ref().map(|x| {
hir::TraitItemKind::Method(this.lower_method_sig(sig),
body.as_ref().map(|x| {
let body = this.lower_block(x);
let expr = this.expr_block(body, ThinVec::new());
this.record_expr(expr)
}))
}
TraitItemKind::Type(ref bounds, ref default) => {
hir::TypeTraitItem(this.lower_bounds(bounds),
default.as_ref().map(|x| this.lower_ty(x)))
hir::TraitItemKind::Type(this.lower_bounds(bounds),
default.as_ref().map(|x| this.lower_ty(x)))
}
TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
},
@ -947,6 +956,30 @@ impl<'a> LoweringContext<'a> {
})
}
fn lower_trait_item_ref(&mut self, i: &TraitItem) -> hir::TraitItemRef {
let (kind, has_default) = match i.node {
TraitItemKind::Const(_, ref default) => {
(hir::AssociatedItemKind::Const, default.is_some())
}
TraitItemKind::Type(_, ref default) => {
(hir::AssociatedItemKind::Type, default.is_some())
}
TraitItemKind::Method(ref sig, ref default) => {
(hir::AssociatedItemKind::Method {
has_self: sig.decl.has_self(),
}, default.is_some())
}
TraitItemKind::Macro(..) => unimplemented!(),
};
hir::TraitItemRef {
id: hir::TraitItemId { node_id: i.id },
name: i.ident.name,
span: i.span,
defaultness: self.lower_defaultness(Defaultness::Default, has_default),
kind: kind,
}
}
fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
self.with_parent_def(i.id, |this| {
hir::ImplItem {

View file

@ -62,7 +62,7 @@ impl MaybeFnLike for ast::Item {
impl MaybeFnLike for ast::TraitItem {
fn is_fn_like(&self) -> bool {
match self.node { ast::MethodTraitItem(_, Some(_)) => true, _ => false, }
match self.node { ast::TraitItemKind::Method(_, Some(_)) => true, _ => false, }
}
}
@ -252,7 +252,7 @@ impl<'a> FnLikeNode<'a> {
_ => bug!("item FnLikeNode that is not fn-like"),
},
map::NodeTraitItem(ti) => match ti.node {
ast::MethodTraitItem(ref sig, Some(body)) => {
ast::TraitItemKind::Method(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"),

View file

@ -98,6 +98,10 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
}
}
fn visit_nested_trait_item(&mut self, item_id: TraitItemId) {
self.visit_trait_item(self.krate.trait_item(item_id))
}
fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
self.visit_impl_item(self.krate.impl_item(item_id))
}

View file

@ -257,10 +257,20 @@ impl<'ast> Map<'ast> {
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) {
if self.is_item_body(last_id, item) {
return DepNode::HirBody(def_id);
}
}
return DepNode::Hir(def_id);
}
EntryTraitItem(_, item) => {
let def_id = self.local_def_id(id);
assert!(!self.is_inlined_def_id(def_id));
if let Some(last_id) = last_expr {
// The body of the item may have a separate dep node
if self.is_trait_item_body(last_id, item) {
return DepNode::HirBody(def_id);
}
}
@ -280,7 +290,6 @@ impl<'ast> Map<'ast> {
}
EntryForeignItem(p, _) |
EntryTraitItem(p, _) |
EntryVariant(p, _) |
EntryField(p, _) |
EntryStmt(p, _) |
@ -358,18 +367,16 @@ impl<'ast> Map<'ast> {
}
}
fn is_body(&self, node_id: NodeId, item: &Item) -> bool {
fn is_item_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_trait_item_body(&self, node_id: NodeId, item: &TraitItem) -> bool {
match item.node {
TraitItemKind::Method(_, Some(body)) => body.node_id() == node_id,
_ => false
}
}
@ -436,6 +443,14 @@ impl<'ast> Map<'ast> {
self.forest.krate()
}
pub fn trait_item(&self, id: TraitItemId) -> &'ast TraitItem {
self.read(id.node_id);
// NB: intentionally bypass `self.forest.krate()` so that we
// do not trigger a read of the whole krate here
self.forest.krate.trait_item(id)
}
pub fn impl_item(&self, id: ImplItemId) -> &'ast ImplItem {
self.read(id.node_id);
@ -1045,9 +1060,9 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
}
Some(NodeTraitItem(ti)) => {
let kind = match ti.node {
ConstTraitItem(..) => "assoc constant",
MethodTraitItem(..) => "trait method",
TypeTraitItem(..) => "assoc type",
TraitItemKind::Const(..) => "assoc constant",
TraitItemKind::Method(..) => "trait method",
TraitItemKind::Type(..) => "assoc type",
};
format!("{} {} in {}{}", kind, ti.name, path_str(), id_str)

View file

@ -22,7 +22,6 @@ pub use self::Item_::*;
pub use self::Mutability::*;
pub use self::PrimTy::*;
pub use self::Stmt_::*;
pub use self::TraitItem_::*;
pub use self::Ty_::*;
pub use self::TyParamBound::*;
pub use self::UnOp::*;
@ -41,7 +40,7 @@ use syntax::abi::Abi;
use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, AsmDialect};
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
use syntax::ptr::P;
use syntax::symbol::{Symbol, keywords};
use syntax::symbol::Symbol;
use syntax::tokenstream::TokenTree;
use syntax::util::ThinVec;
@ -431,6 +430,7 @@ pub struct Crate {
// slightly different results.
pub items: BTreeMap<NodeId, Item>,
pub trait_items: BTreeMap<TraitItemId, TraitItem>,
pub impl_items: BTreeMap<ImplItemId, ImplItem>,
pub exprs: FnvHashMap<ExprId, Expr>,
}
@ -440,6 +440,10 @@ impl Crate {
&self.items[&id]
}
pub fn trait_item(&self, id: TraitItemId) -> &TraitItem {
&self.trait_items[&id]
}
pub fn impl_item(&self, id: ImplItemId) -> &ImplItem {
&self.impl_items[&id]
}
@ -459,6 +463,10 @@ impl Crate {
visitor.visit_item(item);
}
for (_, trait_item) in &self.trait_items {
visitor.visit_trait_item(trait_item);
}
for (_, impl_item) in &self.impl_items {
visitor.visit_impl_item(impl_item);
}
@ -1070,6 +1078,14 @@ pub struct MethodSig {
pub generics: Generics,
}
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the node-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct TraitItemId {
pub node_id: NodeId,
}
/// Represents an item declaration within a trait declaration,
/// possibly including a default implementation. A trait item is
/// either required (meaning it doesn't have an implementation, just a
@ -1079,21 +1095,21 @@ pub struct TraitItem {
pub id: NodeId,
pub name: Name,
pub attrs: HirVec<Attribute>,
pub node: TraitItem_,
pub node: TraitItemKind,
pub span: Span,
}
/// Represents a trait method or associated constant or type
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum TraitItem_ {
pub enum TraitItemKind {
/// An associated constant with an optional value (otherwise `impl`s
/// must contain a value)
ConstTraitItem(P<Ty>, Option<P<Expr>>),
Const(P<Ty>, Option<P<Expr>>),
/// A method with an optional body
MethodTraitItem(MethodSig, Option<ExprId>),
Method(MethodSig, Option<ExprId>),
/// An associated type with (possibly empty) bounds and optional concrete
/// type
TypeTraitItem(TyParamBounds, Option<P<Ty>>),
Type(TyParamBounds, Option<P<Ty>>),
}
// The bodies for items are stored "out of line", in a separate
@ -1234,16 +1250,6 @@ pub struct Arg {
pub id: NodeId,
}
impl Arg {
fn is_self(&self) -> bool {
if let PatKind::Binding(_, _, name, _) = self.pat.node {
name.node == keywords::SelfValue.name()
} else {
false
}
}
}
/// Represents the header (not the body) of a function declaration
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct FnDecl {
@ -1252,12 +1258,6 @@ pub struct FnDecl {
pub variadic: bool,
}
impl FnDecl {
pub fn has_self(&self) -> bool {
self.inputs.get(0).map(Arg::is_self).unwrap_or(false)
}
}
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum Unsafety {
Unsafe,
@ -1548,7 +1548,7 @@ pub enum Item_ {
/// A union definition, e.g. `union Foo<A, B> {x: A, y: B}`
ItemUnion(VariantData, Generics),
/// Represents a Trait Declaration
ItemTrait(Unsafety, Generics, TyParamBounds, HirVec<TraitItem>),
ItemTrait(Unsafety, Generics, TyParamBounds, HirVec<TraitItemRef>),
// Default trait implementations
///
@ -1584,6 +1584,21 @@ impl Item_ {
}
}
/// A reference from an trait to one of its associated items. This
/// contains the item's id, naturally, but also the item's name and
/// some other high-level details (like whether it is an associated
/// type or method, and whether it is public). This allows other
/// passes to find the impl they want without loading the id (which
/// means fewer edges in the incremental compilation graph).
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct TraitItemRef {
pub id: TraitItemId,
pub name: Name,
pub kind: AssociatedItemKind,
pub span: Span,
pub defaultness: Defaultness,
}
/// A reference from an impl to one of its associated items. This
/// contains the item's id, naturally, but also the item's name and
/// some other high-level details (like whether it is an associated

View file

@ -858,7 +858,7 @@ impl<'a> State<'a> {
word(&mut self.s, " ")?;
self.bopen()?;
for trait_item in trait_items {
self.print_trait_item(trait_item)?;
self.print_trait_item_ref(trait_item)?;
}
self.bclose(item.span)?;
}
@ -1008,19 +1008,29 @@ impl<'a> State<'a> {
vis)
}
pub fn print_trait_item_ref(&mut self, item_ref: &hir::TraitItemRef) -> io::Result<()> {
if let Some(krate) = self.krate {
// skip nested items if krate context was not provided
let item = &krate.trait_item(item_ref.id);
self.print_trait_item(item)
} else {
Ok(())
}
}
pub fn print_trait_item(&mut self, ti: &hir::TraitItem) -> io::Result<()> {
self.ann.pre(self, NodeSubItem(ti.id))?;
self.hardbreak_if_not_bol()?;
self.maybe_print_comment(ti.span.lo)?;
self.print_outer_attributes(&ti.attrs)?;
match ti.node {
hir::ConstTraitItem(ref ty, ref default) => {
hir::TraitItemKind::Const(ref ty, ref default) => {
self.print_associated_const(ti.name,
&ty,
default.as_ref().map(|expr| &**expr),
&hir::Inherited)?;
}
hir::MethodTraitItem(ref sig, ref body) => {
hir::TraitItemKind::Method(ref sig, ref body) => {
if body.is_some() {
self.head("")?;
}
@ -1034,7 +1044,7 @@ impl<'a> State<'a> {
word(&mut self.s, ";")?;
}
}
hir::TypeTraitItem(ref bounds, ref default) => {
hir::TraitItemKind::Type(ref bounds, ref default) => {
self.print_associated_type(ti.name,
Some(bounds),
default.as_ref().map(|ty| &**ty))?;

View file

@ -1079,7 +1079,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
},
ast_map::NodeTraitItem(item) => {
match item.node {
hir::MethodTraitItem(ref sig, Some(_)) => {
hir::TraitItemKind::Method(ref sig, Some(_)) => {
Some((&sig.decl,
&sig.generics,
sig.unsafety,

View file

@ -183,9 +183,9 @@ impl<'a> InlinedItemRef<'a> {
_tcx: TyCtxt)
-> InlinedItemRef<'a> {
let (body, args) = match item.node {
hir::ConstTraitItem(_, Some(ref body)) =>
hir::TraitItemKind::Const(_, Some(ref body)) =>
(&**body, Vec::new()),
hir::ConstTraitItem(_, None) => {
hir::TraitItemKind::Const(_, None) => {
bug!("InlinedItemRef::from_trait_item called for const without body")
},
_ => bug!("InlinedItemRef::from_trait_item wrong kind")

View file

@ -328,11 +328,12 @@ impl<'v, 'k> ItemLikeVisitor<'v> for LifeSeeder<'k> {
self.worklist.extend(enum_def.variants.iter()
.map(|variant| variant.node.data.id()));
}
hir::ItemTrait(.., ref trait_items) => {
for trait_item in trait_items {
hir::ItemTrait(.., ref trait_item_refs) => {
for trait_item_ref in trait_item_refs {
let trait_item = self.krate.trait_item(trait_item_ref.id);
match trait_item.node {
hir::ConstTraitItem(_, Some(_)) |
hir::MethodTraitItem(_, Some(_)) => {
hir::TraitItemKind::Const(_, Some(_)) |
hir::TraitItemKind::Method(_, Some(_)) => {
if has_allow_dead_code_or_lang_attr(&trait_item.attrs) {
self.worklist.push(trait_item.id);
}
@ -354,6 +355,10 @@ impl<'v, 'k> ItemLikeVisitor<'v> for LifeSeeder<'k> {
}
}
fn visit_trait_item(&mut self, _item: &hir::TraitItem) {
// ignore: we are handling this in `visit_item` above
}
fn visit_impl_item(&mut self, _item: &hir::ImplItem) {
// ignore: we are handling this in `visit_item` above
}
@ -567,15 +572,15 @@ 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::TraitItemKind::Const(_, Some(ref body)) => {
intravisit::walk_expr(self, body)
}
hir::MethodTraitItem(_, Some(body_id)) => {
hir::TraitItemKind::Method(_, Some(body_id)) => {
self.visit_body(body_id)
}
hir::ConstTraitItem(_, None) |
hir::MethodTraitItem(_, None) |
hir::TypeTraitItem(..) => {}
hir::TraitItemKind::Const(_, None) |
hir::TraitItemKind::Method(_, None) |
hir::TraitItemKind::Type(..) => {}
}
}
}

View file

@ -17,7 +17,7 @@ use syntax::ast::NodeId;
use syntax::attr;
use syntax::entry::EntryPointType;
use syntax_pos::Span;
use hir::{Item, ItemFn, ImplItem};
use hir::{Item, ItemFn, ImplItem, TraitItem};
use hir::itemlikevisit::ItemLikeVisitor;
struct EntryContext<'a, 'tcx: 'a> {
@ -47,6 +47,9 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
find_item(item, self, at_root);
}
fn visit_trait_item(&mut self, _trait_item: &'tcx TraitItem) {
// entry fn is never a trait item
}
fn visit_impl_item(&mut self, _impl_item: &'tcx ImplItem) {
// entry fn is never an impl item

View file

@ -132,7 +132,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ItemVisitor<'a, 'tcx> {
}
fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) {
if let hir::ConstTraitItem(_, Some(ref expr)) = item.node {
if let hir::TraitItemKind::Const(_, Some(ref expr)) = item.node {
self.visit_const(item.id, expr);
} else {
intravisit::walk_trait_item(self, item);

View file

@ -140,6 +140,10 @@ impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> {
}
}
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
// at present, lang items are always items, not trait items
}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
// at present, lang items are always items, not impl items
}

View file

@ -166,9 +166,9 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
}
Some(ast_map::NodeTraitItem(trait_method)) => {
match trait_method.node {
hir::ConstTraitItem(_, ref default) => default.is_some(),
hir::MethodTraitItem(_, ref body) => body.is_some(),
hir::TypeTraitItem(..) => false,
hir::TraitItemKind::Const(_, ref default) => default.is_some(),
hir::TraitItemKind::Method(_, ref body) => body.is_some(),
hir::TraitItemKind::Type(..) => false,
}
}
Some(ast_map::NodeImplItem(impl_item)) => {
@ -274,17 +274,17 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
}
ast_map::NodeTraitItem(trait_method) => {
match trait_method.node {
hir::ConstTraitItem(_, None) |
hir::MethodTraitItem(_, None) => {
hir::TraitItemKind::Const(_, None) |
hir::TraitItemKind::Method(_, None) => {
// Keep going, nothing to get exported
}
hir::ConstTraitItem(_, Some(ref body)) => {
hir::TraitItemKind::Const(_, Some(ref body)) => {
self.visit_expr(body);
}
hir::MethodTraitItem(_, Some(body_id)) => {
hir::TraitItemKind::Method(_, Some(body_id)) => {
self.visit_body(body_id);
}
hir::TypeTraitItem(..) => {}
hir::TraitItemKind::Type(..) => {}
}
}
ast_map::NodeImplItem(impl_item) => {
@ -358,6 +358,8 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a,
}
}
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
// processed in visit_item above
}

View file

@ -266,7 +266,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
// methods in an impl can reuse label names.
let saved = replace(&mut self.labels_in_fn, vec![]);
if let hir::MethodTraitItem(ref sig, None) = trait_item.node {
if let hir::TraitItemKind::Method(ref sig, None) = trait_item.node {
self.visit_early_late(
trait_item.id,
&sig.decl, &sig.generics,

View file

@ -48,7 +48,7 @@ impl<'a, 'tcx> MirSource {
match tcx.map.get(id) {
map::NodeItem(&Item { node: ItemConst(..), .. }) |
map::NodeTraitItem(&TraitItem { node: ConstTraitItem(..), .. }) |
map::NodeTraitItem(&TraitItem { node: TraitItemKind::Const(..), .. }) |
map::NodeImplItem(&ImplItem { node: ImplItemKind::Const(..), .. }) => {
MirSource::Const(id)
}

View file

@ -1212,7 +1212,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
}
Some(ast_map::NodeTraitItem(trait_item)) => {
match trait_item.node {
hir::TypeTraitItem(..) | hir::ConstTraitItem(..) => {
hir::TraitItemKind::Type(..) | hir::TraitItemKind::Const(..) => {
// associated types don't have their own entry (for some reason),
// so for now just grab environment for the trait
let trait_id = tcx.map.get_parent(id);
@ -1221,7 +1221,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
trait_def_id,
tcx.region_maps.item_extent(id))
}
hir::MethodTraitItem(_, ref body) => {
hir::TraitItemKind::Method(_, ref body) => {
// Use call-site for extent (unless this is a
// trait method with no default; then fallback
// to the method id).
@ -2100,10 +2100,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}
hir::ItemTrait(.., ref trait_items) => {
for trait_item in trait_items {
hir::ItemTrait(.., ref trait_item_refs) => {
for trait_item_ref in trait_item_refs {
let assoc_item =
self.associated_item_from_trait_item_ref(parent_def_id, trait_item);
self.associated_item_from_trait_item_ref(parent_def_id, trait_item_ref);
self.associated_items.borrow_mut().insert(assoc_item.def_id, assoc_item);
}
}
@ -2121,28 +2121,22 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
fn associated_item_from_trait_item_ref(self,
parent_def_id: DefId,
trait_item: &hir::TraitItem)
trait_item_ref: &hir::TraitItemRef)
-> AssociatedItem {
let def_id = self.map.local_def_id(trait_item.id);
let (kind, has_self, has_value) = match trait_item.node {
hir::MethodTraitItem(ref sig, ref body) => {
(AssociatedKind::Method, sig.decl.has_self(),
body.is_some())
}
hir::ConstTraitItem(_, ref value) => {
(AssociatedKind::Const, false, value.is_some())
}
hir::TypeTraitItem(_, ref ty) => {
(AssociatedKind::Type, false, ty.is_some())
let def_id = self.map.local_def_id(trait_item_ref.id.node_id);
let (kind, has_self) = match trait_item_ref.kind {
hir::AssociatedItemKind::Const => (ty::AssociatedKind::Const, false),
hir::AssociatedItemKind::Method { has_self } => {
(ty::AssociatedKind::Method, has_self)
}
hir::AssociatedItemKind::Type => (ty::AssociatedKind::Type, false),
};
AssociatedItem {
name: trait_item.name,
name: trait_item_ref.name,
kind: kind,
vis: Visibility::from_hir(&hir::Inherited, trait_item.id, self),
defaultness: hir::Defaultness::Default { has_value: has_value },
vis: Visibility::from_hir(&hir::Inherited, trait_item_ref.id.node_id, self),
defaultness: trait_item_ref.defaultness,
def_id: def_id,
container: TraitContainer(parent_def_id),
method_has_self_argument: has_self
@ -2187,11 +2181,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
let id = self.map.as_local_node_id(def_id).unwrap();
let item = self.map.expect_item(id);
let vec: Vec<_> = match item.node {
hir::ItemTrait(.., ref trait_items) => {
trait_items.iter()
.map(|trait_item| trait_item.id)
.map(|id| self.map.local_def_id(id))
.collect()
hir::ItemTrait(.., ref trait_item_refs) => {
trait_item_refs.iter()
.map(|trait_item_ref| trait_item_ref.id)
.map(|id| self.map.local_def_id(id.node_id))
.collect()
}
hir::ItemImpl(.., ref impl_item_refs) => {
impl_item_refs.iter()

View file

@ -88,7 +88,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BorrowckCtxt<'a, 'tcx> {
}
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
if let hir::ConstTraitItem(_, Some(ref expr)) = ti.node {
if let hir::TraitItemKind::Const(_, Some(ref expr)) = ti.node {
gather_loans::gather_loans_in_static_initializer(self, ti.id, &expr);
}
intravisit::walk_trait_item(self, ti);

View file

@ -51,7 +51,7 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> {
}
fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) {
if let hir::ConstTraitItem(..) = item.node {
if let hir::TraitItemKind::Const(..) = item.node {
return // nothing worth match checking in a constant
} else {
intravisit::walk_trait_item(self, item);

View file

@ -102,7 +102,7 @@ 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(ref ty, ref expr_option) => {
hir::TraitItemKind::Const(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

View file

@ -35,6 +35,9 @@ impl<'v> ItemLikeVisitor<'v> for Finder {
}
}
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
}
}

View file

@ -171,6 +171,10 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for IfThisChanged<'a, 'tcx> {
self.process_attrs(item.id, &item.attrs);
}
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
self.process_attrs(trait_item.id, &trait_item.attrs);
}
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
self.process_attrs(impl_item.id, &impl_item.attrs);
}

View file

@ -234,6 +234,11 @@ impl<'a, 'tcx> Visitor<'tcx> for HashItemsVisitor<'a, 'tcx> {
visit::walk_item(self, item);
}
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
self.calculate_node_id(trait_item.id, |v| v.visit_trait_item(trait_item));
visit::walk_trait_item(self, trait_item);
}
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
self.calculate_node_id(impl_item.id, |v| v.visit_impl_item(impl_item));
visit::walk_impl_item(self, impl_item);

View file

@ -473,12 +473,12 @@ enum SawTraitOrImplItemComponent {
SawTraitOrImplItemType
}
fn saw_trait_item(ti: &TraitItem_) -> SawTraitOrImplItemComponent {
fn saw_trait_item(ti: &TraitItemKind) -> SawTraitOrImplItemComponent {
match *ti {
ConstTraitItem(..) => SawTraitOrImplItemConst,
MethodTraitItem(ref sig, ref body) =>
TraitItemKind::Const(..) => SawTraitOrImplItemConst,
TraitItemKind::Method(ref sig, ref body) =>
SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi, body.is_some()),
TypeTraitItem(..) => SawTraitOrImplItemType
TraitItemKind::Type(..) => SawTraitOrImplItemType
}
}
@ -1157,6 +1157,7 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
// These fields are handled separately:
exported_macros: _,
items: _,
trait_items: _,
impl_items: _,
exprs: _,
} = *krate;

View file

@ -185,6 +185,9 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for DirtyCleanVisitor<'a, 'tcx> {
}
}
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
}
}
@ -229,6 +232,9 @@ impl<'a, 'tcx, 'm> ItemLikeVisitor<'tcx> for DirtyCleanMetadataVisitor<'a, 'tcx,
}
}
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
}
}

View file

@ -272,7 +272,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase {
}
fn check_trait_item(&mut self, cx: &LateContext, trait_item: &hir::TraitItem) {
if let hir::MethodTraitItem(_, None) = trait_item.node {
if let hir::TraitItemKind::Method(_, None) = trait_item.node {
self.check_snake_case(cx,
"trait method",
&trait_item.name.as_str(),
@ -363,7 +363,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals {
fn check_trait_item(&mut self, cx: &LateContext, ti: &hir::TraitItem) {
match ti.node {
hir::ConstTraitItem(..) => {
hir::TraitItemKind::Const(..) => {
NonUpperCaseGlobals::check_upper_case(cx, "associated constant", ti.name, ti.span);
}
_ => {}

View file

@ -241,7 +241,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
}
fn check_trait_item(&mut self, cx: &LateContext, trait_item: &hir::TraitItem) {
if let hir::MethodTraitItem(ref sig, None) = trait_item.node {
if let hir::TraitItemKind::Method(ref sig, None) = trait_item.node {
if sig.unsafety == hir::Unsafety::Unsafe {
cx.span_lint(UNSAFE_CODE,
trait_item.span,
@ -374,12 +374,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
hir::ItemEnum(..) => "an enum",
hir::ItemStruct(..) => "a struct",
hir::ItemUnion(..) => "a union",
hir::ItemTrait(.., ref items) => {
hir::ItemTrait(.., ref trait_item_refs) => {
// Issue #11592, traits are always considered exported, even when private.
if it.vis == hir::Visibility::Inherited {
self.private_traits.insert(it.id);
for itm in items {
self.private_traits.insert(itm.id);
for trait_item_ref in trait_item_refs {
self.private_traits.insert(trait_item_ref.id.node_id);
}
return;
}
@ -418,9 +418,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
}
let desc = match trait_item.node {
hir::ConstTraitItem(..) => "an associated constant",
hir::MethodTraitItem(..) => "a trait method",
hir::TypeTraitItem(..) => "an associated type",
hir::TraitItemKind::Const(..) => "an associated constant",
hir::TraitItemKind::Method(..) => "a trait method",
hir::TraitItemKind::Type(..) => "an associated type",
};
self.check_missing_docs_attrs(cx,

View file

@ -442,7 +442,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let kind = match trait_item.kind {
ty::AssociatedKind::Const => EntryKind::AssociatedConst(container),
ty::AssociatedKind::Method => {
let fn_data = if let hir::MethodTraitItem(ref sig, _) = ast_item.node {
let fn_data = if let hir::TraitItemKind::Method(ref sig, _) = ast_item.node {
FnData {
constness: hir::Constness::NotConst,
arg_names: self.encode_fn_arg_names(&sig.decl),
@ -486,7 +486,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
ast: if let hir::ConstTraitItem(_, Some(_)) = ast_item.node {
ast: if let hir::TraitItemKind::Const(_, 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();
@ -1162,6 +1162,8 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'a, 'tcx> {
}
}
fn visit_trait_item(&mut self, _trait_item: &'v hir::TraitItem) {}
fn visit_impl_item(&mut self, _impl_item: &'v hir::ImplItem) {
// handled in `visit_item` above
}

View file

@ -168,7 +168,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
// Trait associated const defaults.
fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) {
if let hir::ConstTraitItem(_, Some(ref expr)) = item.node {
if let hir::TraitItemKind::Const(_, Some(ref expr)) = item.node {
self.cx(MirSource::Const(item.id)).build(|cx| {
build::construct_const(cx, item.id, expr)
});

View file

@ -265,7 +265,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
fn visit_trait_item(&mut self, t: &'tcx hir::TraitItem) {
match t.node {
hir::ConstTraitItem(_, ref default) => {
hir::TraitItemKind::Const(_, ref default) => {
if let Some(ref expr) = *default {
self.global_expr(Mode::Const, &expr);
} else {

View file

@ -115,6 +115,11 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
self.visit_item(nested_item)
}
fn visit_nested_trait_item(&mut self, trait_item_id: hir::TraitItemId) {
let nested_trait_item = self.krate.unwrap().trait_item(trait_item_id);
self.visit_trait_item(nested_trait_item)
}
fn visit_nested_impl_item(&mut self, impl_item_id: hir::ImplItemId) {
let nested_impl_item = self.krate.unwrap().impl_item(impl_item_id);
self.visit_impl_item(nested_impl_item)

View file

@ -66,7 +66,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> {
fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) {
match ti.node {
hir::ConstTraitItem(_, ref default) => {
hir::TraitItemKind::Const(_, ref default) => {
if let Some(_) = *default {
let mut recursion_visitor = CheckItemRecursionVisitor::new(self, &ti.span);
recursion_visitor.visit_trait_item(ti);

View file

@ -33,6 +33,9 @@ impl<'v> ItemLikeVisitor<'v> for RegistrarFinder {
}
}
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
}
}

View file

@ -160,21 +160,19 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
}
hir::ItemImpl(.., None, _, ref impl_item_refs) => {
for impl_item_ref in impl_item_refs {
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
if impl_item.vis == hir::Public {
self.update(impl_item.id, item_level);
if impl_item_ref.vis == hir::Public {
self.update(impl_item_ref.id.node_id, item_level);
}
}
}
hir::ItemImpl(.., Some(_), _, ref impl_item_refs) => {
for impl_item_ref in impl_item_refs {
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
self.update(impl_item.id, item_level);
self.update(impl_item_ref.id.node_id, item_level);
}
}
hir::ItemTrait(.., ref trait_items) => {
for trait_item in trait_items {
self.update(trait_item.id, item_level);
hir::ItemTrait(.., ref trait_item_refs) => {
for trait_item_ref in trait_item_refs {
self.update(trait_item_ref.id.node_id, item_level);
}
}
hir::ItemStruct(ref def, _) | hir::ItemUnion(ref def, _) => {
@ -214,15 +212,16 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
self.reach(item.id).generics().predicates().item_type();
}
}
hir::ItemTrait(.., ref trait_items) => {
hir::ItemTrait(.., ref trait_item_refs) => {
if item_level.is_some() {
self.reach(item.id).generics().predicates();
for trait_item in trait_items {
let mut reach = self.reach(trait_item.id);
for trait_item_ref in trait_item_refs {
let mut reach = self.reach(trait_item_ref.id.node_id);
reach.generics().predicates();
if let hir::TypeTraitItem(_, None) = trait_item.node {
if trait_item_ref.kind == hir::AssociatedItemKind::Type &&
!trait_item_ref.defaultness.has_value() {
// No type to visit.
} else {
reach.item_type();
@ -231,12 +230,12 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
}
}
// Visit everything except for private impl items
hir::ItemImpl(.., ref trait_ref, _, ref impl_items) => {
hir::ItemImpl(.., ref trait_ref, _, ref impl_item_refs) => {
if item_level.is_some() {
self.reach(item.id).generics().predicates().impl_trait_ref();
for impl_item in impl_items {
let id = impl_item.id.node_id;
for impl_item_ref in impl_item_refs {
let id = impl_item_ref.id.node_id;
if trait_ref.is_some() || self.get(id).is_some() {
self.reach(id).generics().predicates().item_type();
}
@ -789,22 +788,19 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
// methods will be visible as `Public::foo`.
let mut found_pub_static = false;
for impl_item_ref in impl_item_refs {
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
match impl_item.node {
hir::ImplItemKind::Const(..) => {
if self.item_is_public(&impl_item.id, &impl_item.vis) {
if self.item_is_public(&impl_item_ref.id.node_id, &impl_item_ref.vis) {
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
match impl_item_ref.kind {
hir::AssociatedItemKind::Const => {
found_pub_static = true;
intravisit::walk_impl_item(self, impl_item);
}
}
hir::ImplItemKind::Method(ref sig, _) => {
if !sig.decl.has_self() &&
self.item_is_public(&impl_item.id, &impl_item.vis) {
hir::AssociatedItemKind::Method { has_self: false } => {
found_pub_static = true;
intravisit::walk_impl_item(self, impl_item);
}
_ => {}
}
_ => {}
}
}
if found_pub_static {
@ -1092,14 +1088,15 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
self.inner_visibility = item_visibility;
intravisit::walk_item(self, item);
}
hir::ItemTrait(.., ref trait_items) => {
hir::ItemTrait(.., ref trait_item_refs) => {
self.check(item.id, item_visibility).generics().predicates();
for trait_item in trait_items {
let mut check = self.check(trait_item.id, item_visibility);
for trait_item_ref in trait_item_refs {
let mut check = self.check(trait_item_ref.id.node_id, item_visibility);
check.generics().predicates();
if let hir::TypeTraitItem(_, None) = trait_item.node {
if trait_item_ref.kind == hir::AssociatedItemKind::Type &&
!trait_item_ref.defaultness.has_value() {
// No type to visit.
} else {
check.item_type();

View file

@ -1122,6 +1122,11 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
}
}
fn visit_trait_item(&mut self, _: &'v hir::TraitItem) {
// Even if there's a default body with no explicit generics,
// it's still generic over some `Self: Trait`, so not a root.
}
fn visit_impl_item(&mut self, ii: &'v hir::ImplItem) {
match ii.node {
hir::ImplItemKind::Method(hir::MethodSig {

View file

@ -1708,12 +1708,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
pub fn ty_of_method(&self,
sig: &hir::MethodSig,
untransformed_self_ty: Ty<'tcx>,
opt_self_value_ty: Option<Ty<'tcx>>,
anon_scope: Option<AnonTypeScope>)
-> &'tcx ty::BareFnTy<'tcx> {
self.ty_of_method_or_bare_fn(sig.unsafety,
sig.abi,
Some(untransformed_self_ty),
opt_self_value_ty,
&sig.decl,
None,
anon_scope)
@ -1731,7 +1731,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
fn ty_of_method_or_bare_fn(&self,
unsafety: hir::Unsafety,
abi: abi::Abi,
opt_untransformed_self_ty: Option<Ty<'tcx>>,
opt_self_value_ty: Option<Ty<'tcx>>,
decl: &hir::FnDecl,
arg_anon_scope: Option<AnonTypeScope>,
ret_anon_scope: Option<AnonTypeScope>)
@ -1746,13 +1746,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
let input_tys: Vec<Ty> =
decl.inputs.iter().map(|a| self.ty_of_arg(&rb, a, None)).collect();
let has_self = decl.has_self();
let explicit_self = match (opt_untransformed_self_ty, has_self) {
(Some(untransformed_self_ty), true) => {
Some(ExplicitSelf::determine(untransformed_self_ty, input_tys[0]))
}
_ => None
};
let has_self = opt_self_value_ty.is_some();
let explicit_self = opt_self_value_ty.map(|self_value_ty| {
ExplicitSelf::determine(self_value_ty, input_tys[0])
});
let implied_output_region = match explicit_self {
// `implied_output_region` is the region that will be assumed for any

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use rustc::hir::{self, ImplItemKind, TraitItem_};
use rustc::hir::{self, ImplItemKind, TraitItemKind};
use rustc::infer::{self, InferOk};
use rustc::middle::free_region::FreeRegionMap;
use rustc::ty;
@ -449,10 +449,10 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
TypeError::Mutability => {
if let Some(trait_m_node_id) = tcx.map.as_local_node_id(trait_m.def_id) {
let trait_m_iter = match tcx.map.expect_trait_item(trait_m_node_id).node {
TraitItem_::MethodTraitItem(ref trait_m_sig, _) => {
TraitItemKind::Method(ref trait_m_sig, _) => {
trait_m_sig.decl.inputs.iter()
}
_ => bug!("{:?} is not a MethodTraitItem", trait_m),
_ => bug!("{:?} is not a TraitItemKind::Method", trait_m),
};
impl_m_iter.zip(trait_m_iter).find(|&(ref impl_arg, ref trait_arg)| {
@ -475,10 +475,10 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
if let Some(trait_m_node_id) = tcx.map.as_local_node_id(trait_m.def_id) {
let (trait_m_output, trait_m_iter) =
match tcx.map.expect_trait_item(trait_m_node_id).node {
TraitItem_::MethodTraitItem(ref trait_m_sig, _) => {
TraitItemKind::Method(ref trait_m_sig, _) => {
(&trait_m_sig.decl.output, trait_m_sig.decl.inputs.iter())
}
_ => bug!("{:?} is not a MethodTraitItem", trait_m),
_ => bug!("{:?} is not a TraitItemKind::Method", trait_m),
};
let impl_iter = impl_sig.inputs().iter();
@ -674,7 +674,7 @@ fn compare_number_of_method_arguments<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let trait_m_node_id = tcx.map.as_local_node_id(trait_m.def_id);
let trait_span = if let Some(trait_id) = trait_m_node_id {
match tcx.map.expect_trait_item(trait_id).node {
TraitItem_::MethodTraitItem(ref trait_m_sig, _) => {
TraitItemKind::Method(ref trait_m_sig, _) => {
if let Some(arg) = trait_m_sig.decl.inputs.get(if trait_number_args > 0 {
trait_number_args - 1
} else {
@ -825,7 +825,7 @@ pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
// Add a label to the Span containing just the type of the item
let trait_c_node_id = tcx.map.as_local_node_id(trait_c.def_id).unwrap();
let trait_c_span = match tcx.map.expect_trait_item(trait_c_node_id).node {
TraitItem_::ConstTraitItem(ref ty, _) => ty.span,
TraitItemKind::Const(ref ty, _) => ty.span,
_ => bug!("{:?} is not a trait const", trait_c),
};

View file

@ -463,6 +463,9 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> {
}
}
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
}
}

View file

@ -565,6 +565,10 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
check_item_body(self.ccx, i);
}
fn visit_trait_item(&mut self, _item: &'tcx hir::TraitItem) {
// done as part of `visit_item` above
}
fn visit_impl_item(&mut self, _item: &'tcx hir::ImplItem) {
// done as part of `visit_item` above
}
@ -945,18 +949,19 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
}
}
}
hir::ItemTrait(.., ref trait_items) => {
for trait_item in trait_items {
hir::ItemTrait(.., ref trait_item_refs) => {
for trait_item_ref in trait_item_refs {
let trait_item = ccx.tcx.map.trait_item(trait_item_ref.id);
match trait_item.node {
hir::ConstTraitItem(_, Some(ref expr)) => {
hir::TraitItemKind::Const(_, Some(ref expr)) => {
check_const(ccx, &expr, trait_item.id)
}
hir::MethodTraitItem(ref sig, Some(body_id)) => {
hir::TraitItemKind::Method(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) |
hir::TypeTraitItem(..) => {
hir::TraitItemKind::Method(_, None) |
hir::TraitItemKind::Const(_, None) |
hir::TraitItemKind::Type(..) => {
// Nothing to do.
}
}

View file

@ -159,10 +159,10 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
}
}
fn check_trait_or_impl_item(&mut self,
item_id: ast::NodeId,
span: Span,
sig_if_method: Option<&hir::MethodSig>) {
fn check_associated_item(&mut self,
item_id: ast::NodeId,
span: Span,
sig_if_method: Option<&hir::MethodSig>) {
let code = self.code.clone();
self.for_id(item_id, span).with_fcx(|fcx, this| {
let free_substs = &fcx.parameter_environment.free_substs;
@ -607,10 +607,10 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) {
debug!("visit_trait_item: {:?}", trait_item);
let method_sig = match trait_item.node {
hir::TraitItem_::MethodTraitItem(ref sig, _) => Some(sig),
hir::TraitItemKind::Method(ref sig, _) => Some(sig),
_ => None
};
self.check_trait_or_impl_item(trait_item.id, trait_item.span, method_sig);
self.check_associated_item(trait_item.id, trait_item.span, method_sig);
intravisit::walk_trait_item(self, trait_item)
}
@ -620,7 +620,7 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
hir::ImplItemKind::Method(ref sig, _) => Some(sig),
_ => None
};
self.check_trait_or_impl_item(impl_item.id, impl_item.span, method_sig);
self.check_associated_item(impl_item.id, impl_item.span, method_sig);
intravisit::walk_impl_item(self, impl_item)
}
}

View file

@ -50,6 +50,9 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for UnusedTraitImportVisitor<'a, 'tcx> {
}
}
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
}
}

View file

@ -58,6 +58,9 @@ impl<'a, 'gcx, 'tcx, 'v> ItemLikeVisitor<'v> for CoherenceCheckVisitor<'a, 'gcx,
}
}
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
}
}

View file

@ -67,13 +67,15 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
}
}
}
}
impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
/// Checks exactly one impl for orphan rules and other such
/// restrictions. In this fn, it can happen that multiple errors
/// apply to a specific impl, so just return after reporting one
/// to prevent inundating the user with a bunch of similar error
/// reports.
fn check_item(&self, item: &hir::Item) {
fn visit_item(&mut self, item: &hir::Item) {
let def_id = self.tcx.map.local_def_id(item.id);
match item.node {
hir::ItemImpl(.., None, ref ty, _) => {
@ -378,11 +380,8 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
}
}
}
}
impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
fn visit_item(&mut self, item: &hir::Item) {
self.check_item(item);
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {

View file

@ -205,6 +205,9 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OverlapChecker<'cx, 'tcx> {
}
}
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
}
}

View file

@ -107,6 +107,9 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for UnsafetyChecker<'cx, 'tcx> {
}
}
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
}
}

View file

@ -204,6 +204,13 @@ impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
intravisit::walk_ty(self, ty);
}
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
self.with_collect_item_sig(trait_item.id, || {
convert_trait_item(self.ccx, trait_item)
});
intravisit::walk_trait_item(self, trait_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)
@ -644,8 +651,14 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
ImplContainer(_) => Some(AnonTypeScope::new(def_id)),
TraitContainer(_) => None
};
let assoc_item = ccx.tcx.associated_item(def_id);
let self_value_ty = if assoc_item.method_has_self_argument {
Some(untransformed_rcvr_ty)
} else {
None
};
let fty = AstConv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
sig, untransformed_rcvr_ty, anon_scope);
sig, self_value_ty, anon_scope);
let substs = mk_item_substs(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
ccx.tcx.map.span(id), def_id);
@ -785,56 +798,12 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
tcx.predicates.borrow_mut().insert(def_id, ty_predicates.clone());
},
hir::ItemTrait(.., ref trait_items) => {
hir::ItemTrait(..) => {
generics_of_def_id(ccx, def_id);
trait_def_of_item(ccx, it);
let _: Result<(), ErrorReported> = // any error is already reported, can ignore
ccx.ensure_super_predicates(it.span, def_id);
convert_trait_predicates(ccx, it);
let trait_predicates = tcx.item_predicates(def_id);
debug!("convert: trait_bounds={:?}", trait_predicates);
// FIXME: is the ordering here important? I think it is.
let container = TraitContainer(def_id);
// Convert all the associated constants.
for trait_item in trait_items {
if let hir::ConstTraitItem(ref ty, _) = trait_item.node {
let const_def_id = ccx.tcx.map.local_def_id(trait_item.id);
generics_of_def_id(ccx, const_def_id);
let ty = ccx.icx(&trait_predicates)
.to_ty(&ExplicitRscope, ty);
tcx.item_types.borrow_mut().insert(const_def_id, ty);
convert_associated_const(ccx, container, trait_item.id, ty)
}
}
// Convert all the associated types.
for trait_item in trait_items {
if let hir::TypeTraitItem(_, ref opt_ty) = trait_item.node {
let type_def_id = ccx.tcx.map.local_def_id(trait_item.id);
generics_of_def_id(ccx, type_def_id);
let typ = opt_ty.as_ref().map({
|ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty)
});
convert_associated_type(ccx, container, trait_item.id, typ);
}
}
// Convert all the methods
for trait_item in trait_items {
if let hir::MethodTraitItem(ref sig, _) = trait_item.node {
convert_method(ccx,
container,
trait_item.id,
sig,
tcx.mk_self_type(),
&trait_predicates);
}
}
},
hir::ItemStruct(ref struct_def, _) |
hir::ItemUnion(ref struct_def, _) => {
@ -866,6 +835,44 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
}
}
fn convert_trait_item(ccx: &CrateCtxt, trait_item: &hir::TraitItem) {
let tcx = ccx.tcx;
// we can lookup details about the trait because items are visited
// before trait-items
let trait_def_id = tcx.map.get_parent_did(trait_item.id);
let trait_predicates = tcx.item_predicates(trait_def_id);
match trait_item.node {
hir::TraitItemKind::Const(ref ty, _) => {
let const_def_id = ccx.tcx.map.local_def_id(trait_item.id);
generics_of_def_id(ccx, const_def_id);
let ty = ccx.icx(&trait_predicates)
.to_ty(&ExplicitRscope, &ty);
tcx.item_types.borrow_mut().insert(const_def_id, ty);
convert_associated_const(ccx, TraitContainer(trait_def_id),
trait_item.id, ty);
}
hir::TraitItemKind::Type(_, ref opt_ty) => {
let type_def_id = ccx.tcx.map.local_def_id(trait_item.id);
generics_of_def_id(ccx, type_def_id);
let typ = opt_ty.as_ref().map({
|ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty)
});
convert_associated_type(ccx, TraitContainer(trait_def_id), trait_item.id, typ);
}
hir::TraitItemKind::Method(ref sig, _) => {
convert_method(ccx, TraitContainer(trait_def_id),
trait_item.id, sig, tcx.mk_self_type(),
&trait_predicates);
}
}
}
fn convert_impl_item(ccx: &CrateCtxt, impl_item: &hir::ImplItem) {
let tcx = ccx.tcx;
@ -1290,12 +1297,13 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
ast_generics: &hir::Generics,
trait_predicates: &ty::GenericPredicates<'tcx>,
self_trait_ref: ty::TraitRef<'tcx>,
trait_items: &[hir::TraitItem])
trait_item_refs: &[hir::TraitItemRef])
-> Vec<ty::Predicate<'tcx>>
{
trait_items.iter().flat_map(|trait_item| {
trait_item_refs.iter().flat_map(|trait_item_ref| {
let trait_item = ccx.tcx.map.trait_item(trait_item_ref.id);
let bounds = match trait_item.node {
hir::TypeTraitItem(ref bounds, _) => bounds,
hir::TraitItemKind::Type(ref bounds, _) => bounds,
_ => {
return vec![].into_iter();
}
@ -1363,7 +1371,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let ast_generics = match node {
NodeTraitItem(item) => {
match item.node {
MethodTraitItem(ref sig, _) => &sig.generics,
TraitItemKind::Method(ref sig, _) => &sig.generics,
_ => &no_generics
}
}

View file

@ -87,6 +87,8 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for ImplWfCheck<'a, 'tcx> {
}
}
fn visit_trait_item(&mut self, _trait_item: &'tcx hir::TraitItem) { }
fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem) { }
}

View file

@ -120,6 +120,9 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> {
}
}
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
}
}

View file

@ -258,6 +258,9 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for TermsContext<'a, 'tcx> {
}
}
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
}
}

View file

@ -1270,17 +1270,17 @@ impl Clean<PolyTrait> for hir::PolyTraitRef {
impl Clean<Item> for hir::TraitItem {
fn clean(&self, cx: &DocContext) -> Item {
let inner = match self.node {
hir::ConstTraitItem(ref ty, ref default) => {
hir::TraitItemKind::Const(ref ty, ref default) => {
AssociatedConstItem(ty.clean(cx),
default.as_ref().map(|e| pprust::expr_to_string(&e)))
}
hir::MethodTraitItem(ref sig, Some(_)) => {
hir::TraitItemKind::Method(ref sig, Some(_)) => {
MethodItem(sig.clean(cx))
}
hir::MethodTraitItem(ref sig, None) => {
hir::TraitItemKind::Method(ref sig, None) => {
TyMethodItem(sig.clean(cx))
}
hir::TypeTraitItem(ref bounds, ref default) => {
hir::TraitItemKind::Type(ref bounds, ref default) => {
AssociatedTypeItem(bounds.clean(cx), default.clean(cx))
}
};

View file

@ -456,11 +456,14 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
};
om.constants.push(s);
},
hir::ItemTrait(unsafety, ref gen, ref b, ref items) => {
hir::ItemTrait(unsafety, ref gen, ref b, ref item_ids) => {
let items = item_ids.iter()
.map(|ti| self.cx.tcx.map.trait_item(ti.id).clone())
.collect();
let t = Trait {
unsafety: unsafety,
name: name,
items: items.clone(),
items: items,
generics: gen.clone(),
bounds: b.iter().cloned().collect(),
id: item.id,

View file

@ -34,9 +34,11 @@ struct WontChange {
mod signatures {
use WillChange;
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK
#[rustc_then_this_would_need(CollectItem)] //~ ERROR OK
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR no path
#[rustc_then_this_would_need(CollectItem)] //~ ERROR no path
trait Bar {
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK
#[rustc_then_this_would_need(CollectItem)] //~ ERROR OK
fn do_something(x: WillChange);
}

View file

@ -35,8 +35,9 @@ enum Enum {
Variant2(i32)
}
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR no path
trait Trait {
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK
fn method(&self, _: TypeAlias);
}

View file

@ -98,11 +98,15 @@ trait TraitAddReturnType {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitAddReturnType {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method() -> u32;
}
@ -115,11 +119,15 @@ trait TraitChangeReturnType {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitChangeReturnType {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method() -> u64;
}
@ -132,11 +140,15 @@ trait TraitAddParameterToMethod {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitAddParameterToMethod {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method(a: u32);
}
@ -149,11 +161,15 @@ trait TraitChangeMethodParameterName {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitChangeMethodParameterName {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method(b: u32);
}
@ -166,11 +182,15 @@ trait TraitChangeMethodParameterType {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitChangeMethodParameterType {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method(a: i64);
}
@ -183,11 +203,15 @@ trait TraitChangeMethodParameterTypeRef {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitChangeMethodParameterTypeRef {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method(a: &mut i32);
}
@ -200,11 +224,15 @@ trait TraitChangeMethodParametersOrder {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitChangeMethodParametersOrder {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method(b: i64, a: i32);
}
@ -253,11 +281,15 @@ trait TraitChangeModeSelfRefToMut {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitChangeModeSelfRefToMut {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method(&mut self);
}
@ -269,11 +301,15 @@ trait TraitChangeModeSelfOwnToMut: Sized {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitChangeModeSelfOwnToMut: Sized {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method(mut self) {}
}
@ -285,11 +321,15 @@ trait TraitChangeModeSelfOwnToRef {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitChangeModeSelfOwnToRef {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method(&self);
}
@ -302,11 +342,15 @@ trait TraitAddUnsafeModifier {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitAddUnsafeModifier {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
unsafe fn method();
}
@ -319,11 +363,15 @@ trait TraitAddExternModifier {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitAddExternModifier {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
extern fn method();
}
@ -336,11 +384,15 @@ trait TraitChangeExternCToRustIntrinsic {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitChangeExternCToRustIntrinsic {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
extern "rust-intrinsic" fn method();
}
@ -353,11 +405,15 @@ trait TraitAddTypeParameterToMethod {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitAddTypeParameterToMethod {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method<T>();
}
@ -370,11 +426,15 @@ trait TraitAddLifetimeParameterToMethod {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitAddLifetimeParameterToMethod {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method<'a>();
}
@ -391,11 +451,15 @@ trait TraitAddTraitBoundToMethodTypeParameter {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitAddTraitBoundToMethodTypeParameter {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method<T: ReferencedTrait0>();
}
@ -408,11 +472,15 @@ trait TraitAddBuiltinBoundToMethodTypeParameter {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitAddBuiltinBoundToMethodTypeParameter {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method<T: Sized>();
}
@ -425,11 +493,15 @@ trait TraitAddLifetimeBoundToMethodLifetimeParameter {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitAddLifetimeBoundToMethodLifetimeParameter {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method<'a, 'b: 'a>(a: &'a u32, b: &'b u32);
}
@ -442,11 +514,15 @@ trait TraitAddSecondTraitBoundToMethodTypeParameter {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitAddSecondTraitBoundToMethodTypeParameter {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method<T: ReferencedTrait0 + ReferencedTrait1>();
}
@ -459,11 +535,15 @@ trait TraitAddSecondBuiltinBoundToMethodTypeParameter {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitAddSecondBuiltinBoundToMethodTypeParameter {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method<T: Sized + Sync>();
}
@ -476,11 +556,15 @@ trait TraitAddSecondLifetimeBoundToMethodLifetimeParameter {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitAddSecondLifetimeBoundToMethodLifetimeParameter {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method<'a, 'b, 'c: 'a + 'b>(a: &'a u32, b: &'b u32, c: &'c u32);
}
@ -514,11 +598,15 @@ trait TraitAddTraitBoundToAssociatedType {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitAddTraitBoundToAssociatedType {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
type Associated: ReferencedTrait0;
fn mathod();
@ -535,11 +623,15 @@ trait TraitAddLifetimeBoundToAssociatedType<'a> {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitAddLifetimeBoundToAssociatedType<'a> {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
type Associated: 'a;
fn mathod();
@ -617,11 +709,15 @@ trait TraitChangeTypeOfAssociatedConstant {
}
#[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_metadata_clean(cfg="cfail3")]
trait TraitChangeTypeOfAssociatedConstant {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
const Value: f64;
fn mathod();
@ -1013,11 +1109,15 @@ mod change_return_type_of_method_indirectly_use {
#[cfg(not(cfail1))]
use super::ReferenceType1 as ReturnType;
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
trait TraitChangeReturnType {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method() -> ReturnType;
}
}
@ -1031,11 +1131,15 @@ mod change_method_parameter_type_indirectly_by_use {
#[cfg(not(cfail1))]
use super::ReferenceType1 as ArgType;
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
trait TraitChangeArgType {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method(a: ArgType);
}
}
@ -1049,11 +1153,15 @@ mod change_method_parameter_type_bound_indirectly_by_use {
#[cfg(not(cfail1))]
use super::ReferencedTrait1 as Bound;
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
trait TraitChangeBoundOfMethodTypeParameter {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method<T: Bound>(a: T);
}
}
@ -1068,11 +1176,15 @@ mod change_method_parameter_type_bound_indirectly_by_use_where {
#[cfg(not(cfail1))]
use super::ReferencedTrait1 as Bound;
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
trait TraitChangeBoundOfMethodTypeParameterWhere {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn method<T>(a: T) where T: Bound;
}
}

View file

@ -1,11 +1,3 @@
error: cannot borrow immutable borrowed content `*a` as mutable
--> $DIR/mut-arg-hint.rs:13:9
|
12 | fn foo(mut a: &String) {
| ------- use `&mut String` here to make mutable
13 | a.push_str("bar");
| ^
error: cannot borrow immutable borrowed content `*a` as mutable
--> $DIR/mut-arg-hint.rs:18:5
|
@ -14,6 +6,14 @@ error: cannot borrow immutable borrowed content `*a` as mutable
18 | a.push_str("foo");
| ^
error: cannot borrow immutable borrowed content `*a` as mutable
--> $DIR/mut-arg-hint.rs:13:9
|
12 | fn foo(mut a: &String) {
| ------- use `&mut String` here to make mutable
13 | a.push_str("bar");
| ^
error: cannot borrow immutable borrowed content `*a` as mutable
--> $DIR/mut-arg-hint.rs:25:9
|