Auto merge of #79519 - cjgillot:noattr, r=wesleywiser

Store HIR attributes in a side table

Same idea as #72015 but for attributes.
The objective is to reduce incr-comp invalidations due to modified attributes.
Notably, those due to modified doc comments.

Implementation:
- collect attributes during AST->HIR lowering, in `LocalDefId -> ItemLocalId -> &[Attributes]` nested tables;
- access the attributes through a `hir_owner_attrs` query;
- local refactorings to use this access;
- remove `attrs` from HIR data structures one-by-one.

Change in behaviour:
- the HIR visitor traverses all attributes at once instead of parent-by-parent;
- attribute arrays are sometimes duplicated: for statements and variant constructors;
- as a consequence, attributes are marked as used after unused-attribute lint emission to avoid duplicate lints.

~~Current bug: the lint level is not correctly applied in `std::backtrace_rs`, triggering an unused attribute warning on `#![no_std]`. I welcome suggestions.~~
This commit is contained in:
bors 2021-03-10 08:40:51 +00:00
commit dff1edf919
88 changed files with 936 additions and 920 deletions

View File

@ -258,9 +258,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
ex.span = e.span;
}
// Merge attributes into the inner expression.
let mut attrs: Vec<_> = e.attrs.iter().map(|a| self.lower_attr(a)).collect();
attrs.extend::<Vec<_>>(ex.attrs.into());
ex.attrs = attrs.into();
if !e.attrs.is_empty() {
let old_attrs = self.attrs.get(&ex.hir_id).map(|la| *la).unwrap_or(&[]);
self.attrs.insert(
ex.hir_id,
&*self.arena.alloc_from_iter(
e.attrs
.iter()
.map(|a| self.lower_attr(a))
.chain(old_attrs.iter().cloned()),
),
);
}
return ex;
}
@ -272,12 +281,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span),
};
hir::Expr {
hir_id: self.lower_node_id(e.id),
kind,
span: e.span,
attrs: e.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into(),
}
let hir_id = self.lower_node_id(e.id);
self.lower_attrs(hir_id, &e.attrs);
hir::Expr { hir_id, kind, span: e.span }
})
}
@ -618,14 +624,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::Guard::If(self.lower_expr(cond))
}
});
hir::Arm {
hir_id: self.next_id(),
attrs: self.lower_attrs(&arm.attrs),
pat,
guard,
body: self.lower_expr(&arm.body),
span: arm.span,
}
let hir_id = self.next_id();
self.lower_attrs(hir_id, &arm.attrs);
hir::Arm { hir_id, pat, guard, body: self.lower_expr(&arm.body), span: arm.span }
}
/// Lower an `async` construct to a generator that is then wrapped so it implements `Future`.
@ -669,7 +670,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
Ident::with_dummy_span(sym::_task_context),
hir::BindingAnnotation::Mutable,
);
let param = hir::Param { attrs: &[], hir_id: self.next_id(), pat, ty_span: span, span };
let param = hir::Param { hir_id: self.next_id(), pat, ty_span: span, span };
let params = arena_vec![self; param];
let body_id = self.lower_body(move |this| {
@ -690,12 +691,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
span,
Some(hir::Movability::Static),
);
let generator = hir::Expr {
hir_id: self.lower_node_id(closure_node_id),
kind: generator_kind,
span,
attrs: ThinVec::new(),
};
let generator =
hir::Expr { hir_id: self.lower_node_id(closure_node_id), kind: generator_kind, span };
// `future::from_generator`:
let unstable_span =
@ -849,7 +846,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir_id: loop_hir_id,
kind: hir::ExprKind::Loop(loop_block, None, hir::LoopSource::Loop, span),
span,
attrs: ThinVec::new(),
});
// mut pinned => loop { ... }
@ -1026,7 +1022,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Introduce a `let` for destructuring: `let (lhs1, lhs2) = t`.
let destructure_let = self.stmt_let_pat(
ThinVec::new(),
None,
whole_span,
Some(rhs),
pat,
@ -1785,7 +1781,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `let mut __next`
let next_let = self.stmt_let_pat(
ThinVec::new(),
None,
desugared_span,
None,
next_pat,
@ -1795,7 +1791,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `let <pat> = __next`
let pat = self.lower_pat(pat);
let pat_let = self.stmt_let_pat(
ThinVec::new(),
None,
desugared_span,
Some(next_expr),
pat,
@ -1819,12 +1815,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::LoopSource::ForLoop,
e.span.with_hi(orig_head_span.hi()),
);
let loop_expr = self.arena.alloc(hir::Expr {
hir_id: self.lower_node_id(e.id),
kind,
span: e.span,
attrs: ThinVec::new(),
});
let loop_expr =
self.arena.alloc(hir::Expr { hir_id: self.lower_node_id(e.id), kind, span: e.span });
// `mut iter => { ... }`
let iter_arm = self.arm(iter_pat, loop_expr);
@ -2159,7 +2151,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
kind: hir::ExprKind<'hir>,
attrs: AttrVec,
) -> hir::Expr<'hir> {
hir::Expr { hir_id: self.next_id(), kind, span, attrs }
let hir_id = self.next_id();
self.lower_attrs(hir_id, &attrs);
hir::Expr { hir_id, kind, span }
}
fn field(&mut self, ident: Ident, expr: &'hir hir::Expr<'hir>, span: Span) -> hir::Field<'hir> {
@ -2167,13 +2161,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
fn arm(&mut self, pat: &'hir hir::Pat<'hir>, expr: &'hir hir::Expr<'hir>) -> hir::Arm<'hir> {
hir::Arm {
hir_id: self.next_id(),
attrs: &[],
pat,
guard: None,
span: expr.span,
body: expr,
}
hir::Arm { hir_id: self.next_id(), pat, guard: None, span: expr.span, body: expr }
}
}

View File

@ -217,44 +217,41 @@ impl<'hir> LoweringContext<'_, 'hir> {
pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item<'hir>> {
let mut ident = i.ident;
let mut vis = self.lower_visibility(&i.vis, None);
let attrs = self.lower_attrs(&i.attrs);
if let ItemKind::MacroDef(MacroDef { ref body, macro_rules }) = i.kind {
if !macro_rules || self.sess.contains_name(&i.attrs, sym::macro_export) {
let def_id = self.lower_node_id(i.id).expect_owner();
let hir_id = self.lower_node_id(i.id);
self.lower_attrs(hir_id, &i.attrs);
let body = P(self.lower_mac_args(body));
self.exported_macros.push(hir::MacroDef {
ident,
vis,
attrs,
def_id,
def_id: hir_id.expect_owner(),
span: i.span,
ast: MacroDef { body, macro_rules },
});
} else {
self.non_exported_macro_attrs.extend(attrs.iter().cloned());
for a in i.attrs.iter() {
let a = self.lower_attr(a);
self.non_exported_macro_attrs.push(a);
}
}
return None;
}
let kind = self.lower_item_kind(i.span, i.id, &mut ident, attrs, &mut vis, &i.kind);
Some(hir::Item {
def_id: self.lower_node_id(i.id).expect_owner(),
ident,
attrs,
kind,
vis,
span: i.span,
})
let hir_id = self.lower_node_id(i.id);
let attrs = self.lower_attrs(hir_id, &i.attrs);
let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, &mut vis, &i.kind);
Some(hir::Item { def_id: hir_id.expect_owner(), ident, kind, vis, span: i.span })
}
fn lower_item_kind(
&mut self,
span: Span,
id: NodeId,
hir_id: hir::HirId,
ident: &mut Ident,
attrs: &'hir [Attribute],
attrs: Option<&'hir [Attribute]>,
vis: &mut hir::Visibility<'hir>,
i: &ItemKind,
) -> hir::ItemKind<'hir> {
@ -365,14 +362,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_generics(generics, ImplTraitContext::disallowed()),
),
ItemKind::Struct(ref struct_def, ref generics) => {
let struct_def = self.lower_variant_data(struct_def);
let struct_def = self.lower_variant_data(hir_id, struct_def);
hir::ItemKind::Struct(
struct_def,
self.lower_generics(generics, ImplTraitContext::disallowed()),
)
}
ItemKind::Union(ref vdata, ref generics) => {
let vdata = self.lower_variant_data(vdata);
let vdata = self.lower_variant_data(hir_id, vdata);
hir::ItemKind::Union(
vdata,
self.lower_generics(generics, ImplTraitContext::disallowed()),
@ -505,7 +502,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
id: NodeId,
vis: &mut hir::Visibility<'hir>,
ident: &mut Ident,
attrs: &'hir [Attribute],
attrs: Option<&'hir [Attribute]>,
) -> hir::ItemKind<'hir> {
debug!("lower_use_tree(tree={:?})", tree);
debug!("lower_use_tree: vis = {:?}", vis);
@ -554,11 +551,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
let path = this.lower_path_extra(res, &path, ParamMode::Explicit, None);
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
let vis = this.rebuild_vis(&vis);
if let Some(attrs) = attrs {
this.attrs.insert(new_id, attrs);
}
this.insert_item(hir::Item {
def_id: new_id.expect_owner(),
ident,
attrs,
kind,
vis,
span,
@ -626,11 +625,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
let kind =
this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);
if let Some(attrs) = attrs {
this.attrs.insert(new_hir_id, attrs);
}
this.insert_item(hir::Item {
def_id: new_hir_id.expect_owner(),
ident,
attrs,
kind,
vis,
span: use_tree.span,
@ -699,11 +700,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem<'hir> {
let def_id = self.resolver.local_def_id(i.id);
let hir_id = self.lower_node_id(i.id);
let def_id = hir_id.expect_owner();
self.lower_attrs(hir_id, &i.attrs);
hir::ForeignItem {
def_id,
ident: i.ident,
attrs: self.lower_attrs(&i.attrs),
kind: match i.kind {
ForeignItemKind::Fn(box FnKind(_, ref sig, ref generics, _)) => {
let fdec = &sig.decl;
@ -748,29 +750,43 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
let id = self.lower_node_id(v.id);
self.lower_attrs(id, &v.attrs);
hir::Variant {
attrs: self.lower_attrs(&v.attrs),
data: self.lower_variant_data(&v.data),
id,
data: self.lower_variant_data(id, &v.data),
disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
id: self.lower_node_id(v.id),
ident: v.ident,
span: v.span,
}
}
fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData<'hir> {
fn lower_variant_data(
&mut self,
parent_id: hir::HirId,
vdata: &VariantData,
) -> hir::VariantData<'hir> {
match *vdata {
VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct(
self.arena
.alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_struct_field(f))),
recovered,
),
VariantData::Tuple(ref fields, id) => hir::VariantData::Tuple(
self.arena
.alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_struct_field(f))),
self.lower_node_id(id),
),
VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id)),
VariantData::Tuple(ref fields, id) => {
let ctor_id = self.lower_node_id(id);
self.alias_attrs(ctor_id, parent_id);
hir::VariantData::Tuple(
self.arena.alloc_from_iter(
fields.iter().enumerate().map(|f| self.lower_struct_field(f)),
),
ctor_id,
)
}
VariantData::Unit(id) => {
let ctor_id = self.lower_node_id(id);
self.alias_attrs(ctor_id, parent_id);
hir::VariantData::Unit(ctor_id)
}
}
}
@ -787,9 +803,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
} else {
self.lower_ty(&f.ty, ImplTraitContext::disallowed())
};
let hir_id = self.lower_node_id(f.id);
self.lower_attrs(hir_id, &f.attrs);
hir::StructField {
span: f.span,
hir_id: self.lower_node_id(f.id),
hir_id,
ident: match f.ident {
Some(ident) => ident,
// FIXME(jseyfried): positional field hygiene.
@ -797,12 +815,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
},
vis: self.lower_visibility(&f.vis, None),
ty,
attrs: self.lower_attrs(&f.attrs),
}
}
fn lower_trait_item(&mut self, i: &AssocItem) -> hir::TraitItem<'hir> {
let trait_item_def_id = self.resolver.local_def_id(i.id);
let hir_id = self.lower_node_id(i.id);
let trait_item_def_id = hir_id.expect_owner();
let (generics, kind) = match i.kind {
AssocItemKind::Const(_, ref ty, ref default) => {
@ -835,14 +853,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"),
};
hir::TraitItem {
def_id: trait_item_def_id,
ident: i.ident,
attrs: self.lower_attrs(&i.attrs),
generics,
kind,
span: i.span,
}
self.lower_attrs(hir_id, &i.attrs);
hir::TraitItem { def_id: trait_item_def_id, ident: i.ident, generics, kind, span: i.span }
}
fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
@ -920,10 +932,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Since `default impl` is not yet implemented, this is always true in impls.
let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
let hir_id = self.lower_node_id(i.id);
self.lower_attrs(hir_id, &i.attrs);
hir::ImplItem {
def_id: self.lower_node_id(i.id).expect_owner(),
def_id: hir_id.expect_owner(),
ident: i.ident,
attrs: self.lower_attrs(&i.attrs),
generics,
vis: self.lower_visibility(&i.vis, None),
defaultness,
@ -1024,9 +1037,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
let hir_id = self.lower_node_id(param.id);
self.lower_attrs(hir_id, &param.attrs);
hir::Param {
attrs: self.lower_attrs(&param.attrs),
hir_id: self.lower_node_id(param.id),
hir_id,
pat: self.lower_pat(&param.pat),
ty_span: param.ty.span,
span: param.span,
@ -1158,11 +1172,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
//
// If this is the simple case, this parameter will end up being the same as the
// original parameter, but with a different pattern id.
let mut stmt_attrs = AttrVec::new();
stmt_attrs.extend(parameter.attrs.iter().cloned());
let stmt_attrs = this.attrs.get(&parameter.hir_id).copied();
let (new_parameter_pat, new_parameter_id) = this.pat_ident(desugared_span, ident);
let new_parameter = hir::Param {
attrs: parameter.attrs,
hir_id: parameter.hir_id,
pat: new_parameter_pat,
ty_span: parameter.ty_span,
@ -1205,7 +1217,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
);
let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id);
let move_stmt = this.stmt_let_pat(
AttrVec::new(),
None,
desugared_span,
Some(move_expr),
move_pat,

View File

@ -114,6 +114,8 @@ struct LoweringContext<'a, 'hir: 'a> {
generator_kind: Option<hir::GeneratorKind>,
attrs: BTreeMap<hir::HirId, &'hir [Attribute]>,
/// When inside an `async` context, this is the `HirId` of the
/// `task_context` local bound to the resume argument of the generator.
task_context: Option<hir::HirId>,
@ -309,6 +311,7 @@ pub fn lower_crate<'a, 'hir>(
bodies: BTreeMap::new(),
trait_impls: BTreeMap::new(),
modules: BTreeMap::new(),
attrs: BTreeMap::default(),
exported_macros: Vec::new(),
non_exported_macro_attrs: Vec::new(),
catch_scopes: Vec::new(),
@ -565,7 +568,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c);
let module = self.lower_mod(&c.items, c.span);
let attrs = self.lower_attrs(&c.attrs);
self.lower_attrs(hir::CRATE_HIR_ID, &c.attrs);
let body_ids = body_ids(&self.bodies);
let proc_macros =
c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect();
@ -592,8 +595,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id);
#[cfg(debug_assertions)]
for (&id, attrs) in self.attrs.iter() {
// Verify that we do not store empty slices in the map.
if attrs.is_empty() {
panic!("Stored empty attributes for {:?}", id);
}
}
hir::Crate {
item: hir::CrateItem { module, attrs, span: c.span },
item: hir::CrateItem { module, span: c.span },
exported_macros: self.arena.alloc_from_iter(self.exported_macros),
non_exported_macro_attrs: self.arena.alloc_from_iter(self.non_exported_macro_attrs),
items: self.items,
@ -606,6 +617,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
modules: self.modules,
proc_macros,
trait_map,
attrs: self.attrs,
}
}
@ -834,7 +846,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::GenericParam {
hir_id: self.lower_node_id(node_id),
name: hir_name,
attrs: &[],
bounds: &[],
span,
pure_wrt_drop: false,
@ -967,11 +978,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ret
}
fn lower_attrs(&mut self, attrs: &[Attribute]) -> &'hir [Attribute] {
self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)))
fn lower_attrs(&mut self, id: hir::HirId, attrs: &[Attribute]) -> Option<&'hir [Attribute]> {
if attrs.is_empty() {
None
} else {
let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)));
debug_assert!(!ret.is_empty());
self.attrs.insert(id, ret);
Some(ret)
}
}
fn lower_attr(&mut self, attr: &Attribute) -> Attribute {
fn lower_attr(&self, attr: &Attribute) -> Attribute {
// Note that we explicitly do not walk the path. Since we don't really
// lower attributes (we use the AST version) there is nowhere to keep
// the `HirId`s. We don't actually need HIR version of attributes anyway.
@ -991,7 +1009,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
Attribute { kind, id: attr.id, style: attr.style, span: attr.span }
}
fn lower_mac_args(&mut self, args: &MacArgs) -> MacArgs {
fn alias_attrs(&mut self, id: hir::HirId, target_id: hir::HirId) {
if let Some(&a) = self.attrs.get(&target_id) {
debug_assert!(!a.is_empty());
self.attrs.insert(id, a);
}
}
fn lower_mac_args(&self, args: &MacArgs) -> MacArgs {
match *args {
MacArgs::Empty => MacArgs::Empty,
MacArgs::Delimited(dspan, delim, ref tokens) => {
@ -1444,7 +1469,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir_id: self.lower_node_id(def_node_id),
name: ParamName::Plain(ident),
pure_wrt_drop: false,
attrs: &[],
bounds: hir_bounds,
span,
kind: hir::GenericParamKind::Type {
@ -1572,7 +1596,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let opaque_ty_item = hir::Item {
def_id: opaque_ty_id,
ident: Ident::invalid(),
attrs: Default::default(),
kind: opaque_ty_item_kind,
vis: respan(span.shrink_to_lo(), hir::VisibilityKind::Inherited),
span: opaque_ty_span,
@ -1733,7 +1756,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
name,
span: lifetime.span,
pure_wrt_drop: false,
attrs: &[],
bounds: &[],
kind: hir::GenericParamKind::Lifetime { kind },
});
@ -1790,14 +1812,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
)
});
let init = l.init.as_ref().map(|e| self.lower_expr(e));
let hir_id = self.lower_node_id(l.id);
self.lower_attrs(hir_id, &l.attrs);
(
hir::Local {
hir_id: self.lower_node_id(l.id),
hir_id,
ty,
pat: self.lower_pat(&l.pat),
init,
span: l.span,
attrs: l.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into(),
source: hir::LocalSource::Normal,
},
ids,
@ -2300,12 +2323,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
};
let hir_id = self.lower_node_id(param.id);
self.lower_attrs(hir_id, &param.attrs);
hir::GenericParam {
hir_id: self.lower_node_id(param.id),
hir_id,
name,
span: param.ident.span,
pure_wrt_drop: self.sess.contains_name(&param.attrs, sym::may_dangle),
attrs: self.lower_attrs(&param.attrs),
bounds: self.arena.alloc_from_iter(bounds),
kind,
}
@ -2426,7 +2450,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
fn lower_stmt(&mut self, s: &Stmt) -> SmallVec<[hir::Stmt<'hir>; 1]> {
let kind = match s.kind {
let (hir_id, kind) = match s.kind {
StmtKind::Local(ref l) => {
let (l, item_ids) = self.lower_local(l);
let mut ids: SmallVec<[hir::Stmt<'hir>; 1]> = item_ids
@ -2439,9 +2463,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.stmt(s.span, hir::StmtKind::Item(item_id))
})
.collect();
let hir_id = self.lower_node_id(s.id);
self.alias_attrs(hir_id, l.hir_id);
ids.push({
hir::Stmt {
hir_id: self.lower_node_id(s.id),
hir_id,
kind: hir::StmtKind::Local(self.arena.alloc(l)),
span: s.span,
}
@ -2464,12 +2490,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
})
.collect();
}
StmtKind::Expr(ref e) => hir::StmtKind::Expr(self.lower_expr(e)),
StmtKind::Semi(ref e) => hir::StmtKind::Semi(self.lower_expr(e)),
StmtKind::Expr(ref e) => {
let e = self.lower_expr(e);
let hir_id = self.lower_node_id(s.id);
self.alias_attrs(hir_id, e.hir_id);
(hir_id, hir::StmtKind::Expr(e))
}
StmtKind::Semi(ref e) => {
let e = self.lower_expr(e);
let hir_id = self.lower_node_id(s.id);
self.alias_attrs(hir_id, e.hir_id);
(hir_id, hir::StmtKind::Semi(e))
}
StmtKind::Empty => return smallvec![],
StmtKind::MacCall(..) => panic!("shouldn't exist here"),
};
smallvec![hir::Stmt { hir_id: self.lower_node_id(s.id), kind, span: s.span }]
smallvec![hir::Stmt { hir_id, kind, span: s.span }]
}
fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {
@ -2513,13 +2549,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn stmt_let_pat(
&mut self,
attrs: AttrVec,
attrs: Option<&'hir [Attribute]>,
span: Span,
init: Option<&'hir hir::Expr<'hir>>,
pat: &'hir hir::Pat<'hir>,
source: hir::LocalSource,
) -> hir::Stmt<'hir> {
let local = hir::Local { attrs, hir_id: self.next_id(), init, pat, source, span, ty: None };
let hir_id = self.next_id();
if let Some(a) = attrs {
debug_assert!(!a.is_empty());
self.attrs.insert(hir_id, a);
}
let local = hir::Local { hir_id, init, pat, source, span, ty: None };
self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
}

View File

@ -433,12 +433,10 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
let sess = tcx.sess;
let crate_name = tcx.crate_name(LOCAL_CRATE);
let no_builtins = tcx.sess.contains_name(&tcx.hir().krate().item.attrs, sym::no_builtins);
let is_compiler_builtins =
tcx.sess.contains_name(&tcx.hir().krate().item.attrs, sym::compiler_builtins);
let subsystem = tcx
.sess
.first_attr_value_str_by_name(&tcx.hir().krate().item.attrs, sym::windows_subsystem);
let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
let no_builtins = tcx.sess.contains_name(crate_attrs, sym::no_builtins);
let is_compiler_builtins = tcx.sess.contains_name(crate_attrs, sym::compiler_builtins);
let subsystem = tcx.sess.first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem);
let windows_subsystem = subsystem.map(|subsystem| {
if subsystem != sym::windows && subsystem != sym::console {
tcx.sess.fatal(&format!(

View File

@ -6,7 +6,7 @@ use crate::{itemlikevisit, LangItem};
use rustc_ast::util::parser::ExprPrecedence;
use rustc_ast::{self as ast, CrateSugar, LlvmAsmDialect};
use rustc_ast::{AttrVec, Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, UintTy};
use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, UintTy};
pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto};
pub use rustc_ast::{CaptureBy, Movability, Mutability};
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
@ -469,7 +469,6 @@ pub enum GenericParamKind<'hir> {
pub struct GenericParam<'hir> {
pub hir_id: HirId,
pub name: ParamName,
pub attrs: &'hir [Attribute],
pub bounds: GenericBounds<'hir>,
pub span: Span,
pub pure_wrt_drop: bool,
@ -630,7 +629,6 @@ pub struct ModuleItems {
#[derive(Encodable, Debug, HashStable_Generic)]
pub struct CrateItem<'hir> {
pub module: Mod<'hir>,
pub attrs: &'hir [Attribute],
pub span: Span,
}
@ -675,6 +673,9 @@ pub struct Crate<'hir> {
pub proc_macros: Vec<HirId>,
pub trait_map: BTreeMap<HirId, Vec<TraitCandidate>>,
/// Collected attributes from HIR nodes.
pub attrs: BTreeMap<HirId, &'hir [Attribute]>,
}
impl Crate<'hir> {
@ -766,7 +767,6 @@ impl Crate<'_> {
pub struct MacroDef<'hir> {
pub ident: Ident,
pub vis: Visibility<'hir>,
pub attrs: &'hir [Attribute],
pub def_id: LocalDefId,
pub span: Span,
pub ast: ast::MacroDef,
@ -1166,16 +1166,6 @@ pub enum StmtKind<'hir> {
Semi(&'hir Expr<'hir>),
}
impl<'hir> StmtKind<'hir> {
pub fn attrs(&self, get_item: impl FnOnce(ItemId) -> &'hir Item<'hir>) -> &'hir [Attribute] {
match *self {
StmtKind::Local(ref l) => &l.attrs,
StmtKind::Item(ref item_id) => &get_item(*item_id).attrs,
StmtKind::Expr(ref e) | StmtKind::Semi(ref e) => &e.attrs,
}
}
}
/// Represents a `let` statement (i.e., `let <pat>:<ty> = <expr>;`).
#[derive(Debug, HashStable_Generic)]
pub struct Local<'hir> {
@ -1186,7 +1176,6 @@ pub struct Local<'hir> {
pub init: Option<&'hir Expr<'hir>>,
pub hir_id: HirId,
pub span: Span,
pub attrs: AttrVec,
/// Can be `ForLoopDesugar` if the `let` statement is part of a `for` loop
/// desugaring. Otherwise will be `Normal`.
pub source: LocalSource,
@ -1199,7 +1188,6 @@ pub struct Arm<'hir> {
#[stable_hasher(ignore)]
pub hir_id: HirId,
pub span: Span,
pub attrs: &'hir [Attribute],
/// If this pattern and the optional guard matches, then `body` is evaluated.
pub pat: &'hir Pat<'hir>,
/// Optional guard clause.
@ -1458,7 +1446,6 @@ pub struct AnonConst {
pub struct Expr<'hir> {
pub hir_id: HirId,
pub kind: ExprKind<'hir>,
pub attrs: AttrVec,
pub span: Span,
}
@ -2040,7 +2027,6 @@ impl TraitItemId {
pub struct TraitItem<'hir> {
pub ident: Ident,
pub def_id: LocalDefId,
pub attrs: &'hir [Attribute],
pub generics: Generics<'hir>,
pub kind: TraitItemKind<'hir>,
pub span: Span,
@ -2103,7 +2089,6 @@ pub struct ImplItem<'hir> {
pub def_id: LocalDefId,
pub vis: Visibility<'hir>,
pub defaultness: Defaultness,
pub attrs: &'hir [Attribute],
pub generics: Generics<'hir>,
pub kind: ImplItemKind<'hir>,
pub span: Span,
@ -2433,7 +2418,6 @@ pub struct LlvmInlineAsm<'hir> {
/// Represents a parameter in a function header.
#[derive(Debug, HashStable_Generic)]
pub struct Param<'hir> {
pub attrs: &'hir [Attribute],
pub hir_id: HirId,
pub pat: &'hir Pat<'hir>,
pub ty_span: Span,
@ -2551,8 +2535,6 @@ pub struct Variant<'hir> {
/// Name of the variant.
#[stable_hasher(project(name))]
pub ident: Ident,
/// Attributes of the variant.
pub attrs: &'hir [Attribute],
/// Id of the variant (not the constructor, see `VariantData::ctor_hir_id()`).
pub id: HirId,
/// Fields and constructor id of the variant.
@ -2646,7 +2628,6 @@ pub struct StructField<'hir> {
pub vis: Visibility<'hir>,
pub hir_id: HirId,
pub ty: &'hir Ty<'hir>,
pub attrs: &'hir [Attribute],
}
impl StructField<'_> {
@ -2715,7 +2696,6 @@ impl ItemId {
pub struct Item<'hir> {
pub ident: Ident,
pub def_id: LocalDefId,
pub attrs: &'hir [Attribute],
pub kind: ItemKind<'hir>,
pub vis: Visibility<'hir>,
pub span: Span,
@ -2932,7 +2912,6 @@ pub struct ForeignItemRef<'hir> {
#[derive(Debug)]
pub struct ForeignItem<'hir> {
pub ident: Ident,
pub attrs: &'hir [Attribute],
pub kind: ForeignItemKind<'hir>,
pub def_id: LocalDefId,
pub span: Span,
@ -3091,13 +3070,13 @@ impl<'hir> Node<'hir> {
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
mod size_asserts {
rustc_data_structures::static_assert_size!(super::Block<'static>, 48);
rustc_data_structures::static_assert_size!(super::Expr<'static>, 72);
rustc_data_structures::static_assert_size!(super::Expr<'static>, 64);
rustc_data_structures::static_assert_size!(super::Pat<'static>, 88);
rustc_data_structures::static_assert_size!(super::QPath<'static>, 24);
rustc_data_structures::static_assert_size!(super::Ty<'static>, 72);
rustc_data_structures::static_assert_size!(super::Item<'static>, 200);
rustc_data_structures::static_assert_size!(super::TraitItem<'static>, 144);
rustc_data_structures::static_assert_size!(super::ImplItem<'static>, 168);
rustc_data_structures::static_assert_size!(super::ForeignItem<'static>, 152);
rustc_data_structures::static_assert_size!(super::Item<'static>, 184);
rustc_data_structures::static_assert_size!(super::TraitItem<'static>, 128);
rustc_data_structures::static_assert_size!(super::ImplItem<'static>, 152);
rustc_data_structures::static_assert_size!(super::ForeignItem<'static>, 136);
}

View File

@ -1,4 +1,5 @@
use crate::def_id::{LocalDefId, CRATE_DEF_INDEX};
use rustc_index::vec::IndexVec;
use std::fmt;
/// Uniquely identifies a node in the HIR of the current crate. It is
@ -61,3 +62,69 @@ pub const CRATE_HIR_ID: HirId = HirId {
owner: LocalDefId { local_def_index: CRATE_DEF_INDEX },
local_id: ItemLocalId::from_u32(0),
};
#[derive(Clone, Default, Debug, Encodable, Decodable)]
pub struct HirIdVec<T> {
map: IndexVec<LocalDefId, IndexVec<ItemLocalId, T>>,
}
impl<T> HirIdVec<T> {
pub fn push_owner(&mut self, id: LocalDefId) {
self.map.ensure_contains_elem(id, IndexVec::new);
}
pub fn push(&mut self, id: HirId, value: T) {
if id.local_id == ItemLocalId::from_u32(0) {
self.push_owner(id.owner);
}
let submap = &mut self.map[id.owner];
let _ret_id = submap.push(value);
debug_assert_eq!(_ret_id, id.local_id);
}
pub fn push_sparse(&mut self, id: HirId, value: T)
where
T: Default,
{
self.map.ensure_contains_elem(id.owner, IndexVec::new);
let submap = &mut self.map[id.owner];
let i = id.local_id.index();
let len = submap.len();
if i >= len {
submap.extend(std::iter::repeat_with(T::default).take(i - len + 1));
}
submap[id.local_id] = value;
}
pub fn get(&self, id: HirId) -> Option<&T> {
self.map.get(id.owner)?.get(id.local_id)
}
pub fn get_owner(&self, id: LocalDefId) -> &IndexVec<ItemLocalId, T> {
&self.map[id]
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.map.iter().flat_map(|la| la.iter())
}
pub fn iter_enumerated(&self) -> impl Iterator<Item = (HirId, &T)> {
self.map.iter_enumerated().flat_map(|(owner, la)| {
la.iter_enumerated().map(move |(local_id, attr)| (HirId { owner, local_id }, attr))
})
}
}
impl<T> std::ops::Index<HirId> for HirIdVec<T> {
type Output = T;
fn index(&self, id: HirId) -> &T {
&self.map[id.owner][id.local_id]
}
}
impl<T> std::ops::IndexMut<HirId> for HirIdVec<T> {
fn index_mut(&mut self, id: HirId) -> &mut T {
&mut self.map[id.owner][id.local_id]
}
}

View File

@ -101,29 +101,21 @@ where
#[derive(Copy, Clone)]
pub enum FnKind<'a> {
/// `#[xxx] pub async/const/extern "Abi" fn foo()`
ItemFn(Ident, &'a Generics<'a>, FnHeader, &'a Visibility<'a>, &'a [Attribute]),
ItemFn(Ident, &'a Generics<'a>, FnHeader, &'a Visibility<'a>),
/// `fn foo(&self)`
Method(Ident, &'a FnSig<'a>, Option<&'a Visibility<'a>>, &'a [Attribute]),
Method(Ident, &'a FnSig<'a>, Option<&'a Visibility<'a>>),
/// `|x, y| {}`
Closure(&'a [Attribute]),
Closure,
}
impl<'a> FnKind<'a> {
pub fn attrs(&self) -> &'a [Attribute] {
match *self {
FnKind::ItemFn(.., attrs) => attrs,
FnKind::Method(.., attrs) => attrs,
FnKind::Closure(attrs) => attrs,
}
}
pub fn header(&self) -> Option<&FnHeader> {
match *self {
FnKind::ItemFn(_, _, ref header, _, _) => Some(header),
FnKind::Method(_, ref sig, _, _) => Some(&sig.header),
FnKind::Closure(_) => None,
FnKind::ItemFn(_, _, ref header, _) => Some(header),
FnKind::Method(_, ref sig, _) => Some(&sig.header),
FnKind::Closure => None,
}
}
}
@ -466,7 +458,7 @@ pub trait Visitor<'v>: Sized {
fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding<'v>) {
walk_assoc_type_binding(self, type_binding)
}
fn visit_attribute(&mut self, _attr: &'v Attribute) {}
fn visit_attribute(&mut self, _id: HirId, _attr: &'v Attribute) {}
fn visit_macro_def(&mut self, macro_def: &'v MacroDef<'v>) {
walk_macro_def(self, macro_def)
}
@ -484,14 +476,17 @@ pub trait Visitor<'v>: Sized {
/// Walks the contents of a crate. See also `Crate::visit_all_items`.
pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate<'v>) {
visitor.visit_mod(&krate.item.module, krate.item.span, CRATE_HIR_ID);
walk_list!(visitor, visit_attribute, krate.item.attrs);
walk_list!(visitor, visit_macro_def, krate.exported_macros);
for (&id, attrs) in krate.attrs.iter() {
for a in *attrs {
visitor.visit_attribute(id, a)
}
}
}
pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef<'v>) {
visitor.visit_id(macro_def.hir_id());
visitor.visit_ident(macro_def.ident);
walk_list!(visitor, visit_attribute, macro_def.attrs);
}
pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod<'v>, mod_hir_id: HirId) {
@ -510,7 +505,6 @@ pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local<'v>) {
// Intentionally visiting the expr first - the initialization expr
// dominates the local's definition.
walk_list!(visitor, visit_expr, &local.init);
walk_list!(visitor, visit_attribute, local.attrs.iter());
visitor.visit_id(local.hir_id);
visitor.visit_pat(&local.pat);
walk_list!(visitor, visit_ty, &local.ty);
@ -557,7 +551,6 @@ pub fn walk_trait_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_ref: &'v TraitR
pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) {
visitor.visit_id(param.hir_id);
visitor.visit_pat(&param.pat);
walk_list!(visitor, visit_attribute, param.attrs);
}
pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
@ -579,7 +572,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
visitor.visit_nested_body(body);
}
ItemKind::Fn(ref sig, ref generics, body_id) => visitor.visit_fn(
FnKind::ItemFn(item.ident, generics, sig.header, &item.vis, &item.attrs),
FnKind::ItemFn(item.ident, generics, sig.header, &item.vis),
&sig.decl,
body_id,
item.span,
@ -652,7 +645,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
walk_list!(visitor, visit_param_bound, bounds);
}
}
walk_list!(visitor, visit_attribute, item.attrs);
}
pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path<'v>, hir_id: HirId) {
@ -686,7 +678,6 @@ pub fn walk_variant<'v, V: Visitor<'v>>(
variant.span,
);
walk_list!(visitor, visit_anon_const, &variant.disr_expr);
walk_list!(visitor, visit_attribute, variant.attrs);
}
pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
@ -851,8 +842,6 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v
ForeignItemKind::Static(ref typ, _) => visitor.visit_ty(typ),
ForeignItemKind::Type => (),
}
walk_list!(visitor, visit_attribute, foreign_item.attrs);
}
pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericBound<'v>) {
@ -870,7 +859,6 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericB
pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v GenericParam<'v>) {
visitor.visit_id(param.hir_id);
walk_list!(visitor, visit_attribute, param.attrs);
match param.name {
ParamName::Plain(ident) => visitor.visit_ident(ident),
ParamName::Error | ParamName::Fresh(_) => {}
@ -940,7 +928,7 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'
FnKind::ItemFn(_, generics, ..) => {
visitor.visit_generics(generics);
}
FnKind::Method(..) | FnKind::Closure(_) => {}
FnKind::Method(..) | FnKind::Closure => {}
}
}
@ -960,7 +948,6 @@ pub fn walk_fn<'v, V: Visitor<'v>>(
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem<'v>) {
visitor.visit_ident(trait_item.ident);
walk_list!(visitor, visit_attribute, trait_item.attrs);
visitor.visit_generics(&trait_item.generics);
match trait_item.kind {
TraitItemKind::Const(ref ty, default) => {
@ -977,7 +964,7 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
}
TraitItemKind::Fn(ref sig, TraitFn::Provided(body_id)) => {
visitor.visit_fn(
FnKind::Method(trait_item.ident, sig, None, &trait_item.attrs),
FnKind::Method(trait_item.ident, sig, None),
&sig.decl,
body_id,
trait_item.span,
@ -1003,21 +990,12 @@ pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_item_ref:
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem<'v>) {
// N.B., deliberately force a compilation error if/when new fields are added.
let ImplItem {
def_id: _,
ident,
ref vis,
ref defaultness,
attrs,
ref generics,
ref kind,
span: _,
} = *impl_item;
let ImplItem { def_id: _, ident, ref vis, ref defaultness, ref generics, ref kind, span: _ } =
*impl_item;
visitor.visit_ident(ident);
visitor.visit_vis(vis);
visitor.visit_defaultness(defaultness);
walk_list!(visitor, visit_attribute, attrs);
visitor.visit_generics(generics);
match *kind {
ImplItemKind::Const(ref ty, body) => {
@ -1027,7 +1005,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
}
ImplItemKind::Fn(ref sig, body_id) => {
visitor.visit_fn(
FnKind::Method(impl_item.ident, sig, Some(&impl_item.vis), &impl_item.attrs),
FnKind::Method(impl_item.ident, sig, Some(&impl_item.vis)),
&sig.decl,
body_id,
impl_item.span,
@ -1075,7 +1053,6 @@ pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v
visitor.visit_vis(&struct_field.vis);
visitor.visit_ident(struct_field.ident);
visitor.visit_ty(&struct_field.ty);
walk_list!(visitor, visit_attribute, struct_field.attrs);
}
pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block<'v>) {
@ -1102,7 +1079,6 @@ pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonCo
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) {
visitor.visit_id(expression.hir_id);
walk_list!(visitor, visit_attribute, expression.attrs.iter());
match expression.kind {
ExprKind::Box(ref subexpression) => visitor.visit_expr(subexpression),
ExprKind::Array(subexpressions) => {
@ -1162,7 +1138,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
}
ExprKind::Closure(_, ref function_declaration, body, _fn_decl_span, _gen) => visitor
.visit_fn(
FnKind::Closure(&expression.attrs),
FnKind::Closure,
function_declaration,
body,
expression.span,
@ -1246,7 +1222,6 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) {
}
}
visitor.visit_expr(&arm.body);
walk_list!(visitor, visit_attribute, arm.attrs);
}
pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility<'v>) {

View File

@ -139,11 +139,10 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for VisibilityKind<'_>
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for TraitItem<'_> {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
let TraitItem { def_id: _, ident, ref attrs, ref generics, ref kind, span } = *self;
let TraitItem { def_id: _, ident, ref generics, ref kind, span } = *self;
hcx.hash_hir_item_like(|hcx| {
ident.name.hash_stable(hcx, hasher);
attrs.hash_stable(hcx, hasher);
generics.hash_stable(hcx, hasher);
kind.hash_stable(hcx, hasher);
span.hash_stable(hcx, hasher);
@ -153,22 +152,13 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for TraitItem<'_> {
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ImplItem<'_> {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
let ImplItem {
def_id: _,
ident,
ref vis,
defaultness,
ref attrs,
ref generics,
ref kind,
span,
} = *self;
let ImplItem { def_id: _, ident, ref vis, defaultness, ref generics, ref kind, span } =
*self;
hcx.hash_hir_item_like(|hcx| {
ident.name.hash_stable(hcx, hasher);
vis.hash_stable(hcx, hasher);
defaultness.hash_stable(hcx, hasher);
attrs.hash_stable(hcx, hasher);
generics.hash_stable(hcx, hasher);
kind.hash_stable(hcx, hasher);
span.hash_stable(hcx, hasher);
@ -178,11 +168,10 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ImplItem<'_> {
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ForeignItem<'_> {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
let ForeignItem { def_id: _, ident, ref attrs, ref kind, span, ref vis } = *self;
let ForeignItem { def_id: _, ident, ref kind, span, ref vis } = *self;
hcx.hash_hir_item_like(|hcx| {
ident.name.hash_stable(hcx, hasher);
attrs.hash_stable(hcx, hasher);
kind.hash_stable(hcx, hasher);
span.hash_stable(hcx, hasher);
vis.hash_stable(hcx, hasher);
@ -192,11 +181,10 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ForeignItem<'_> {
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Item<'_> {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
let Item { ident, ref attrs, def_id: _, ref kind, ref vis, span } = *self;
let Item { ident, def_id: _, ref kind, ref vis, span } = *self;
hcx.hash_hir_item_like(|hcx| {
ident.name.hash_stable(hcx, hasher);
attrs.hash_stable(hcx, hasher);
kind.hash_stable(hcx, hasher);
vis.hash_stable(hcx, hasher);
span.hash_stable(hcx, hasher);
@ -206,11 +194,10 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Item<'_> {
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for MacroDef<'_> {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
let MacroDef { ident, ref attrs, def_id: _, ref ast, ref vis, span } = *self;
let MacroDef { ident, def_id: _, ref ast, ref vis, span } = *self;
hcx.hash_hir_item_like(|hcx| {
ident.name.hash_stable(hcx, hasher);
attrs.hash_stable(hcx, hasher);
ast.hash_stable(hcx, hasher);
vis.hash_stable(hcx, hasher);
span.hash_stable(hcx, hasher);

View File

@ -16,6 +16,7 @@ use rustc_target::spec::abi::Abi;
use std::borrow::Cow;
use std::cell::Cell;
use std::collections::BTreeMap;
use std::vec;
pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: hir::HirId) -> String {
@ -82,6 +83,7 @@ impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> {
pub struct State<'a> {
pub s: pp::Printer,
comments: Option<Comments<'a>>,
attrs: &'a BTreeMap<hir::HirId, &'a [ast::Attribute]>,
ann: &'a (dyn PpAnn + 'a),
}
@ -163,12 +165,12 @@ pub fn print_crate<'a>(
input: String,
ann: &'a dyn PpAnn,
) -> String {
let mut s = State::new_from_input(sm, filename, input, ann);
let mut s = State::new_from_input(sm, filename, input, &krate.attrs, ann);
// When printing the AST, we sometimes need to inject `#[no_std]` here.
// Since you can't compile the HIR, it's not necessary.
s.print_mod(&krate.item.module, &krate.item.attrs);
s.print_mod(&krate.item.module, s.attrs(hir::CRATE_HIR_ID));
s.print_remaining_comments();
s.s.eof()
}
@ -178,9 +180,19 @@ impl<'a> State<'a> {
sm: &'a SourceMap,
filename: FileName,
input: String,
attrs: &'a BTreeMap<hir::HirId, &[ast::Attribute]>,
ann: &'a dyn PpAnn,
) -> State<'a> {
State { s: pp::mk_printer(), comments: Some(Comments::new(sm, filename, input)), ann }
State {
s: pp::mk_printer(),
comments: Some(Comments::new(sm, filename, input)),
attrs,
ann,
}
}
fn attrs(&self, id: hir::HirId) -> &'a [ast::Attribute] {
self.attrs.get(&id).map_or(&[], |la| *la)
}
}
@ -188,7 +200,8 @@ pub fn to_string<F>(ann: &dyn PpAnn, f: F) -> String
where
F: FnOnce(&mut State<'_>),
{
let mut printer = State { s: pp::mk_printer(), comments: None, ann };
let mut printer =
State { s: pp::mk_printer(), comments: None, attrs: &BTreeMap::default(), ann };
f(&mut printer);
printer.s.eof()
}
@ -441,7 +454,7 @@ impl<'a> State<'a> {
pub fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
self.hardbreak_if_not_bol();
self.maybe_print_comment(item.span.lo());
self.print_outer_attributes(&item.attrs);
self.print_outer_attributes(self.attrs(item.hir_id()));
match item.kind {
hir::ForeignItemKind::Fn(ref decl, ref arg_names, ref generics) => {
self.head("");
@ -549,7 +562,8 @@ impl<'a> State<'a> {
pub fn print_item(&mut self, item: &hir::Item<'_>) {
self.hardbreak_if_not_bol();
self.maybe_print_comment(item.span.lo());
self.print_outer_attributes(&item.attrs);
let attrs = self.attrs(item.hir_id());
self.print_outer_attributes(attrs);
self.ann.pre(self, AnnNode::Item(item));
match item.kind {
hir::ItemKind::ExternCrate(orig_name) => {
@ -634,14 +648,14 @@ impl<'a> State<'a> {
self.print_ident(item.ident);
self.nbsp();
self.bopen();
self.print_mod(_mod, &item.attrs);
self.print_mod(_mod, attrs);
self.bclose(item.span);
}
hir::ItemKind::ForeignMod { abi, items } => {
self.head("extern");
self.word_nbsp(abi.to_string());
self.bopen();
self.print_inner_attributes(item.attrs);
self.print_inner_attributes(self.attrs(item.hir_id()));
for item in items {
self.ann.nested(self, Nested::ForeignItem(item.id));
}
@ -725,7 +739,7 @@ impl<'a> State<'a> {
self.s.space();
self.bopen();
self.print_inner_attributes(&item.attrs);
self.print_inner_attributes(attrs);
for impl_item in items {
self.ann.nested(self, Nested::ImplItem(impl_item.id));
}
@ -822,7 +836,7 @@ impl<'a> State<'a> {
for v in variants {
self.space_if_not_bol();
self.maybe_print_comment(v.span.lo());
self.print_outer_attributes(&v.attrs);
self.print_outer_attributes(self.attrs(v.id));
self.ibox(INDENT_UNIT);
self.print_variant(v);
self.s.word(",");
@ -876,7 +890,7 @@ impl<'a> State<'a> {
self.popen();
self.commasep(Inconsistent, struct_def.fields(), |s, field| {
s.maybe_print_comment(field.span.lo());
s.print_outer_attributes(&field.attrs);
s.print_outer_attributes(s.attrs(field.hir_id));
s.print_visibility(&field.vis);
s.print_type(&field.ty)
});
@ -898,7 +912,7 @@ impl<'a> State<'a> {
for field in struct_def.fields() {
self.hardbreak_if_not_bol();
self.maybe_print_comment(field.span.lo());
self.print_outer_attributes(&field.attrs);
self.print_outer_attributes(self.attrs(field.hir_id));
self.print_visibility(&field.vis);
self.print_ident(field.ident);
self.word_nbsp(":");
@ -937,7 +951,7 @@ impl<'a> State<'a> {
self.ann.pre(self, AnnNode::SubItem(ti.hir_id()));
self.hardbreak_if_not_bol();
self.maybe_print_comment(ti.span.lo());
self.print_outer_attributes(&ti.attrs);
self.print_outer_attributes(self.attrs(ti.hir_id()));
match ti.kind {
hir::TraitItemKind::Const(ref ty, default) => {
let vis =
@ -976,7 +990,7 @@ impl<'a> State<'a> {
self.ann.pre(self, AnnNode::SubItem(ii.hir_id()));
self.hardbreak_if_not_bol();
self.maybe_print_comment(ii.span.lo());
self.print_outer_attributes(&ii.attrs);
self.print_outer_attributes(self.attrs(ii.hir_id()));
self.print_defaultness(ii.defaultness);
match ii.kind {
@ -1321,7 +1335,7 @@ impl<'a> State<'a> {
pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
self.maybe_print_comment(expr.span.lo());
self.print_outer_attributes(&expr.attrs);
self.print_outer_attributes(self.attrs(expr.hir_id));
self.ibox(INDENT_UNIT);
self.ann.pre(self, AnnNode::Expr(expr));
match expr.kind {
@ -2020,20 +2034,20 @@ impl<'a> State<'a> {
}
pub fn print_param(&mut self, arg: &hir::Param<'_>) {
self.print_outer_attributes(&arg.attrs);
self.print_outer_attributes(self.attrs(arg.hir_id));
self.print_pat(&arg.pat);
}
pub fn print_arm(&mut self, arm: &hir::Arm<'_>) {
// I have no idea why this check is necessary, but here it
// is :(
if arm.attrs.is_empty() {
if self.attrs(arm.hir_id).is_empty() {
self.s.space();
}
self.cbox(INDENT_UNIT);
self.ann.pre(self, AnnNode::Arm(arm));
self.ibox(0);
self.print_outer_attributes(&arm.attrs);
self.print_outer_attributes(&self.attrs(arm.hir_id));
self.print_pat(&arm.pat);
self.s.space();
if let Some(ref g) = arm.guard {

View File

@ -68,7 +68,7 @@ pub fn assert_dep_graph(tcx: TyCtxt<'_>) {
let (if_this_changed, then_this_would_need) = {
let mut visitor =
IfThisChanged { tcx, if_this_changed: vec![], then_this_would_need: vec![] };
visitor.process_attrs(hir::CRATE_HIR_ID, &tcx.hir().krate().item.attrs);
visitor.process_attrs(hir::CRATE_HIR_ID);
tcx.hir().krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
(visitor.if_this_changed, visitor.then_this_would_need)
};
@ -113,9 +113,10 @@ impl IfThisChanged<'tcx> {
value
}
fn process_attrs(&mut self, hir_id: hir::HirId, attrs: &[ast::Attribute]) {
fn process_attrs(&mut self, hir_id: hir::HirId) {
let def_id = self.tcx.hir().local_def_id(hir_id);
let def_path_hash = self.tcx.def_path_hash(def_id.to_def_id());
let attrs = self.tcx.hir().attrs(hir_id);
for attr in attrs {
if self.tcx.sess.check_name(attr, sym::rustc_if_this_changed) {
let dep_node_interned = self.argument(attr);
@ -167,22 +168,22 @@ impl Visitor<'tcx> for IfThisChanged<'tcx> {
}
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
self.process_attrs(item.hir_id(), &item.attrs);
self.process_attrs(item.hir_id());
intravisit::walk_item(self, item);
}
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
self.process_attrs(trait_item.hir_id(), &trait_item.attrs);
self.process_attrs(trait_item.hir_id());
intravisit::walk_trait_item(self, trait_item);
}
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
self.process_attrs(impl_item.hir_id(), &impl_item.attrs);
self.process_attrs(impl_item.hir_id());
intravisit::walk_impl_item(self, impl_item);
}
fn visit_struct_field(&mut self, s: &'tcx hir::StructField<'tcx>) {
self.process_attrs(s.hir_id, &s.attrs);
self.process_attrs(s.hir_id);
intravisit::walk_struct_field(self, s);
}
}

View File

@ -44,7 +44,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) {
let ams = AssertModuleSource { tcx, available_cgus };
for attr in tcx.hir().krate().item.attrs {
for attr in tcx.hir().attrs(rustc_hir::CRATE_HIR_ID) {
ams.check_attr(attr);
}
})

View File

@ -168,7 +168,7 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
// Note that we cannot use the existing "unused attribute"-infrastructure
// here, since that is running before codegen. This is also the reason why
// all codegen-specific attributes are `AssumedUsed` in rustc_ast::feature_gate.
all_attrs.report_unchecked_attrs(&dirty_clean_visitor.checked_attrs);
all_attrs.report_unchecked_attrs(dirty_clean_visitor.checked_attrs);
})
}
@ -535,13 +535,14 @@ impl FindAllAttrs<'_, 'tcx> {
false
}
fn report_unchecked_attrs(&self, checked_attrs: &FxHashSet<ast::AttrId>) {
fn report_unchecked_attrs(&self, mut checked_attrs: FxHashSet<ast::AttrId>) {
for attr in &self.found_attrs {
if !checked_attrs.contains(&attr.id) {
self.tcx.sess.span_err(
attr.span,
"found unchecked `#[rustc_dirty]` / `#[rustc_clean]` attribute",
);
checked_attrs.insert(attr.id);
}
}
}
@ -554,7 +555,7 @@ impl intravisit::Visitor<'tcx> for FindAllAttrs<'_, 'tcx> {
intravisit::NestedVisitorMap::All(self.tcx.hir())
}
fn visit_attribute(&mut self, attr: &'tcx Attribute) {
fn visit_attribute(&mut self, _: hir::HirId, attr: &'tcx Attribute) {
if self.is_active_attr(attr) {
self.found_attrs.push(attr);
}

View File

@ -695,9 +695,7 @@ impl<I: Idx, T> IndexVec<I, T> {
pub fn convert_index_type<Ix: Idx>(self) -> IndexVec<Ix, T> {
IndexVec { raw: self.raw, _marker: PhantomData }
}
}
impl<I: Idx, T: Clone> IndexVec<I, T> {
/// Grows the index vector so that it contains an entry for
/// `elem`; if that is already true, then has no
/// effect. Otherwise, inserts new values as needed by invoking
@ -710,11 +708,6 @@ impl<I: Idx, T: Clone> IndexVec<I, T> {
}
}
#[inline]
pub fn resize(&mut self, new_len: usize, value: T) {
self.raw.resize(new_len, value)
}
#[inline]
pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
let min_new_len = elem.index() + 1;
@ -722,6 +715,13 @@ impl<I: Idx, T: Clone> IndexVec<I, T> {
}
}
impl<I: Idx, T: Clone> IndexVec<I, T> {
#[inline]
pub fn resize(&mut self, new_len: usize, value: T) {
self.raw.resize(new_len, value)
}
}
impl<I: Idx, T: Ord> IndexVec<I, T> {
#[inline]
pub fn binary_search(&self, value: &T) -> Result<I, I> {

View File

@ -25,7 +25,8 @@ struct Finder<'tcx> {
impl<'v> ItemLikeVisitor<'v> for Finder<'_> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
if self.tcx.sess.contains_name(&item.attrs, sym::rustc_proc_macro_decls) {
let attrs = self.tcx.hir().attrs(item.hir_id());
if self.tcx.sess.contains_name(attrs, sym::rustc_proc_macro_decls) {
self.decls = Some(item.hir_id());
}
}

View File

@ -508,8 +508,7 @@ impl MissingDoc {
fn check_missing_docs_attrs(
&self,
cx: &LateContext<'_>,
id: Option<hir::HirId>,
attrs: &[ast::Attribute],
id: hir::HirId,
sp: Span,
article: &'static str,
desc: &'static str,
@ -528,12 +527,13 @@ impl MissingDoc {
// Only check publicly-visible items, using the result from the privacy pass.
// It's an option so the crate root can also use this function (it doesn't
// have a `NodeId`).
if let Some(id) = id {
if id != hir::CRATE_HIR_ID {
if !cx.access_levels.is_exported(id) {
return;
}
}
let attrs = cx.tcx.hir().attrs(id);
let has_doc = attrs.iter().any(|a| has_doc(cx.sess(), a));
if !has_doc {
cx.struct_span_lint(
@ -565,10 +565,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
}
fn check_crate(&mut self, cx: &LateContext<'_>, krate: &hir::Crate<'_>) {
self.check_missing_docs_attrs(cx, None, &krate.item.attrs, krate.item.span, "the", "crate");
self.check_missing_docs_attrs(cx, hir::CRATE_HIR_ID, krate.item.span, "the", "crate");
for macro_def in krate.exported_macros {
let has_doc = macro_def.attrs.iter().any(|a| has_doc(cx.sess(), a));
let attrs = cx.tcx.hir().attrs(macro_def.hir_id());
let has_doc = attrs.iter().any(|a| has_doc(cx.sess(), a));
if !has_doc {
cx.struct_span_lint(
MISSING_DOCS,
@ -622,7 +623,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
let (article, desc) = cx.tcx.article_and_description(it.def_id.to_def_id());
self.check_missing_docs_attrs(cx, Some(it.hir_id()), &it.attrs, it.span, article, desc);
self.check_missing_docs_attrs(cx, it.hir_id(), it.span, article, desc);
}
fn check_trait_item(&mut self, cx: &LateContext<'_>, trait_item: &hir::TraitItem<'_>) {
@ -632,14 +633,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
let (article, desc) = cx.tcx.article_and_description(trait_item.def_id.to_def_id());
self.check_missing_docs_attrs(
cx,
Some(trait_item.hir_id()),
&trait_item.attrs,
trait_item.span,
article,
desc,
);
self.check_missing_docs_attrs(cx, trait_item.hir_id(), trait_item.span, article, desc);
}
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
@ -649,43 +643,22 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
}
let (article, desc) = cx.tcx.article_and_description(impl_item.def_id.to_def_id());
self.check_missing_docs_attrs(
cx,
Some(impl_item.hir_id()),
&impl_item.attrs,
impl_item.span,
article,
desc,
);
self.check_missing_docs_attrs(cx, impl_item.hir_id(), impl_item.span, article, desc);
}
fn check_foreign_item(&mut self, cx: &LateContext<'_>, foreign_item: &hir::ForeignItem<'_>) {
let (article, desc) = cx.tcx.article_and_description(foreign_item.def_id.to_def_id());
self.check_missing_docs_attrs(
cx,
Some(foreign_item.hir_id()),
&foreign_item.attrs,
foreign_item.span,
article,
desc,
);
self.check_missing_docs_attrs(cx, foreign_item.hir_id(), foreign_item.span, article, desc);
}
fn check_struct_field(&mut self, cx: &LateContext<'_>, sf: &hir::StructField<'_>) {
if !sf.is_positional() {
self.check_missing_docs_attrs(
cx,
Some(sf.hir_id),
&sf.attrs,
sf.span,
"a",
"struct field",
)
self.check_missing_docs_attrs(cx, sf.hir_id, sf.span, "a", "struct field")
}
}
fn check_variant(&mut self, cx: &LateContext<'_>, v: &hir::Variant<'_>) {
self.check_missing_docs_attrs(cx, Some(v.id), &v.attrs, v.span, "a", "variant");
self.check_missing_docs_attrs(cx, v.id, v.span, "a", "variant");
}
}
@ -1119,9 +1092,10 @@ declare_lint_pass!(InvalidNoMangleItems => [NO_MANGLE_CONST_ITEMS, NO_MANGLE_GEN
impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
let attrs = cx.tcx.hir().attrs(it.hir_id());
match it.kind {
hir::ItemKind::Fn(.., ref generics, _) => {
if let Some(no_mangle_attr) = cx.sess().find_by_name(&it.attrs, sym::no_mangle) {
if let Some(no_mangle_attr) = cx.sess().find_by_name(attrs, sym::no_mangle) {
for param in generics.params {
match param.kind {
GenericParamKind::Lifetime { .. } => {}
@ -1147,7 +1121,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
}
}
hir::ItemKind::Const(..) => {
if cx.sess().contains_name(&it.attrs, sym::no_mangle) {
if cx.sess().contains_name(attrs, sym::no_mangle) {
// Const items do not refer to a particular location in memory, and therefore
// don't have anything to attach a symbol to
cx.struct_span_lint(NO_MANGLE_CONST_ITEMS, it.span, |lint| {
@ -1827,7 +1801,8 @@ impl<'tcx> LateLintPass<'tcx> for UnnameableTestItems {
return;
}
if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::rustc_test_marker) {
let attrs = cx.tcx.hir().attrs(it.hir_id());
if let Some(attr) = cx.sess().find_by_name(attrs, sym::rustc_test_marker) {
cx.struct_span_lint(UNNAMEABLE_TEST_ITEMS, attr.span, |lint| {
lint.build("cannot test inner items").emit()
});

View File

@ -283,7 +283,7 @@ fn is_doc_keyword(s: Symbol) -> bool {
impl<'tcx> LateLintPass<'tcx> for ExistingDocKeyword {
fn check_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::Item<'_>) {
for attr in item.attrs {
for attr in cx.tcx.hir().attrs(item.hir_id()) {
if !attr.has_name(sym::doc) {
continue;
}

View File

@ -16,7 +16,6 @@
use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore};
use rustc_ast as ast;
use rustc_ast::walk_list;
use rustc_data_structures::sync::{join, par_iter, ParallelIterator};
use rustc_hir as hir;
use rustc_hir::def_id::{LocalDefId, LOCAL_CRATE};
@ -53,10 +52,11 @@ impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> {
/// Merge the lints specified by any lint attributes into the
/// current lint context, call the provided function, then reset the
/// lints in effect to their previous state.
fn with_lint_attrs<F>(&mut self, id: hir::HirId, attrs: &'tcx [ast::Attribute], f: F)
fn with_lint_attrs<F>(&mut self, id: hir::HirId, f: F)
where
F: FnOnce(&mut Self),
{
let attrs = self.context.tcx.hir().attrs(id);
let prev = self.context.last_node_with_lint_attrs;
self.context.last_node_with_lint_attrs = id;
self.enter_attrs(attrs);
@ -125,7 +125,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
}
fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
self.with_lint_attrs(param.hir_id, &param.attrs, |cx| {
self.with_lint_attrs(param.hir_id, |cx| {
lint_callback!(cx, check_param, param);
hir_visit::walk_param(cx, param);
});
@ -142,7 +142,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
self.context.generics = it.kind.generics();
let old_cached_typeck_results = self.context.cached_typeck_results.take();
let old_enclosing_body = self.context.enclosing_body.take();
self.with_lint_attrs(it.hir_id(), &it.attrs, |cx| {
self.with_lint_attrs(it.hir_id(), |cx| {
cx.with_param_env(it.hir_id(), |cx| {
lint_callback!(cx, check_item, it);
hir_visit::walk_item(cx, it);
@ -155,7 +155,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
}
fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) {
self.with_lint_attrs(it.hir_id(), &it.attrs, |cx| {
self.with_lint_attrs(it.hir_id(), |cx| {
cx.with_param_env(it.hir_id(), |cx| {
lint_callback!(cx, check_foreign_item, it);
hir_visit::walk_foreign_item(cx, it);
@ -170,7 +170,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
}
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
self.with_lint_attrs(e.hir_id, &e.attrs, |cx| {
self.with_lint_attrs(e.hir_id, |cx| {
lint_callback!(cx, check_expr, e);
hir_visit::walk_expr(cx, e);
lint_callback!(cx, check_expr_post, e);
@ -178,11 +178,9 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
}
fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
let get_item = |id: hir::ItemId| self.context.tcx.hir().item(id);
let attrs = &s.kind.attrs(get_item);
// See `EarlyContextAndPass::visit_stmt` for an explanation
// of why we call `walk_stmt` outside of `with_lint_attrs`
self.with_lint_attrs(s.hir_id, attrs, |cx| {
self.with_lint_attrs(s.hir_id, |cx| {
lint_callback!(cx, check_stmt, s);
});
hir_visit::walk_stmt(self, s);
@ -222,7 +220,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
}
fn visit_struct_field(&mut self, s: &'tcx hir::StructField<'tcx>) {
self.with_lint_attrs(s.hir_id, &s.attrs, |cx| {
self.with_lint_attrs(s.hir_id, |cx| {
lint_callback!(cx, check_struct_field, s);
hir_visit::walk_struct_field(cx, s);
})
@ -234,7 +232,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
g: &'tcx hir::Generics<'tcx>,
item_id: hir::HirId,
) {
self.with_lint_attrs(v.id, &v.attrs, |cx| {
self.with_lint_attrs(v.id, |cx| {
lint_callback!(cx, check_variant, v);
hir_visit::walk_variant(cx, v, g, item_id);
lint_callback!(cx, check_variant_post, v);
@ -257,7 +255,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
}
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
self.with_lint_attrs(l.hir_id, &l.attrs, |cx| {
self.with_lint_attrs(l.hir_id, |cx| {
lint_callback!(cx, check_local, l);
hir_visit::walk_local(cx, l);
})
@ -301,7 +299,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
let generics = self.context.generics.take();
self.context.generics = Some(&trait_item.generics);
self.with_lint_attrs(trait_item.hir_id(), &trait_item.attrs, |cx| {
self.with_lint_attrs(trait_item.hir_id(), |cx| {
cx.with_param_env(trait_item.hir_id(), |cx| {
lint_callback!(cx, check_trait_item, trait_item);
hir_visit::walk_trait_item(cx, trait_item);
@ -314,7 +312,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
let generics = self.context.generics.take();
self.context.generics = Some(&impl_item.generics);
self.with_lint_attrs(impl_item.hir_id(), &impl_item.attrs, |cx| {
self.with_lint_attrs(impl_item.hir_id(), |cx| {
cx.with_param_env(impl_item.hir_id(), |cx| {
lint_callback!(cx, check_impl_item, impl_item);
hir_visit::walk_impl_item(cx, impl_item);
@ -334,8 +332,10 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
hir_visit::walk_path(self, p);
}
fn visit_attribute(&mut self, attr: &'tcx ast::Attribute) {
lint_callback!(self, check_attribute, attr);
fn visit_attribute(&mut self, hir_id: hir::HirId, attr: &'tcx ast::Attribute) {
self.with_lint_attrs(hir_id, |cx| {
lint_callback!(cx, check_attribute, attr);
})
}
}
@ -396,7 +396,9 @@ fn late_lint_mod_pass<'tcx, T: LateLintPass<'tcx>>(
// Visit the crate attributes
if hir_id == hir::CRATE_HIR_ID {
walk_list!(cx, visit_attribute, tcx.hir().attrs(hir::CRATE_HIR_ID));
for attr in tcx.hir().attrs(hir::CRATE_HIR_ID).iter() {
cx.visit_attribute(hir_id, attr)
}
}
}
@ -440,7 +442,7 @@ fn late_lint_pass_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, pass: T)
let mut cx = LateContextAndPass { context, pass };
// Visit the whole crate.
cx.with_lint_attrs(hir::CRATE_HIR_ID, &krate.item.attrs, |cx| {
cx.with_lint_attrs(hir::CRATE_HIR_ID, |cx| {
// since the root module isn't visited as an item (because it isn't an
// item), warn for it here.
lint_callback!(cx, check_crate, krate);

View File

@ -38,7 +38,7 @@ fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> LintLevelMap {
builder.levels.id_to_set.reserve(krate.exported_macros.len() + 1);
let push = builder.levels.push(&krate.item.attrs, &store, true);
let push = builder.levels.push(tcx.hir().attrs(hir::CRATE_HIR_ID), &store, true);
builder.levels.register_id(hir::CRATE_HIR_ID);
for macro_def in krate.exported_macros {
builder.levels.register_id(macro_def.hir_id());
@ -566,11 +566,12 @@ struct LintLevelMapBuilder<'a, 'tcx> {
}
impl LintLevelMapBuilder<'_, '_> {
fn with_lint_attrs<F>(&mut self, id: hir::HirId, attrs: &[ast::Attribute], f: F)
fn with_lint_attrs<F>(&mut self, id: hir::HirId, f: F)
where
F: FnOnce(&mut Self),
{
let is_crate_hir = id == hir::CRATE_HIR_ID;
let attrs = self.tcx.hir().attrs(id);
let push = self.levels.push(attrs, self.store, is_crate_hir);
if push.changed {
self.levels.register_id(id);
@ -588,19 +589,19 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'_, 'tcx> {
}
fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
self.with_lint_attrs(param.hir_id, &param.attrs, |builder| {
self.with_lint_attrs(param.hir_id, |builder| {
intravisit::walk_param(builder, param);
});
}
fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
self.with_lint_attrs(it.hir_id(), &it.attrs, |builder| {
self.with_lint_attrs(it.hir_id(), |builder| {
intravisit::walk_item(builder, it);
});
}
fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) {
self.with_lint_attrs(it.hir_id(), &it.attrs, |builder| {
self.with_lint_attrs(it.hir_id(), |builder| {
intravisit::walk_foreign_item(builder, it);
})
}
@ -613,13 +614,13 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'_, 'tcx> {
}
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
self.with_lint_attrs(e.hir_id, &e.attrs, |builder| {
self.with_lint_attrs(e.hir_id, |builder| {
intravisit::walk_expr(builder, e);
})
}
fn visit_struct_field(&mut self, s: &'tcx hir::StructField<'tcx>) {
self.with_lint_attrs(s.hir_id, &s.attrs, |builder| {
self.with_lint_attrs(s.hir_id, |builder| {
intravisit::walk_struct_field(builder, s);
})
}
@ -630,31 +631,31 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'_, 'tcx> {
g: &'tcx hir::Generics<'tcx>,
item_id: hir::HirId,
) {
self.with_lint_attrs(v.id, &v.attrs, |builder| {
self.with_lint_attrs(v.id, |builder| {
intravisit::walk_variant(builder, v, g, item_id);
})
}
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
self.with_lint_attrs(l.hir_id, &l.attrs, |builder| {
self.with_lint_attrs(l.hir_id, |builder| {
intravisit::walk_local(builder, l);
})
}
fn visit_arm(&mut self, a: &'tcx hir::Arm<'tcx>) {
self.with_lint_attrs(a.hir_id, &a.attrs, |builder| {
self.with_lint_attrs(a.hir_id, |builder| {
intravisit::walk_arm(builder, a);
})
}
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
self.with_lint_attrs(trait_item.hir_id(), &trait_item.attrs, |builder| {
self.with_lint_attrs(trait_item.hir_id(), |builder| {
intravisit::walk_trait_item(builder, trait_item);
});
}
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
self.with_lint_attrs(impl_item.hir_id(), &impl_item.attrs, |builder| {
self.with_lint_attrs(impl_item.hir_id(), |builder| {
intravisit::walk_impl_item(builder, impl_item);
});
}

View File

@ -400,14 +400,15 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
}
_ => (),
},
FnKind::ItemFn(ident, _, header, _, attrs) => {
FnKind::ItemFn(ident, _, header, _) => {
let attrs = cx.tcx.hir().attrs(id);
// Skip foreign-ABI #[no_mangle] functions (Issue #31924)
if header.abi != Abi::Rust && cx.sess().contains_name(attrs, sym::no_mangle) {
return;
}
self.check_snake_case(cx, "function", ident);
}
FnKind::Closure(_) => (),
FnKind::Closure => (),
}
}
@ -504,8 +505,9 @@ impl NonUpperCaseGlobals {
impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
let attrs = cx.tcx.hir().attrs(it.hir_id());
match it.kind {
hir::ItemKind::Static(..) if !cx.sess().contains_name(&it.attrs, sym::no_mangle) => {
hir::ItemKind::Static(..) if !cx.sess().contains_name(attrs, sym::no_mangle) => {
NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident);
}
hir::ItemKind::Const(..) => {

View File

@ -406,6 +406,8 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAttributes {
if !cx.sess().is_attr_used(attr) {
debug!("emitting warning for: {:?}", attr);
cx.struct_span_lint(UNUSED_ATTRIBUTES, attr.span, |lint| {
// Mark as used to avoid duplicate warnings.
cx.sess().mark_attr_used(attr);
lint.build("unused attribute").emit()
});
// Is it a builtin attribute that must be used at the crate level?

View File

@ -8,7 +8,7 @@ crate fn collect(tcx: TyCtxt<'_>) -> Vec<String> {
let mut collector = Collector { tcx, args: Vec::new() };
tcx.hir().krate().visit_all_item_likes(&mut collector);
for attr in tcx.hir().krate().item.attrs.iter() {
for attr in tcx.hir().attrs(hir::CRATE_HIR_ID).iter() {
if attr.has_name(sym::link_args) {
if let Some(linkarg) = attr.value_str() {
collector.add_link_args(linkarg);
@ -36,7 +36,9 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
// First, add all of the custom #[link_args] attributes
let sess = &self.tcx.sess;
for m in it.attrs.iter().filter(|a| sess.check_name(a, sym::link_args)) {
for m in
self.tcx.hir().attrs(it.hir_id()).iter().filter(|a| sess.check_name(a, sym::link_args))
{
if let Some(linkarg) = m.value_str() {
self.add_link_args(linkarg);
}

View File

@ -44,7 +44,8 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
// Process all of the #[link(..)]-style arguments
let sess = &self.tcx.sess;
for m in it.attrs.iter().filter(|a| sess.check_name(a, sym::link)) {
for m in self.tcx.hir().attrs(it.hir_id()).iter().filter(|a| sess.check_name(a, sym::link))
{
let items = match m.meta_item_list() {
Some(item) => item,
None => continue,

View File

@ -12,7 +12,6 @@
//! for the `Code` associated with a particular NodeId.
use crate::hir::map::Map;
use rustc_ast::Attribute;
use rustc_hir as hir;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Expr, FnDecl, Node};
@ -105,7 +104,6 @@ struct ItemFnParts<'a> {
body: hir::BodyId,
id: hir::HirId,
span: Span,
attrs: &'a [Attribute],
}
/// These are all the components one can extract from a closure expr
@ -115,18 +113,11 @@ struct ClosureParts<'a> {
body: hir::BodyId,
id: hir::HirId,
span: Span,
attrs: &'a [Attribute],
}
impl<'a> ClosureParts<'a> {
fn new(
d: &'a FnDecl<'a>,
b: hir::BodyId,
id: hir::HirId,
s: Span,
attrs: &'a [Attribute],
) -> Self {
ClosureParts { decl: d, body: b, id, span: s, attrs }
fn new(d: &'a FnDecl<'a>, b: hir::BodyId, id: hir::HirId, s: Span) -> Self {
ClosureParts { decl: d, body: b, id, span: s }
}
}
@ -146,7 +137,7 @@ impl<'a> FnLikeNode<'a> {
pub fn body(self) -> hir::BodyId {
self.handle(
|i: ItemFnParts<'a>| i.body,
|_, _, _: &'a hir::FnSig<'a>, _, body: hir::BodyId, _, _| body,
|_, _, _: &'a hir::FnSig<'a>, _, body: hir::BodyId, _| body,
|c: ClosureParts<'a>| c.body,
)
}
@ -154,7 +145,7 @@ impl<'a> FnLikeNode<'a> {
pub fn decl(self) -> &'a FnDecl<'a> {
self.handle(
|i: ItemFnParts<'a>| &*i.decl,
|_, _, sig: &'a hir::FnSig<'a>, _, _, _, _| &sig.decl,
|_, _, sig: &'a hir::FnSig<'a>, _, _, _| &sig.decl,
|c: ClosureParts<'a>| c.decl,
)
}
@ -162,7 +153,7 @@ impl<'a> FnLikeNode<'a> {
pub fn span(self) -> Span {
self.handle(
|i: ItemFnParts<'_>| i.span,
|_, _, _: &'a hir::FnSig<'a>, _, _, span, _| span,
|_, _, _: &'a hir::FnSig<'a>, _, _, span| span,
|c: ClosureParts<'_>| c.span,
)
}
@ -170,7 +161,7 @@ impl<'a> FnLikeNode<'a> {
pub fn id(self) -> hir::HirId {
self.handle(
|i: ItemFnParts<'_>| i.id,
|id, _, _: &'a hir::FnSig<'a>, _, _, _, _| id,
|id, _, _: &'a hir::FnSig<'a>, _, _, _| id,
|c: ClosureParts<'_>| c.id,
)
}
@ -189,12 +180,11 @@ impl<'a> FnLikeNode<'a> {
pub fn kind(self) -> FnKind<'a> {
let item = |p: ItemFnParts<'a>| -> FnKind<'a> {
FnKind::ItemFn(p.ident, p.generics, p.header, p.vis, p.attrs)
};
let closure = |c: ClosureParts<'a>| FnKind::Closure(c.attrs);
let method = |_, ident: Ident, sig: &'a hir::FnSig<'a>, vis, _, _, attrs| {
FnKind::Method(ident, sig, vis, attrs)
FnKind::ItemFn(p.ident, p.generics, p.header, p.vis)
};
let closure = |_: ClosureParts<'a>| FnKind::Closure;
let method =
|_, ident: Ident, sig: &'a hir::FnSig<'a>, vis, _, _| FnKind::Method(ident, sig, vis);
self.handle(item, method, closure)
}
@ -208,7 +198,6 @@ impl<'a> FnLikeNode<'a> {
Option<&'a hir::Visibility<'a>>,
hir::BodyId,
Span,
&'a [Attribute],
) -> A,
C: FnOnce(ClosureParts<'a>) -> A,
{
@ -221,7 +210,6 @@ impl<'a> FnLikeNode<'a> {
body: block,
vis: &i.vis,
span: i.span,
attrs: &i.attrs,
header: sig.header,
generics,
}),
@ -229,19 +217,19 @@ impl<'a> FnLikeNode<'a> {
},
Node::TraitItem(ti) => match ti.kind {
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
method(ti.hir_id(), ti.ident, sig, None, body, ti.span, &ti.attrs)
method(ti.hir_id(), ti.ident, sig, None, body, ti.span)
}
_ => bug!("trait method FnLikeNode that is not fn-like"),
},
Node::ImplItem(ii) => match ii.kind {
hir::ImplItemKind::Fn(ref sig, body) => {
method(ii.hir_id(), ii.ident, sig, Some(&ii.vis), body, ii.span, &ii.attrs)
method(ii.hir_id(), ii.ident, sig, Some(&ii.vis), body, ii.span)
}
_ => bug!("impl method FnLikeNode that is not fn-like"),
},
Node::Expr(e) => match e.kind {
hir::ExprKind::Closure(_, ref decl, block, _fn_decl_span, _gen) => {
closure(ClosureParts::new(&decl, block, e.hir_id, e.span, &e.attrs))
closure(ClosureParts::new(&decl, block, e.hir_id, e.span))
}
_ => bug!("expr FnLikeNode that is not fn-like"),
},

View File

@ -116,6 +116,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
modules: _,
proc_macros: _,
trait_map: _,
attrs: _,
} = *krate;
hash_body(&mut hcx, root_mod_def_path_hash, item, &mut hir_body_nodes)

View File

@ -457,10 +457,7 @@ impl<'hir> Map<'hir> {
/// invoking `krate.attrs` because it registers a tighter
/// dep-graph access.
pub fn krate_attrs(&self) -> &'hir [ast::Attribute] {
match self.get_entry(CRATE_HIR_ID).node {
Node::Crate(item) => item.attrs,
_ => bug!(),
}
self.attrs(CRATE_HIR_ID)
}
pub fn get_module(&self, module: LocalDefId) -> (&'hir Mod<'hir>, Span, HirId) {
@ -853,34 +850,7 @@ impl<'hir> Map<'hir> {
/// Given a node ID, gets a list of attributes associated with the AST
/// corresponding to the node-ID.
pub fn attrs(&self, id: HirId) -> &'hir [ast::Attribute] {
self.find_entry(id).map_or(&[], |entry| match entry.node {
Node::Param(a) => a.attrs,
Node::Local(l) => &l.attrs[..],
Node::Item(i) => i.attrs,
Node::ForeignItem(fi) => fi.attrs,
Node::TraitItem(ref ti) => ti.attrs,
Node::ImplItem(ref ii) => ii.attrs,
Node::Variant(ref v) => v.attrs,
Node::Field(ref f) => f.attrs,
Node::Expr(ref e) => &*e.attrs,
Node::Stmt(ref s) => s.kind.attrs(|id| self.item(id)),
Node::Arm(ref a) => &*a.attrs,
Node::GenericParam(param) => param.attrs,
// Unit/tuple structs/variants take the attributes straight from
// the struct/variant definition.
Node::Ctor(..) => self.attrs(self.get_parent_item(id)),
Node::Crate(item) => item.attrs,
Node::MacroDef(def) => def.attrs,
Node::AnonConst(..)
| Node::PathSegment(..)
| Node::Ty(..)
| Node::Pat(..)
| Node::Binding(..)
| Node::TraitRef(..)
| Node::Block(..)
| Node::Lifetime(..)
| Node::Visibility(..) => &[],
})
self.tcx.hir_attrs(id.owner).get(id.local_id)
}
/// Gets the span of the definition of the specified HIR node.

View File

@ -9,6 +9,7 @@ pub mod place;
use crate::ich::StableHashingContext;
use crate::ty::query::Providers;
use crate::ty::TyCtxt;
use rustc_ast::Attribute;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@ -16,6 +17,7 @@ use rustc_hir::def_id::{LocalDefId, LOCAL_CRATE};
use rustc_hir::*;
use rustc_index::vec::IndexVec;
use rustc_span::DUMMY_SP;
use std::collections::BTreeMap;
#[derive(Debug)]
pub struct Owner<'tcx> {
@ -55,6 +57,48 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for OwnerNodes<'tcx> {
}
}
#[derive(Copy, Clone)]
pub struct AttributeMap<'tcx> {
map: &'tcx BTreeMap<HirId, &'tcx [Attribute]>,
prefix: LocalDefId,
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for AttributeMap<'tcx> {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
let range = self.range();
range.clone().count().hash_stable(hcx, hasher);
for (key, value) in range {
key.hash_stable(hcx, hasher);
value.hash_stable(hcx, hasher);
}
}
}
impl<'tcx> std::fmt::Debug for AttributeMap<'tcx> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AttributeMap")
.field("prefix", &self.prefix)
.field("range", &&self.range().collect::<Vec<_>>()[..])
.finish()
}
}
impl<'tcx> AttributeMap<'tcx> {
fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] {
self.map.get(&HirId { owner: self.prefix, local_id: id }).copied().unwrap_or(&[])
}
fn range(&self) -> std::collections::btree_map::Range<'_, rustc_hir::HirId, &[Attribute]> {
let local_zero = ItemLocalId::from_u32(0);
let range = HirId { owner: self.prefix, local_id: local_zero }..HirId {
owner: LocalDefId { local_def_index: self.prefix.local_def_index + 1 },
local_id: local_zero,
};
self.map.range(range)
}
}
impl<'tcx> TyCtxt<'tcx> {
#[inline(always)]
pub fn hir(self) -> map::Map<'tcx> {
@ -76,6 +120,7 @@ pub fn provide(providers: &mut Providers) {
providers.hir_module_items = |tcx, id| &tcx.untracked_crate.modules[&id];
providers.hir_owner = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].signature;
providers.hir_owner_nodes = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].with_bodies.as_deref();
providers.hir_attrs = |tcx, id| AttributeMap { map: &tcx.untracked_crate.attrs, prefix: id };
providers.def_span = |tcx, def_id| tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP);
providers.fn_arg_names = |tcx, id| {
let hir = tcx.hir();

View File

@ -66,11 +66,10 @@ impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
fn hash_hir_expr(&mut self, expr: &hir::Expr<'_>, hasher: &mut StableHasher) {
self.while_hashing_hir_bodies(true, |hcx| {
let hir::Expr { hir_id: _, ref span, ref kind, ref attrs } = *expr;
let hir::Expr { hir_id: _, ref span, ref kind } = *expr;
span.hash_stable(hcx, hasher);
kind.hash_stable(hcx, hasher);
attrs.hash_stable(hcx, hasher);
})
}

View File

@ -61,6 +61,15 @@ rustc_queries! {
desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
}
/// Gives access to the HIR attributes inside the HIR owner `key`.
///
/// This can be conveniently accessed by methods on `tcx.hir()`.
/// Avoid calling this query directly.
query hir_attrs(key: LocalDefId) -> rustc_middle::hir::AttributeMap<'tcx> {
eval_always
desc { |tcx| "HIR owner attributes in `{}`", tcx.def_path_str(key.to_def_id()) }
}
/// Computes the `DefId` of the corresponding const parameter in case the `key` is a
/// const argument and returns `None` otherwise.
///

View File

@ -15,7 +15,7 @@ crate fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
if let Some(fn_like_node) = FnLikeNode::from_node(tcx.hir().get(hir_id)) {
if let FnKind::Closure(_) = fn_like_node.kind() {
if let FnKind::Closure = fn_like_node.kind() {
// closures can't recur, so they don't matter.
return;
}

View File

@ -62,12 +62,12 @@ impl CheckAttrVisitor<'tcx> {
fn check_attributes(
&self,
hir_id: HirId,
attrs: &'hir [Attribute],
span: &Span,
target: Target,
item: Option<ItemLike<'_>>,
) {
let mut is_valid = true;
let attrs = self.tcx.hir().attrs(hir_id);
for attr in attrs {
is_valid &= if self.tcx.sess.check_name(attr, sym::inline) {
self.check_inline(hir_id, attr, span, target)
@ -1213,53 +1213,29 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
fn visit_item(&mut self, item: &'tcx Item<'tcx>) {
let target = Target::from_item(item);
self.check_attributes(
item.hir_id(),
item.attrs,
&item.span,
target,
Some(ItemLike::Item(item)),
);
self.check_attributes(item.hir_id(), &item.span, target, Some(ItemLike::Item(item)));
intravisit::walk_item(self, item)
}
fn visit_generic_param(&mut self, generic_param: &'tcx hir::GenericParam<'tcx>) {
let target = Target::from_generic_param(generic_param);
self.check_attributes(
generic_param.hir_id,
generic_param.attrs,
&generic_param.span,
target,
None,
);
self.check_attributes(generic_param.hir_id, &generic_param.span, target, None);
intravisit::walk_generic_param(self, generic_param)
}
fn visit_trait_item(&mut self, trait_item: &'tcx TraitItem<'tcx>) {
let target = Target::from_trait_item(trait_item);
self.check_attributes(
trait_item.hir_id(),
&trait_item.attrs,
&trait_item.span,
target,
None,
);
self.check_attributes(trait_item.hir_id(), &trait_item.span, target, None);
intravisit::walk_trait_item(self, trait_item)
}
fn visit_struct_field(&mut self, struct_field: &'tcx hir::StructField<'tcx>) {
self.check_attributes(
struct_field.hir_id,
&struct_field.attrs,
&struct_field.span,
Target::Field,
None,
);
self.check_attributes(struct_field.hir_id, &struct_field.span, Target::Field, None);
intravisit::walk_struct_field(self, struct_field);
}
fn visit_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) {
self.check_attributes(arm.hir_id, &arm.attrs, &arm.span, Target::Arm, None);
self.check_attributes(arm.hir_id, &arm.span, Target::Arm, None);
intravisit::walk_arm(self, arm);
}
@ -1267,7 +1243,6 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
let target = Target::from_foreign_item(f_item);
self.check_attributes(
f_item.hir_id(),
&f_item.attrs,
&f_item.span,
target,
Some(ItemLike::ForeignItem(f_item)),
@ -1277,14 +1252,14 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
let target = target_from_impl_item(self.tcx, impl_item);
self.check_attributes(impl_item.hir_id(), &impl_item.attrs, &impl_item.span, target, None);
self.check_attributes(impl_item.hir_id(), &impl_item.span, target, None);
intravisit::walk_impl_item(self, impl_item)
}
fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) {
// When checking statements ignore expressions, they will be checked later.
if let hir::StmtKind::Local(ref l) = stmt.kind {
self.check_attributes(l.hir_id, &l.attrs, &stmt.span, Target::Statement, None);
self.check_attributes(l.hir_id, &stmt.span, Target::Statement, None);
}
intravisit::walk_stmt(self, stmt)
}
@ -1295,7 +1270,7 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
_ => Target::Expression,
};
self.check_attributes(expr.hir_id, &expr.attrs, &expr.span, target, None);
self.check_attributes(expr.hir_id, &expr.span, target, None);
intravisit::walk_expr(self, expr)
}
@ -1305,23 +1280,17 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
generics: &'tcx hir::Generics<'tcx>,
item_id: HirId,
) {
self.check_attributes(variant.id, variant.attrs, &variant.span, Target::Variant, None);
self.check_attributes(variant.id, &variant.span, Target::Variant, None);
intravisit::walk_variant(self, variant, generics, item_id)
}
fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef<'tcx>) {
self.check_attributes(
macro_def.hir_id(),
macro_def.attrs,
&macro_def.span,
Target::MacroDef,
None,
);
self.check_attributes(macro_def.hir_id(), &macro_def.span, Target::MacroDef, None);
intravisit::walk_macro_def(self, macro_def);
}
fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
self.check_attributes(param.hir_id, param.attrs, &param.span, Target::Param, None);
self.check_attributes(param.hir_id, &param.span, Target::Param, None);
intravisit::walk_param(self, param);
}
@ -1389,13 +1358,7 @@ fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
tcx.hir().visit_exported_macros_in_krate(check_attr_visitor);
check_invalid_macro_level_attr(tcx, tcx.hir().krate().non_exported_macro_attrs);
if module_def_id.is_top_level_module() {
check_attr_visitor.check_attributes(
CRATE_HIR_ID,
tcx.hir().krate_attrs(),
&DUMMY_SP,
Target::Mod,
None,
);
check_attr_visitor.check_attributes(CRATE_HIR_ID, &DUMMY_SP, Target::Mod, None);
check_invalid_crate_level_attr(tcx, tcx.hir().krate_attrs());
}
}

View File

@ -15,7 +15,6 @@ use rustc_middle::middle::privacy;
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
use rustc_session::lint;
use rustc_ast as ast;
use rustc_span::symbol::{sym, Symbol};
// Any local node that may call something in its body block should be
@ -346,11 +345,8 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
}
}
fn has_allow_dead_code_or_lang_attr(
tcx: TyCtxt<'_>,
id: hir::HirId,
attrs: &[ast::Attribute],
) -> bool {
fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
let attrs = tcx.hir().attrs(id);
if tcx.sess.contains_name(attrs, sym::lang) {
return true;
}
@ -400,8 +396,7 @@ struct LifeSeeder<'k, 'tcx> {
impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
let allow_dead_code =
has_allow_dead_code_or_lang_attr(self.tcx, item.hir_id(), &item.attrs);
let allow_dead_code = has_allow_dead_code_or_lang_attr(self.tcx, item.hir_id());
if allow_dead_code {
self.worklist.push(item.hir_id());
}
@ -424,11 +419,7 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
for impl_item_ref in items {
let impl_item = self.krate.impl_item(impl_item_ref.id);
if of_trait.is_some()
|| has_allow_dead_code_or_lang_attr(
self.tcx,
impl_item.hir_id(),
&impl_item.attrs,
)
|| has_allow_dead_code_or_lang_attr(self.tcx, impl_item.hir_id())
{
self.worklist.push(impl_item_ref.id.hir_id());
}
@ -446,7 +437,7 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
fn visit_trait_item(&mut self, trait_item: &hir::TraitItem<'_>) {
use hir::TraitItemKind::{Const, Fn};
if matches!(trait_item.kind, Const(_, Some(_)) | Fn(_, hir::TraitFn::Provided(_)))
&& has_allow_dead_code_or_lang_attr(self.tcx, trait_item.hir_id(), &trait_item.attrs)
&& has_allow_dead_code_or_lang_attr(self.tcx, trait_item.hir_id())
{
self.worklist.push(trait_item.hir_id());
}
@ -459,11 +450,7 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
fn visit_foreign_item(&mut self, foreign_item: &hir::ForeignItem<'_>) {
use hir::ForeignItemKind::{Fn, Static};
if matches!(foreign_item.kind, Static(..) | Fn(..))
&& has_allow_dead_code_or_lang_attr(
self.tcx,
foreign_item.hir_id(),
&foreign_item.attrs,
)
&& has_allow_dead_code_or_lang_attr(self.tcx, foreign_item.hir_id())
{
self.worklist.push(foreign_item.hir_id());
}
@ -543,17 +530,16 @@ impl DeadVisitor<'tcx> {
!field.is_positional()
&& !self.symbol_is_live(field.hir_id)
&& !field_type.is_phantom_data()
&& !has_allow_dead_code_or_lang_attr(self.tcx, field.hir_id, &field.attrs)
&& !has_allow_dead_code_or_lang_attr(self.tcx, field.hir_id)
}
fn should_warn_about_variant(&mut self, variant: &hir::Variant<'_>) -> bool {
!self.symbol_is_live(variant.id)
&& !has_allow_dead_code_or_lang_attr(self.tcx, variant.id, &variant.attrs)
!self.symbol_is_live(variant.id) && !has_allow_dead_code_or_lang_attr(self.tcx, variant.id)
}
fn should_warn_about_foreign_item(&mut self, fi: &hir::ForeignItem<'_>) -> bool {
!self.symbol_is_live(fi.hir_id())
&& !has_allow_dead_code_or_lang_attr(self.tcx, fi.hir_id(), &fi.attrs)
&& !has_allow_dead_code_or_lang_attr(self.tcx, fi.hir_id())
}
// id := HIR id of an item's definition.

View File

@ -27,19 +27,19 @@ struct DiagnosticItemCollector<'tcx> {
impl<'v, 'tcx> ItemLikeVisitor<'v> for DiagnosticItemCollector<'tcx> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
self.observe_item(&item.attrs, item.def_id);
self.observe_item(item.def_id);
}
fn visit_trait_item(&mut self, trait_item: &hir::TraitItem<'_>) {
self.observe_item(&trait_item.attrs, trait_item.def_id);
self.observe_item(trait_item.def_id);
}
fn visit_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) {
self.observe_item(&impl_item.attrs, impl_item.def_id);
self.observe_item(impl_item.def_id);
}
fn visit_foreign_item(&mut self, foreign_item: &hir::ForeignItem<'_>) {
self.observe_item(foreign_item.attrs, foreign_item.def_id);
self.observe_item(foreign_item.def_id);
}
}
@ -48,7 +48,9 @@ impl<'tcx> DiagnosticItemCollector<'tcx> {
DiagnosticItemCollector { tcx, items: Default::default() }
}
fn observe_item(&mut self, attrs: &[ast::Attribute], def_id: LocalDefId) {
fn observe_item(&mut self, def_id: LocalDefId) {
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
let attrs = self.tcx.hir().attrs(hir_id);
if let Some(name) = extract(&self.tcx.sess, attrs) {
// insert into our table
collect_item(self.tcx, &mut self.items, name, def_id.to_def_id());
@ -105,7 +107,7 @@ fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> FxHashMap<Symbol, DefId> {
tcx.hir().krate().visit_all_item_likes(&mut collector);
for m in tcx.hir().krate().exported_macros {
collector.observe_item(m.attrs, m.def_id);
collector.observe_item(m.def_id);
}
collector.items

View File

@ -2,7 +2,7 @@ use rustc_ast::entry::EntryPointType;
use rustc_errors::struct_span_err;
use rustc_hir::def_id::{CrateNum, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_hir::{ForeignItem, HirId, ImplItem, Item, ItemKind, TraitItem};
use rustc_hir::{ForeignItem, HirId, ImplItem, Item, ItemKind, TraitItem, CRATE_HIR_ID};
use rustc_middle::hir::map::Map;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
@ -60,7 +60,7 @@ fn entry_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<(LocalDefId, EntryFnType)
}
// If the user wants no main function at all, then stop here.
if tcx.sess.contains_name(&tcx.hir().krate().item.attrs, sym::no_main) {
if tcx.sess.contains_name(&tcx.hir().attrs(CRATE_HIR_ID), sym::no_main) {
return None;
}
@ -80,10 +80,11 @@ fn entry_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<(LocalDefId, EntryFnType)
// Beware, this is duplicated in `librustc_builtin_macros/test_harness.rs`
// (with `ast::Item`), so make sure to keep them in sync.
fn entry_point_type(sess: &Session, item: &Item<'_>, at_root: bool) -> EntryPointType {
if sess.contains_name(&item.attrs, sym::start) {
fn entry_point_type(ctxt: &EntryContext<'_, '_>, item: &Item<'_>, at_root: bool) -> EntryPointType {
let attrs = ctxt.map.attrs(item.hir_id());
if ctxt.session.contains_name(attrs, sym::start) {
EntryPointType::Start
} else if sess.contains_name(&item.attrs, sym::main) {
} else if ctxt.session.contains_name(attrs, sym::main) {
EntryPointType::MainAttr
} else if item.ident.name == sym::main {
if at_root {
@ -103,13 +104,14 @@ fn throw_attr_err(sess: &Session, span: Span, attr: &str) {
}
fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
match entry_point_type(&ctxt.session, item, at_root) {
match entry_point_type(ctxt, item, at_root) {
EntryPointType::None => (),
_ if !matches!(item.kind, ItemKind::Fn(..)) => {
if let Some(attr) = ctxt.session.find_by_name(item.attrs, sym::start) {
let attrs = ctxt.map.attrs(item.hir_id());
if let Some(attr) = ctxt.session.find_by_name(attrs, sym::start) {
throw_attr_err(&ctxt.session, attr.span, "start");
}
if let Some(attr) = ctxt.session.find_by_name(item.attrs, sym::main) {
if let Some(attr) = ctxt.session.find_by_name(attrs, sym::main) {
throw_attr_err(&ctxt.session, attr.span, "main");
}
}

View File

@ -241,7 +241,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
hir_visit::walk_assoc_type_binding(self, type_binding)
}
fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
fn visit_attribute(&mut self, _: hir::HirId, attr: &'v ast::Attribute) {
self.record("Attribute", Id::Attr(attr.id), attr);
}

View File

@ -13,7 +13,6 @@ use crate::weak_lang_items;
use rustc_middle::middle::cstore::ExternCrate;
use rustc_middle::ty::TyCtxt;
use rustc_ast::Attribute;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
@ -30,29 +29,21 @@ struct LanguageItemCollector<'tcx> {
impl ItemLikeVisitor<'v> for LanguageItemCollector<'tcx> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
self.check_for_lang(Target::from_item(item), item.hir_id(), item.attrs);
self.check_for_lang(Target::from_item(item), item.hir_id());
if let hir::ItemKind::Enum(def, ..) = &item.kind {
for variant in def.variants {
self.check_for_lang(Target::Variant, variant.id, variant.attrs);
self.check_for_lang(Target::Variant, variant.id);
}
}
}
fn visit_trait_item(&mut self, trait_item: &hir::TraitItem<'_>) {
self.check_for_lang(
Target::from_trait_item(trait_item),
trait_item.hir_id(),
trait_item.attrs,
)
self.check_for_lang(Target::from_trait_item(trait_item), trait_item.hir_id())
}
fn visit_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) {
self.check_for_lang(
target_from_impl_item(self.tcx, impl_item),
impl_item.hir_id(),
impl_item.attrs,
)
self.check_for_lang(target_from_impl_item(self.tcx, impl_item), impl_item.hir_id())
}
fn visit_foreign_item(&mut self, _: &hir::ForeignItem<'_>) {}
@ -63,7 +54,8 @@ impl LanguageItemCollector<'tcx> {
LanguageItemCollector { tcx, items: LanguageItems::new() }
}
fn check_for_lang(&mut self, actual_target: Target, hir_id: HirId, attrs: &[Attribute]) {
fn check_for_lang(&mut self, actual_target: Target, hir_id: HirId) {
let attrs = self.tcx.hir().attrs(hir_id);
let check_name = |attr, sym| self.tcx.sess.check_name(attr, sym);
if let Some((value, span)) = extract(check_name, &attrs) {
match ITEM_REFS.get(&value).cloned() {

View File

@ -120,7 +120,7 @@ impl Visitor<'tcx> for LibFeatureCollector<'tcx> {
NestedVisitorMap::All(self.tcx.hir())
}
fn visit_attribute(&mut self, attr: &'tcx Attribute) {
fn visit_attribute(&mut self, _: rustc_hir::HirId, attr: &'tcx Attribute) {
if let Some((feature, stable, span)) = self.extract(attr) {
self.collect_feature(feature, stable, span);
}
@ -131,7 +131,7 @@ fn collect(tcx: TyCtxt<'_>) -> LibFeatures {
let mut collector = LibFeatureCollector::new(tcx);
let krate = tcx.hir().krate();
for attr in krate.non_exported_macro_attrs {
collector.visit_attribute(attr);
collector.visit_attribute(rustc_hir::CRATE_HIR_ID, attr);
}
intravisit::walk_crate(&mut collector, krate);
collector.lib_features

View File

@ -46,7 +46,7 @@ impl<'tcx> Visitor<'tcx> for CheckNakedFunctions<'tcx> {
let fn_header;
match fk {
FnKind::Closure(..) => {
FnKind::Closure => {
// Closures with a naked attribute are rejected during attribute
// check. Don't validate them any further.
return;
@ -62,7 +62,8 @@ impl<'tcx> Visitor<'tcx> for CheckNakedFunctions<'tcx> {
}
}
let naked = fk.attrs().iter().any(|attr| attr.has_name(sym::naked));
let attrs = self.tcx.hir().attrs(hir_id);
let naked = attrs.iter().any(|attr| attr.has_name(sym::naked));
if naked {
let body = self.tcx.hir().body(body_id);
check_abi(self.tcx, hir_id, fn_header.abi, ident_span);

View File

@ -97,7 +97,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
fn annotate<F>(
&mut self,
hir_id: HirId,
attrs: &[Attribute],
item_sp: Span,
kind: AnnotationKind,
inherit_deprecation: InheritDeprecation,
@ -107,6 +106,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
) where
F: FnOnce(&mut Self),
{
let attrs = self.tcx.hir().attrs(hir_id);
debug!("annotate(id = {:?}, attrs = {:?})", hir_id, attrs);
let mut did_error = false;
if !self.tcx.features().staged_api {
@ -385,7 +385,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
if let Some(ctor_hir_id) = sd.ctor_hir_id() {
self.annotate(
ctor_hir_id,
&i.attrs,
i.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
@ -400,7 +399,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
self.annotate(
i.hir_id(),
&i.attrs,
i.span,
kind,
InheritDeprecation::Yes,
@ -414,7 +412,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem<'tcx>) {
self.annotate(
ti.hir_id(),
&ti.attrs,
ti.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
@ -431,7 +428,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
if self.in_trait_impl { AnnotationKind::Prohibited } else { AnnotationKind::Required };
self.annotate(
ii.hir_id(),
&ii.attrs,
ii.span,
kind,
InheritDeprecation::Yes,
@ -446,7 +442,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
fn visit_variant(&mut self, var: &'tcx Variant<'tcx>, g: &'tcx Generics<'tcx>, item_id: HirId) {
self.annotate(
var.id,
&var.attrs,
var.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
@ -456,7 +451,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
if let Some(ctor_hir_id) = var.data.ctor_hir_id() {
v.annotate(
ctor_hir_id,
&var.attrs,
var.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
@ -474,7 +468,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
fn visit_struct_field(&mut self, s: &'tcx StructField<'tcx>) {
self.annotate(
s.hir_id,
&s.attrs,
s.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
@ -489,7 +482,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem<'tcx>) {
self.annotate(
i.hir_id(),
&i.attrs,
i.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
@ -504,7 +496,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) {
self.annotate(
md.hir_id(),
&md.attrs,
md.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
@ -525,7 +516,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
self.annotate(
p.hir_id,
&p.attrs,
p.span,
kind,
InheritDeprecation::No,
@ -696,7 +686,6 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
annotator.annotate(
hir::CRATE_HIR_ID,
&krate.item.attrs,
krate.item.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
@ -762,8 +751,9 @@ impl Visitor<'tcx> for Checker<'tcx> {
// error if all involved types and traits are stable, because
// it will have no effect.
// See: https://github.com/rust-lang/rust/issues/55436
let attrs = self.tcx.hir().attrs(item.hir_id());
if let (Some((Stability { level: attr::Unstable { .. }, .. }, span)), _) =
attr::find_stability(&self.tcx.sess, &item.attrs, item.span)
attr::find_stability(&self.tcx.sess, attrs, item.span)
{
let mut c = CheckTraitImplStable { tcx: self.tcx, fully_stable: true };
c.visit_ty(self_ty);

View File

@ -97,7 +97,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
fn visit_foreign_item(&mut self, i: &hir::ForeignItem<'_>) {
let check_name = |attr, sym| self.tcx.sess.check_name(attr, sym);
if let Some((lang_item, _)) = lang_items::extract(check_name, &i.attrs) {
let attrs = self.tcx.hir().attrs(i.hir_id());
if let Some((lang_item, _)) = lang_items::extract(check_name, attrs) {
self.register(lang_item, i.span);
}
intravisit::walk_foreign_item(self, i)

View File

@ -16,7 +16,8 @@ struct RegistrarFinder<'tcx> {
impl<'v, 'tcx> ItemLikeVisitor<'v> for RegistrarFinder<'tcx> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
if let hir::ItemKind::Fn(..) = item.kind {
if self.tcx.sess.contains_name(&item.attrs, sym::plugin_registrar) {
let attrs = self.tcx.hir().attrs(item.hir_id());
if self.tcx.sess.contains_name(attrs, sym::plugin_registrar) {
self.registrars.push((item.def_id, item.span));
}
}

View File

@ -881,7 +881,8 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) {
// Non-opaque macros cannot make other items more accessible than they already are.
if attr::find_transparency(&self.tcx.sess, &md.attrs, md.ast.macro_rules).0
let attrs = self.tcx.hir().attrs(md.hir_id());
if attr::find_transparency(&self.tcx.sess, &attrs, md.ast.macro_rules).0
!= Transparency::Opaque
{
// `#[macro_export]`-ed `macro_rules!` are `Public` since they

View File

@ -1239,7 +1239,8 @@ fn compute_object_lifetime_defaults(tcx: TyCtxt<'_>) -> HirIdMap<Vec<ObjectLifet
let result = object_lifetime_defaults_for_item(tcx, generics);
// Debugging aid.
if tcx.sess.contains_name(&item.attrs, sym::rustc_object_lifetime_default) {
let attrs = tcx.hir().attrs(item.hir_id());
if tcx.sess.contains_name(attrs, sym::rustc_object_lifetime_default) {
let object_lifetime_default_reprs: String = result
.iter()
.map(|set| match *set {

View File

@ -496,6 +496,7 @@ impl<'tcx> DumpVisitor<'tcx> {
if !self.span.filter_generated(item.ident.span) {
let span = self.span_from_span(item.ident.span);
let attrs = self.tcx.hir().attrs(item.hir_id());
self.dumper.dump_def(
&access_from!(self.save_ctxt, item, item.hir_id()),
Def {
@ -508,9 +509,9 @@ impl<'tcx> DumpVisitor<'tcx> {
parent: None,
children: fields,
decl_id: None,
docs: self.save_ctxt.docs_for_attrs(&item.attrs),
docs: self.save_ctxt.docs_for_attrs(attrs),
sig: sig::item_signature(item, &self.save_ctxt),
attributes: lower_attributes(item.attrs.to_vec(), &self.save_ctxt),
attributes: lower_attributes(attrs.to_vec(), &self.save_ctxt),
},
);
}
@ -554,6 +555,7 @@ impl<'tcx> DumpVisitor<'tcx> {
let span = self.span_from_span(name_span);
let id = id_from_hir_id(variant.id, &self.save_ctxt);
let parent = Some(id_from_def_id(item.def_id.to_def_id()));
let attrs = self.tcx.hir().attrs(variant.id);
self.dumper.dump_def(
&access,
@ -567,12 +569,9 @@ impl<'tcx> DumpVisitor<'tcx> {
parent,
children: vec![],
decl_id: None,
docs: self.save_ctxt.docs_for_attrs(&variant.attrs),
docs: self.save_ctxt.docs_for_attrs(attrs),
sig: sig::variant_signature(variant, &self.save_ctxt),
attributes: lower_attributes(
variant.attrs.to_vec(),
&self.save_ctxt,
),
attributes: lower_attributes(attrs.to_vec(), &self.save_ctxt),
},
);
}
@ -594,6 +593,7 @@ impl<'tcx> DumpVisitor<'tcx> {
let span = self.span_from_span(name_span);
let id = id_from_hir_id(variant.id, &self.save_ctxt);
let parent = Some(id_from_def_id(item.def_id.to_def_id()));
let attrs = self.tcx.hir().attrs(variant.id);
self.dumper.dump_def(
&access,
@ -607,12 +607,9 @@ impl<'tcx> DumpVisitor<'tcx> {
parent,
children: vec![],
decl_id: None,
docs: self.save_ctxt.docs_for_attrs(&variant.attrs),
docs: self.save_ctxt.docs_for_attrs(attrs),
sig: sig::variant_signature(variant, &self.save_ctxt),
attributes: lower_attributes(
variant.attrs.to_vec(),
&self.save_ctxt,
),
attributes: lower_attributes(attrs.to_vec(), &self.save_ctxt),
},
);
}
@ -675,6 +672,7 @@ impl<'tcx> DumpVisitor<'tcx> {
let span = self.span_from_span(item.ident.span);
let children =
methods.iter().map(|i| id_from_def_id(i.id.def_id.to_def_id())).collect();
let attrs = self.tcx.hir().attrs(item.hir_id());
self.dumper.dump_def(
&access_from!(self.save_ctxt, item, item.hir_id()),
Def {
@ -687,9 +685,9 @@ impl<'tcx> DumpVisitor<'tcx> {
parent: None,
children,
decl_id: None,
docs: self.save_ctxt.docs_for_attrs(&item.attrs),
docs: self.save_ctxt.docs_for_attrs(attrs),
sig: sig::item_signature(item, &self.save_ctxt),
attributes: lower_attributes(item.attrs.to_vec(), &self.save_ctxt),
attributes: lower_attributes(attrs.to_vec(), &self.save_ctxt),
},
);
}
@ -998,6 +996,7 @@ impl<'tcx> DumpVisitor<'tcx> {
hir::TraitItemKind::Const(ref ty, body) => {
let body = body.map(|b| &self.tcx.hir().body(b).value);
let respan = respan(vis_span, hir::VisibilityKind::Public);
let attrs = self.tcx.hir().attrs(trait_item.hir_id());
self.process_assoc_const(
trait_item.hir_id(),
trait_item.ident,
@ -1005,7 +1004,7 @@ impl<'tcx> DumpVisitor<'tcx> {
body,
trait_id,
&respan,
&trait_item.attrs,
attrs,
);
}
hir::TraitItemKind::Fn(ref sig, ref trait_fn) => {
@ -1031,6 +1030,7 @@ impl<'tcx> DumpVisitor<'tcx> {
if !self.span.filter_generated(trait_item.ident.span) {
let span = self.span_from_span(trait_item.ident.span);
let id = id_from_def_id(trait_item.def_id.to_def_id());
let attrs = self.tcx.hir().attrs(trait_item.hir_id());
self.dumper.dump_def(
&Access { public: true, reachable: true },
@ -1044,7 +1044,7 @@ impl<'tcx> DumpVisitor<'tcx> {
parent: Some(id_from_def_id(trait_id)),
children: vec![],
decl_id: None,
docs: self.save_ctxt.docs_for_attrs(&trait_item.attrs),
docs: self.save_ctxt.docs_for_attrs(attrs),
sig: sig::assoc_type_signature(
trait_item.hir_id(),
trait_item.ident,
@ -1052,10 +1052,7 @@ impl<'tcx> DumpVisitor<'tcx> {
default_ty.as_ref().map(|ty| &**ty),
&self.save_ctxt,
),
attributes: lower_attributes(
trait_item.attrs.to_vec(),
&self.save_ctxt,
),
attributes: lower_attributes(attrs.to_vec(), &self.save_ctxt),
},
);
}
@ -1072,6 +1069,7 @@ impl<'tcx> DumpVisitor<'tcx> {
match impl_item.kind {
hir::ImplItemKind::Const(ref ty, body) => {
let body = self.tcx.hir().body(body);
let attrs = self.tcx.hir().attrs(impl_item.hir_id());
self.process_assoc_const(
impl_item.hir_id(),
impl_item.ident,
@ -1079,7 +1077,7 @@ impl<'tcx> DumpVisitor<'tcx> {
Some(&body.value),
impl_id,
&impl_item.vis,
&impl_item.attrs,
attrs,
);
}
hir::ImplItemKind::Fn(ref sig, body) => {
@ -1118,6 +1116,7 @@ impl<'tcx> DumpVisitor<'tcx> {
.map(|i| id_from_def_id(i.def_id.to_def_id()))
.collect();
let span = self.span_from_span(krate.item.span);
let attrs = self.tcx.hir().attrs(id);
self.dumper.dump_def(
&Access { public: true, reachable: true },
@ -1131,9 +1130,9 @@ impl<'tcx> DumpVisitor<'tcx> {
children,
parent: None,
decl_id: None,
docs: self.save_ctxt.docs_for_attrs(krate.item.attrs),
docs: self.save_ctxt.docs_for_attrs(attrs),
sig: None,
attributes: lower_attributes(krate.item.attrs.to_owned(), &self.save_ctxt),
attributes: lower_attributes(attrs.to_owned(), &self.save_ctxt),
},
);
intravisit::walk_crate(self, krate);
@ -1263,6 +1262,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
if !self.span.filter_generated(item.ident.span) {
let span = self.span_from_span(item.ident.span);
let id = id_from_def_id(item.def_id.to_def_id());
let attrs = self.tcx.hir().attrs(item.hir_id());
self.dumper.dump_def(
&access_from!(self.save_ctxt, item, item.hir_id()),
@ -1276,9 +1276,9 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
parent: None,
children: vec![],
decl_id: None,
docs: self.save_ctxt.docs_for_attrs(&item.attrs),
docs: self.save_ctxt.docs_for_attrs(attrs),
sig: sig::item_signature(item, &self.save_ctxt),
attributes: lower_attributes(item.attrs.to_vec(), &self.save_ctxt),
attributes: lower_attributes(attrs.to_vec(), &self.save_ctxt),
},
);
}

View File

@ -139,6 +139,7 @@ impl<'tcx> SaveContext<'tcx> {
pub fn get_extern_item_data(&self, item: &hir::ForeignItem<'_>) -> Option<Data> {
let def_id = item.def_id.to_def_id();
let qualname = format!("::{}", self.tcx.def_path_str(def_id));
let attrs = self.tcx.hir().attrs(item.hir_id());
match item.kind {
hir::ForeignItemKind::Fn(ref decl, arg_names, ref generics) => {
filter!(self.span_utils, item.ident.span);
@ -169,9 +170,9 @@ impl<'tcx> SaveContext<'tcx> {
parent: None,
children: vec![],
decl_id: None,
docs: self.docs_for_attrs(&item.attrs),
docs: self.docs_for_attrs(attrs),
sig: sig::foreign_item_signature(item, self),
attributes: lower_attributes(item.attrs.to_vec(), self),
attributes: lower_attributes(attrs.to_vec(), self),
}))
}
hir::ForeignItemKind::Static(ref ty, _) => {
@ -190,9 +191,9 @@ impl<'tcx> SaveContext<'tcx> {
parent: None,
children: vec![],
decl_id: None,
docs: self.docs_for_attrs(&item.attrs),
docs: self.docs_for_attrs(attrs),
sig: sig::foreign_item_signature(item, self),
attributes: lower_attributes(item.attrs.to_vec(), self),
attributes: lower_attributes(attrs.to_vec(), self),
}))
}
// FIXME(plietar): needs a new DefKind in rls-data
@ -202,6 +203,7 @@ impl<'tcx> SaveContext<'tcx> {
pub fn get_item_data(&self, item: &hir::Item<'_>) -> Option<Data> {
let def_id = item.def_id.to_def_id();
let attrs = self.tcx.hir().attrs(item.hir_id());
match item.kind {
hir::ItemKind::Fn(ref sig, ref generics, _) => {
let qualname = format!("::{}", self.tcx.def_path_str(def_id));
@ -224,9 +226,9 @@ impl<'tcx> SaveContext<'tcx> {
parent: None,
children: vec![],
decl_id: None,
docs: self.docs_for_attrs(&item.attrs),
docs: self.docs_for_attrs(attrs),
sig: sig::item_signature(item, self),
attributes: lower_attributes(item.attrs.to_vec(), self),
attributes: lower_attributes(attrs.to_vec(), self),
}))
}
hir::ItemKind::Static(ref typ, ..) => {
@ -247,9 +249,9 @@ impl<'tcx> SaveContext<'tcx> {
parent: None,
children: vec![],
decl_id: None,
docs: self.docs_for_attrs(&item.attrs),
docs: self.docs_for_attrs(attrs),
sig: sig::item_signature(item, self),
attributes: lower_attributes(item.attrs.to_vec(), self),
attributes: lower_attributes(attrs.to_vec(), self),
}))
}
hir::ItemKind::Const(ref typ, _) => {
@ -269,9 +271,9 @@ impl<'tcx> SaveContext<'tcx> {
parent: None,
children: vec![],
decl_id: None,
docs: self.docs_for_attrs(&item.attrs),
docs: self.docs_for_attrs(attrs),
sig: sig::item_signature(item, self),
attributes: lower_attributes(item.attrs.to_vec(), self),
attributes: lower_attributes(attrs.to_vec(), self),
}))
}
hir::ItemKind::Mod(ref m) => {
@ -296,9 +298,9 @@ impl<'tcx> SaveContext<'tcx> {
.map(|i| id_from_def_id(i.def_id.to_def_id()))
.collect(),
decl_id: None,
docs: self.docs_for_attrs(&item.attrs),
docs: self.docs_for_attrs(attrs),
sig: sig::item_signature(item, self),
attributes: lower_attributes(item.attrs.to_vec(), self),
attributes: lower_attributes(attrs.to_vec(), self),
}))
}
hir::ItemKind::Enum(ref def, ref generics) => {
@ -317,9 +319,9 @@ impl<'tcx> SaveContext<'tcx> {
parent: None,
children: def.variants.iter().map(|v| id_from_hir_id(v.id, self)).collect(),
decl_id: None,
docs: self.docs_for_attrs(&item.attrs),
docs: self.docs_for_attrs(attrs),
sig: sig::item_signature(item, self),
attributes: lower_attributes(item.attrs.to_vec(), self),
attributes: lower_attributes(attrs.to_vec(), self),
}))
}
hir::ItemKind::Impl(hir::Impl { ref of_trait, ref self_ty, ref items, .. }) => {
@ -387,6 +389,7 @@ impl<'tcx> SaveContext<'tcx> {
let id = id_from_def_id(field_def_id);
let span = self.span_from_span(field.ident.span);
let attrs = self.tcx.hir().attrs(field.hir_id);
Some(Def {
kind: DefKind::Field,
@ -398,9 +401,9 @@ impl<'tcx> SaveContext<'tcx> {
parent: Some(id_from_def_id(scope_def_id)),
children: vec![],
decl_id: None,
docs: self.docs_for_attrs(&field.attrs),
docs: self.docs_for_attrs(attrs),
sig: sig::field_signature(field, self),
attributes: lower_attributes(field.attrs.to_vec(), self),
attributes: lower_attributes(attrs.to_vec(), self),
})
}
@ -424,9 +427,9 @@ impl<'tcx> SaveContext<'tcx> {
let trait_id = self.tcx.trait_id_of_impl(impl_id);
let mut docs = String::new();
let mut attrs = vec![];
if let Some(Node::ImplItem(item)) = hir.find(hir_id) {
docs = self.docs_for_attrs(&item.attrs);
attrs = item.attrs.to_vec();
if let Some(Node::ImplItem(_)) = hir.find(hir_id) {
attrs = self.tcx.hir().attrs(hir_id).to_vec();
docs = self.docs_for_attrs(&attrs);
}
let mut decl_id = None;
@ -470,9 +473,9 @@ impl<'tcx> SaveContext<'tcx> {
let mut docs = String::new();
let mut attrs = vec![];
if let Some(Node::TraitItem(item)) = self.tcx.hir().find(hir_id) {
docs = self.docs_for_attrs(&item.attrs);
attrs = item.attrs.to_vec();
if let Some(Node::TraitItem(_)) = self.tcx.hir().find(hir_id) {
attrs = self.tcx.hir().attrs(hir_id).to_vec();
docs = self.docs_for_attrs(&attrs);
}
(

View File

@ -1466,11 +1466,12 @@ impl intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
if self.span.map_or(true, |span| item.span < span) {
if !item.span.from_expansion() {
// Don't insert between attributes and an item.
if item.attrs.is_empty() {
let attrs = self.tcx.hir().attrs(item.hir_id());
if attrs.is_empty() {
self.span = Some(item.span.shrink_to_lo());
} else {
// Find the first attribute on the item.
for attr in item.attrs {
for attr in attrs {
if self.span.map_or(true, |span| attr.span < span) {
self.span = Some(attr.span.shrink_to_lo());
}

View File

@ -354,7 +354,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
hir_id: hir::HirId,
) {
assert!(
matches!(fk, intravisit::FnKind::Closure(..)),
matches!(fk, intravisit::FnKind::Closure),
"visit_fn invoked for something other than a closure"
);

View File

@ -201,7 +201,8 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: LocalDefId) {
error = true;
}
for attr in it.attrs {
let attrs = tcx.hir().attrs(main_id);
for attr in attrs {
if tcx.sess.check_name(attr, sym::track_caller) {
tcx.sess
.struct_span_err(
@ -300,7 +301,8 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: LocalDefId) {
error = true;
}
for attr in it.attrs {
let attrs = tcx.hir().attrs(start_id);
for attr in attrs {
if tcx.sess.check_name(attr, sym::track_caller) {
tcx.sess
.struct_span_err(

View File

@ -863,7 +863,8 @@ fn clean_fn_or_proc_macro(
name: &mut Symbol,
cx: &mut DocContext<'_>,
) -> ItemKind {
let macro_kind = item.attrs.iter().find_map(|a| {
let attrs = cx.tcx.hir().attrs(item.hir_id());
let macro_kind = attrs.iter().find_map(|a| {
if a.has_name(sym::proc_macro) {
Some(MacroKind::Bang)
} else if a.has_name(sym::proc_macro_derive) {
@ -877,8 +878,7 @@ fn clean_fn_or_proc_macro(
match macro_kind {
Some(kind) => {
if kind == MacroKind::Derive {
*name = item
.attrs
*name = attrs
.lists(sym::proc_macro_derive)
.find_map(|mi| mi.ident())
.expect("proc-macro derives require a name")
@ -886,7 +886,7 @@ fn clean_fn_or_proc_macro(
}
let mut helpers = Vec::new();
for mi in item.attrs.lists(sym::proc_macro_derive) {
for mi in attrs.lists(sym::proc_macro_derive) {
if !mi.has_name(sym::attributes) {
continue;
}
@ -2102,8 +2102,9 @@ fn clean_extern_crate(
let cnum = cx.tcx.extern_mod_stmt_cnum(krate.def_id).unwrap_or(LOCAL_CRATE);
// this is the ID of the crate itself
let crate_def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
let attrs = cx.tcx.hir().attrs(krate.hir_id());
let please_inline = krate.vis.node.is_pub()
&& krate.attrs.iter().any(|a| {
&& attrs.iter().any(|a| {
a.has_name(sym::doc)
&& match a.meta_item_list() {
Some(l) => attr::list_contains_name(&l, sym::inline),
@ -2121,7 +2122,7 @@ fn clean_extern_crate(
cx.tcx.parent_module(krate.hir_id()).to_def_id(),
res,
name,
Some(krate.attrs),
Some(attrs),
&mut visited,
) {
return items;
@ -2130,7 +2131,7 @@ fn clean_extern_crate(
// FIXME: using `from_def_id_and_kind` breaks `rustdoc/masked` for some reason
vec![Item {
name: Some(name),
attrs: box krate.attrs.clean(cx),
attrs: box attrs.clean(cx),
source: krate.span.clean(cx),
def_id: crate_def_id,
visibility: krate.vis.clean(cx),
@ -2152,7 +2153,8 @@ fn clean_use_statement(
return Vec::new();
}
let inline_attr = import.attrs.lists(sym::doc).get_word_attr(sym::inline);
let attrs = cx.tcx.hir().attrs(import.hir_id());
let inline_attr = attrs.lists(sym::doc).get_word_attr(sym::inline);
let pub_underscore = import.vis.node.is_pub() && name == kw::Underscore;
if pub_underscore {
@ -2174,7 +2176,7 @@ fn clean_use_statement(
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
let mut denied = !import.vis.node.is_pub()
|| pub_underscore
|| import.attrs.iter().any(|a| {
|| attrs.iter().any(|a| {
a.has_name(sym::doc)
&& match a.meta_item_list() {
Some(l) => {
@ -2214,7 +2216,7 @@ fn clean_use_statement(
cx.tcx.parent_module(import.hir_id()).to_def_id(),
path.res,
name,
Some(import.attrs),
Some(attrs),
&mut visited,
) {
items.push(Item::from_def_id_and_parts(

View File

@ -106,25 +106,27 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
let tests = interface::run_compiler(config, |compiler| {
compiler.enter(|queries| {
let lower_to_hir = queries.lower_to_hir()?;
let mut opts = scrape_test_config(lower_to_hir.peek().0);
opts.display_warnings |= options.display_warnings;
let enable_per_target_ignores = options.enable_per_target_ignores;
let mut collector = Collector::new(
queries.crate_name()?.peek().to_string(),
options,
false,
opts,
Some(compiler.session().parse_sess.clone_source_map()),
None,
enable_per_target_ignores,
);
let _lower_to_hir = queries.lower_to_hir()?;
let crate_name = queries.crate_name()?.peek().to_string();
let mut global_ctxt = queries.global_ctxt()?.take();
global_ctxt.enter(|tcx| {
let collector = global_ctxt.enter(|tcx| {
let krate = tcx.hir().krate();
let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID);
let mut opts = scrape_test_config(crate_attrs);
opts.display_warnings |= options.display_warnings;
let enable_per_target_ignores = options.enable_per_target_ignores;
let mut collector = Collector::new(
crate_name,
options,
false,
opts,
Some(compiler.session().parse_sess.clone_source_map()),
None,
enable_per_target_ignores,
);
let mut hir_collector = HirCollector {
sess: compiler.session(),
@ -137,13 +139,14 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
};
hir_collector.visit_testable(
"".to_string(),
&krate.item.attrs,
CRATE_HIR_ID,
krate.item.span,
|this| {
intravisit::walk_crate(this, krate);
},
);
collector
});
compiler.session().abort_if_errors();
@ -168,15 +171,13 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
}
// Look for `#![doc(test(no_crate_inject))]`, used by crates in the std facade.
fn scrape_test_config(krate: &::rustc_hir::Crate<'_>) -> TestOptions {
fn scrape_test_config(attrs: &[ast::Attribute]) -> TestOptions {
use rustc_ast_pretty::pprust;
let mut opts =
TestOptions { no_crate_inject: false, display_warnings: false, attrs: Vec::new() };
let test_attrs: Vec<_> = krate
.item
.attrs
let test_attrs: Vec<_> = attrs
.iter()
.filter(|a| a.has_name(sym::doc))
.flat_map(|a| a.meta_item_list().unwrap_or_else(Vec::new))
@ -991,11 +992,11 @@ impl<'a, 'hir, 'tcx> HirCollector<'a, 'hir, 'tcx> {
fn visit_testable<F: FnOnce(&mut Self)>(
&mut self,
name: String,
attrs: &[ast::Attribute],
hir_id: HirId,
sp: Span,
nested: F,
) {
let attrs = self.tcx.hir().attrs(hir_id);
let mut attrs = Attributes::from_ast(self.sess.diagnostic(), attrs, None);
if let Some(ref cfg) = attrs.cfg {
if !cfg.matches(&self.sess.parse_sess, Some(&self.sess.features_untracked())) {
@ -1053,45 +1054,27 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
item.ident.to_string()
};
self.visit_testable(name, &item.attrs, item.hir_id(), item.span, |this| {
self.visit_testable(name, item.hir_id(), item.span, |this| {
intravisit::walk_item(this, item);
});
}
fn visit_trait_item(&mut self, item: &'hir hir::TraitItem<'_>) {
self.visit_testable(
item.ident.to_string(),
&item.attrs,
item.hir_id(),
item.span,
|this| {
intravisit::walk_trait_item(this, item);
},
);
self.visit_testable(item.ident.to_string(), item.hir_id(), item.span, |this| {
intravisit::walk_trait_item(this, item);
});
}
fn visit_impl_item(&mut self, item: &'hir hir::ImplItem<'_>) {
self.visit_testable(
item.ident.to_string(),
&item.attrs,
item.hir_id(),
item.span,
|this| {
intravisit::walk_impl_item(this, item);
},
);
self.visit_testable(item.ident.to_string(), item.hir_id(), item.span, |this| {
intravisit::walk_impl_item(this, item);
});
}
fn visit_foreign_item(&mut self, item: &'hir hir::ForeignItem<'_>) {
self.visit_testable(
item.ident.to_string(),
&item.attrs,
item.hir_id(),
item.span,
|this| {
intravisit::walk_foreign_item(this, item);
},
);
self.visit_testable(item.ident.to_string(), item.hir_id(), item.span, |this| {
intravisit::walk_foreign_item(this, item);
});
}
fn visit_variant(
@ -1100,13 +1083,13 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
g: &'hir hir::Generics<'_>,
item_id: hir::HirId,
) {
self.visit_testable(v.ident.to_string(), &v.attrs, v.id, v.span, |this| {
self.visit_testable(v.ident.to_string(), v.id, v.span, |this| {
intravisit::walk_variant(this, v, g, item_id);
});
}
fn visit_struct_field(&mut self, f: &'hir hir::StructField<'_>) {
self.visit_testable(f.ident.to_string(), &f.attrs, f.hir_id, f.span, |this| {
self.visit_testable(f.ident.to_string(), f.hir_id, f.span, |this| {
intravisit::walk_struct_field(this, f);
});
}
@ -1114,7 +1097,6 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
fn visit_macro_def(&mut self, macro_def: &'hir hir::MacroDef<'_>) {
self.visit_testable(
macro_def.ident.to_string(),
&macro_def.attrs,
macro_def.hir_id(),
macro_def.span,
|_| (),

View File

@ -285,10 +285,12 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
return;
}
let attrs = self.cx.tcx.hir().attrs(item.hir_id());
// If there was a private module in the current path then don't bother inlining
// anything as it will probably be stripped anyway.
if item.vis.node.is_pub() && self.inside_public_path {
let please_inline = item.attrs.iter().any(|item| match item.meta_item_list() {
let please_inline = attrs.iter().any(|item| match item.meta_item_list() {
Some(ref list) if item.has_name(sym::doc) => {
list.iter().any(|i| i.has_name(sym::inline))
}

View File

@ -335,7 +335,7 @@ enum EnumAddMustUse {
}
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
#[must_use]
enum EnumAddMustUse {
@ -353,7 +353,7 @@ enum EnumAddReprC {
}
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
#[rustc_clean(cfg="cfail2", except="type_of")]
#[rustc_clean(cfg="cfail3")]
#[repr(C)]
enum EnumAddReprC {

View File

@ -154,7 +154,7 @@ extern "C" {
}
#[cfg(not(cfail1))]
#[rustc_dirty(cfg = "cfail2", except = "hir_owner_nodes")]
#[rustc_dirty(cfg = "cfail2", except = "hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
#[link_args = "-foo -bar -baz"]
extern "C" {
@ -169,7 +169,7 @@ extern "C" {
}
#[cfg(not(cfail1))]
#[rustc_dirty(cfg = "cfail2", except = "hir_owner_nodes")]
#[rustc_dirty(cfg = "cfail2", except = "hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
#[link(name = "bar")]
extern "C" {

View File

@ -194,7 +194,7 @@ pub fn second_lifetime_bound<'a, 'b, T: 'a + 'b>() {}
pub fn inline() {}
#[cfg(not(cfail1))]
#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes")]
#[rustc_clean(cfg = "cfail2")]
#[rustc_clean(cfg = "cfail3")]
#[inline]
pub fn inline() {}
@ -206,7 +206,7 @@ pub fn inline() {}
pub fn inline_never() {}
#[cfg(not(cfail1))]
#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes")]
#[rustc_clean(cfg = "cfail2")]
#[rustc_clean(cfg = "cfail3")]
#[inline(never)]
pub fn inline_never() {}
@ -217,7 +217,7 @@ pub fn inline_never() {}
pub fn no_mangle() {}
#[cfg(not(cfail1))]
#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes")]
#[rustc_clean(cfg = "cfail2")]
#[rustc_clean(cfg = "cfail3")]
#[no_mangle]
pub fn no_mangle() {}
@ -228,7 +228,7 @@ pub fn no_mangle() {}
pub fn linkage() {}
#[cfg(not(cfail1))]
#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes")]
#[rustc_clean(cfg = "cfail2")]
#[rustc_clean(cfg = "cfail3")]
#[linkage = "weak_odr"]
pub fn linkage() {}

View File

@ -214,7 +214,7 @@ impl Foo {
#[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
impl Foo {
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
#[inline]
pub fn make_method_inline(&self) -> u8 { 0 }
@ -431,7 +431,7 @@ impl Foo {
#[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
impl Foo {
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
#[no_mangle]
pub fn add_no_mangle_to_method(&self) { }

View File

@ -41,7 +41,7 @@ static mut STATIC_MUTABILITY: u8 = 0;
static STATIC_LINKAGE: u8 = 0;
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
#[linkage="weak_odr"]
static STATIC_LINKAGE: u8 = 0;
@ -52,7 +52,7 @@ static STATIC_LINKAGE: u8 = 0;
static STATIC_NO_MANGLE: u8 = 0;
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
#[no_mangle]
static STATIC_NO_MANGLE: u8 = 0;
@ -63,7 +63,7 @@ static STATIC_NO_MANGLE: u8 = 0;
static STATIC_THREAD_LOCAL: u8 = 0;
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
#[thread_local]
static STATIC_THREAD_LOCAL: u8 = 0;

View File

@ -24,8 +24,8 @@
pub struct LayoutPacked;
#[cfg(not(cfail1))]
#[rustc_dirty(label="hir_owner", cfg="cfail2")]
#[rustc_dirty(label="hir_owner_nodes", cfg="cfail2")]
#[rustc_clean(label="hir_owner", cfg="cfail2")]
#[rustc_clean(label="hir_owner_nodes", cfg="cfail2")]
#[rustc_dirty(label="type_of", cfg="cfail2")]
#[rustc_clean(label="generics_of", cfg="cfail2")]
#[rustc_clean(label="predicates_of", cfg="cfail2")]
@ -41,8 +41,8 @@ pub struct LayoutPacked;
struct LayoutC;
#[cfg(not(cfail1))]
#[rustc_dirty(label="hir_owner", cfg="cfail2")]
#[rustc_dirty(label="hir_owner_nodes", cfg="cfail2")]
#[rustc_clean(label="hir_owner", cfg="cfail2")]
#[rustc_clean(label="hir_owner_nodes", cfg="cfail2")]
#[rustc_dirty(label="type_of", cfg="cfail2")]
#[rustc_clean(label="generics_of", cfg="cfail2")]
#[rustc_clean(label="predicates_of", cfg="cfail2")]

View File

@ -457,7 +457,7 @@ impl AddNoMangleToMethod for Foo {
#[rustc_clean(label="hir_owner", cfg="cfail2")]
#[rustc_clean(label="hir_owner", cfg="cfail3")]
impl AddNoMangleToMethod for Foo {
#[rustc_dirty(label="hir_owner", cfg="cfail2")]
#[rustc_clean(label="hir_owner", cfg="cfail2")]
#[rustc_clean(label="hir_owner", cfg="cfail3")]
#[no_mangle]
fn add_no_mangle_to_method(&self) { }
@ -478,7 +478,7 @@ impl MakeMethodInline for Foo {
#[rustc_clean(label="hir_owner", cfg="cfail2")]
#[rustc_clean(label="hir_owner", cfg="cfail3")]
impl MakeMethodInline for Foo {
#[rustc_dirty(label="hir_owner", cfg="cfail2")]
#[rustc_clean(label="hir_owner", cfg="cfail2")]
#[rustc_clean(label="hir_owner", cfg="cfail3")]
#[inline]
fn make_method_inline(&self) -> u8 { 0 }

View File

@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingAllowedAttrPass {
};
let allowed = |attr| pprust::attribute_to_string(attr).contains("allowed_attr");
if !item.attrs.iter().any(allowed) {
if !cx.tcx.hir().attrs(item.hir_id()).iter().any(allowed) {
cx.lint(MISSING_ALLOWED_ATTR, |lint| {
lint.build("Missing 'allowed_attr' attribute").set_span(span).emit()
});

View File

@ -28,8 +28,9 @@ macro_rules! fake_lint_pass {
impl LateLintPass<'_> for $struct {
fn check_crate(&mut self, cx: &LateContext, krate: &rustc_hir::Crate) {
let attrs = cx.tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
$(
if !cx.sess().contains_name(&krate.item.attrs, $attr) {
if !cx.sess().contains_name(attrs, $attr) {
cx.lint(CRATE_NOT_OKAY, |lint| {
let msg = format!("crate is not marked with #![{}]", $attr);
lint.build(&msg).set_span(krate.item.span).emit()

View File

@ -27,7 +27,8 @@ declare_lint_pass!(Pass => [CRATE_NOT_OKAY]);
impl<'tcx> LateLintPass<'tcx> for Pass {
fn check_crate(&mut self, cx: &LateContext, krate: &rustc_hir::Crate) {
if !cx.sess().contains_name(&krate.item.attrs, Symbol::intern("crate_okay")) {
let attrs = cx.tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
if !cx.sess().contains_name(attrs, Symbol::intern("crate_okay")) {
cx.lint(CRATE_NOT_OKAY, |lint| {
lint.build("crate is not marked with #![crate_okay]")
.set_span(krate.item.span)

View File

@ -493,6 +493,30 @@ LL | #![feature(rust1)]
|
= note: `#[warn(stable_features)]` on by default
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:46:1
|
LL | #![plugin_registrar]
| ^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:60:1
|
LL | #![should_panic]
| ^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:61:1
|
LL | #![ignore]
| ^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:67:1
|
LL | #![proc_macro_derive()]
| ^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:191:5
|
@ -517,6 +541,12 @@ warning: unused attribute
LL | #[macro_use] impl S { }
| ^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:204:1
|
LL | #[macro_export]
| ^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:207:17
|
@ -548,10 +578,10 @@ LL | #[macro_export] impl S { }
| ^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:204:1
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:223:1
|
LL | #[macro_export]
| ^^^^^^^^^^^^^^^
LL | #[plugin_registrar]
| ^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:228:17
@ -577,12 +607,6 @@ warning: unused attribute
LL | #[plugin_registrar] impl S { }
| ^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:223:1
|
LL | #[plugin_registrar]
| ^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:301:5
|
@ -607,6 +631,12 @@ warning: unused attribute
LL | #[path = "3800"] impl S { }
| ^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:314:1
|
LL | #[automatically_derived]
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:317:17
|
@ -638,10 +668,10 @@ LL | #[automatically_derived] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:314:1
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:361:1
|
LL | #[automatically_derived]
| ^^^^^^^^^^^^^^^^^^^^^^^^
LL | #[should_panic]
| ^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:17
@ -674,10 +704,10 @@ LL | #[should_panic] impl S { }
| ^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:361:1
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:380:1
|
LL | #[should_panic]
| ^^^^^^^^^^^^^^^
LL | #[ignore]
| ^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:383:17
@ -710,10 +740,10 @@ LL | #[ignore] impl S { }
| ^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:380:1
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:399:1
|
LL | #[ignore]
| ^^^^^^^^^
LL | #[no_implicit_prelude]
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:402:17
@ -746,10 +776,10 @@ LL | #[no_implicit_prelude] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:399:1
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:418:1
|
LL | #[no_implicit_prelude]
| ^^^^^^^^^^^^^^^^^^^^^^
LL | #[reexport_test_harness_main = "2900"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:421:17
@ -781,12 +811,6 @@ warning: unused attribute
LL | #[reexport_test_harness_main = "2900"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:418:1
|
LL | #[reexport_test_harness_main = "2900"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:445:5
|
@ -811,6 +835,18 @@ warning: unused attribute
LL | #[macro_escape] impl S { }
| ^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:458:1
|
LL | #[no_std]
| ^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:458:1
|
LL | #[no_std]
| ^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:462:17
|
@ -871,78 +907,6 @@ warning: crate-level attribute should be an inner attribute: add an exclamation
LL | #[no_std] impl S { }
| ^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:458:1
|
LL | #[no_std]
| ^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:458:1
|
LL | #[no_std]
| ^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:17
|
LL | mod inner { #![crate_name="0900"] }
| ^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be in the root module
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:17
|
LL | mod inner { #![crate_name="0900"] }
| ^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:5
|
LL | #[crate_name = "0900"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:5
|
LL | #[crate_name = "0900"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:5
|
LL | #[crate_name = "0900"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:5
|
LL | #[crate_name = "0900"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5
|
LL | #[crate_name = "0900"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5
|
LL | #[crate_name = "0900"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5
|
LL | #[crate_name = "0900"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5
|
LL | #[crate_name = "0900"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:659:1
|
@ -955,6 +919,78 @@ warning: crate-level attribute should be an inner attribute: add an exclamation
LL | #[crate_name = "0900"]
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:17
|
LL | mod inner { #![crate_name="0900"] }
| ^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be in the root module
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:17
|
LL | mod inner { #![crate_name="0900"] }
| ^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:5
|
LL | #[crate_name = "0900"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:5
|
LL | #[crate_name = "0900"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:5
|
LL | #[crate_name = "0900"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:5
|
LL | #[crate_name = "0900"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5
|
LL | #[crate_name = "0900"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5
|
LL | #[crate_name = "0900"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5
|
LL | #[crate_name = "0900"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5
|
LL | #[crate_name = "0900"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:1
|
LL | #[crate_type = "0800"]
| ^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:1
|
LL | #[crate_type = "0800"]
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:17
|
@ -1016,16 +1052,16 @@ LL | #[crate_type = "0800"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:1
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:709:1
|
LL | #[crate_type = "0800"]
| ^^^^^^^^^^^^^^^^^^^^^^
LL | #[feature(x0600)]
| ^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:1
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:709:1
|
LL | #[crate_type = "0800"]
| ^^^^^^^^^^^^^^^^^^^^^^
LL | #[feature(x0600)]
| ^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:17
@ -1088,16 +1124,16 @@ LL | #[feature(x0600)] impl S { }
| ^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:709:1
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:735:1
|
LL | #[feature(x0600)]
| ^^^^^^^^^^^^^^^^^
LL | #[no_main]
| ^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:709:1
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:735:1
|
LL | #[feature(x0600)]
| ^^^^^^^^^^^^^^^^^
LL | #[no_main]
| ^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:739:17
@ -1160,16 +1196,16 @@ LL | #[no_main] impl S { }
| ^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:735:1
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:773:1
|
LL | #[no_main]
| ^^^^^^^^^^
LL | #[recursion_limit="0200"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:735:1
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:773:1
|
LL | #[no_main]
| ^^^^^^^^^^
LL | #[recursion_limit="0200"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:777:17
@ -1232,16 +1268,16 @@ LL | #[recursion_limit="0200"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:773:1
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:798:1
|
LL | #[recursion_limit="0200"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | #[type_length_limit="0100"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:773:1
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:798:1
|
LL | #[recursion_limit="0200"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | #[type_length_limit="0100"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:17
@ -1303,41 +1339,5 @@ warning: crate-level attribute should be an inner attribute: add an exclamation
LL | #[type_length_limit="0100"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:798:1
|
LL | #[type_length_limit="0100"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:798:1
|
LL | #[type_length_limit="0100"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:46:1
|
LL | #![plugin_registrar]
| ^^^^^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:60:1
|
LL | #![should_panic]
| ^^^^^^^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:61:1
|
LL | #![ignore]
| ^^^^^^^^^^
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:67:1
|
LL | #![proc_macro_derive()]
| ^^^^^^^^^^^^^^^^^^^^^^^
warning: 205 warnings emitted

View File

@ -1,8 +1,8 @@
error: unused attribute
--> $DIR/unused-attr.rs:6:1
--> $DIR/unused-attr.rs:4:1
|
LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
LL | #![rustc_dummy]
| ^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/unused-attr.rs:1:9
@ -10,12 +10,24 @@ note: the lint level is defined here
LL | #![deny(unused_attributes)]
| ^^^^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr.rs:6:1
|
LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr.rs:9:1
|
LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr.rs:12:1
|
LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr.rs:14:5
|
@ -23,17 +35,11 @@ LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr.rs:12:1
--> $DIR/unused-attr.rs:18:1
|
LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr.rs:22:9
|
LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr.rs:20:5
|
@ -41,13 +47,7 @@ LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr.rs:18:1
|
LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr.rs:30:9
--> $DIR/unused-attr.rs:22:9
|
LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
@ -58,6 +58,18 @@ error: unused attribute
LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr.rs:30:9
|
LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr.rs:35:1
|
LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr.rs:37:5
|
@ -65,7 +77,7 @@ LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr.rs:35:1
--> $DIR/unused-attr.rs:41:1
|
LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
@ -82,17 +94,5 @@ error: unused attribute
LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr.rs:41:1
|
LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr.rs:4:1
|
LL | #![rustc_dummy]
| ^^^^^^^^^^^^^^^
error: aborting due to 15 previous errors

View File

@ -276,14 +276,15 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
}
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
let attrs = cx.tcx.hir().attrs(item.hir_id());
if is_relevant_item(cx, item) {
check_attrs(cx, item.span, item.ident.name, &item.attrs)
check_attrs(cx, item.span, item.ident.name, attrs)
}
match item.kind {
ItemKind::ExternCrate(..) | ItemKind::Use(..) => {
let skip_unused_imports = item.attrs.iter().any(|attr| attr.has_name(sym::macro_use));
let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
for attr in item.attrs {
for attr in attrs {
if in_external_macro(cx.sess(), attr.span) {
return;
}
@ -353,13 +354,13 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
if is_relevant_impl(cx, item) {
check_attrs(cx, item.span, item.ident.name, &item.attrs)
check_attrs(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()))
}
}
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
if is_relevant_trait(cx, item) {
check_attrs(cx, item.span, item.ident.name, &item.attrs)
check_attrs(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()))
}
}
}

View File

@ -76,8 +76,8 @@ impl CognitiveComplexity {
if rust_cc > self.limit.limit() {
let fn_span = match kind {
FnKind::ItemFn(ident, _, _, _, _) | FnKind::Method(ident, _, _, _) => ident.span,
FnKind::Closure(_) => {
FnKind::ItemFn(ident, _, _, _) | FnKind::Method(ident, _, _) => ident.span,
FnKind::Closure => {
let header_span = body_span.with_hi(decl.output.span().lo());
let pos = snippet_opt(cx, header_span).and_then(|snip| {
let low_offset = snip.find('|')?;

View File

@ -170,7 +170,8 @@ impl<'tcx> LateLintPass<'tcx> for Derive {
}) = item.kind
{
let ty = cx.tcx.type_of(item.def_id);
let is_automatically_derived = is_automatically_derived(&*item.attrs);
let attrs = cx.tcx.hir().attrs(item.hir_id());
let is_automatically_derived = is_automatically_derived(attrs);
check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived);
check_ord_partial_ord(cx, item.span, trait_ref, ty, is_automatically_derived);

View File

@ -208,12 +208,14 @@ impl_lint_pass!(DocMarkdown =>
);
impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) {
check_attrs(cx, &self.valid_idents, &krate.item.attrs);
fn check_crate(&mut self, cx: &LateContext<'tcx>, _: &'tcx hir::Crate<'_>) {
let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID);
check_attrs(cx, &self.valid_idents, attrs);
}
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
let attrs = cx.tcx.hir().attrs(item.hir_id());
let headers = check_attrs(cx, &self.valid_idents, attrs);
match item.kind {
hir::ItemKind::Fn(ref sig, _, body_id) => {
if !(is_entrypoint_fn(cx, item.def_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)) {
@ -249,7 +251,8 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
}
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
let attrs = cx.tcx.hir().attrs(item.hir_id());
let headers = check_attrs(cx, &self.valid_idents, attrs);
if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
if !in_external_macro(cx.tcx.sess, item.span) {
lint_for_missing_headers(cx, item.hir_id(), item.span, sig, headers, None, None);
@ -258,7 +261,8 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
}
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
let attrs = cx.tcx.hir().attrs(item.hir_id());
let headers = check_attrs(cx, &self.valid_idents, attrs);
if self.in_trait_impl || in_external_macro(cx.tcx.sess, item.span) {
return;
}

View File

@ -73,7 +73,8 @@ impl LateLintPass<'_> for ExhaustiveItems {
if_chain! {
if let ItemKind::Enum(..) | ItemKind::Struct(..) = item.kind;
if cx.access_levels.is_exported(item.hir_id());
if !item.attrs.iter().any(|a| a.has_name(sym::non_exhaustive));
let attrs = cx.tcx.hir().attrs(item.hir_id());
if !attrs.iter().any(|a| a.has_name(sym::non_exhaustive));
then {
let (lint, msg) = if let ItemKind::Struct(ref v, ..) = item.kind {
if v.fields().iter().any(|f| !f.vis.node.is_pub()) {

View File

@ -251,9 +251,9 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
hir_id: hir::HirId,
) {
let unsafety = match kind {
intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _, _) => unsafety,
intravisit::FnKind::Method(_, sig, _, _) => sig.header.unsafety,
intravisit::FnKind::Closure(_) => return,
intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _) => unsafety,
intravisit::FnKind::Method(_, sig, _) => sig.header.unsafety,
intravisit::FnKind::Closure => return,
};
// don't warn for implementations, it's not their fault
@ -267,9 +267,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
..
},
_,
_,
)
| intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _, _) => {
| intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _) => {
self.check_arg_number(cx, decl, span.with_hi(decl.output.span().hi()))
},
_ => {},
@ -281,7 +280,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
}
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
let attr = must_use_attr(&item.attrs);
let attrs = cx.tcx.hir().attrs(item.hir_id());
let attr = must_use_attr(attrs);
if let hir::ItemKind::Fn(ref sig, ref _generics, ref body_id) = item.kind {
let is_public = cx.access_levels.is_exported(item.hir_id());
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
@ -292,7 +292,7 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
check_needless_must_use(cx, &sig.decl, item.hir_id(), item.span, fn_header_span, attr);
return;
}
if is_public && !is_proc_macro(cx.sess(), &item.attrs) && attr_by_name(&item.attrs, "no_mangle").is_none() {
if is_public && !is_proc_macro(cx.sess(), attrs) && attr_by_name(attrs, "no_mangle").is_none() {
check_must_use_candidate(
cx,
&sig.decl,
@ -313,11 +313,12 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
if is_public && trait_ref_of_method(cx, item.hir_id()).is_none() {
check_result_unit_err(cx, &sig.decl, item.span, fn_header_span);
}
let attr = must_use_attr(&item.attrs);
let attrs = cx.tcx.hir().attrs(item.hir_id());
let attr = must_use_attr(attrs);
if let Some(attr) = attr {
check_needless_must_use(cx, &sig.decl, item.hir_id(), item.span, fn_header_span, attr);
} else if is_public
&& !is_proc_macro(cx.sess(), &item.attrs)
&& !is_proc_macro(cx.sess(), attrs)
&& trait_ref_of_method(cx, item.hir_id()).is_none()
{
check_must_use_candidate(
@ -345,7 +346,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
check_result_unit_err(cx, &sig.decl, item.span, fn_header_span);
}
let attr = must_use_attr(&item.attrs);
let attrs = cx.tcx.hir().attrs(item.hir_id());
let attr = must_use_attr(attrs);
if let Some(attr) = attr {
check_needless_must_use(cx, &sig.decl, item.hir_id(), item.span, fn_header_span, attr);
}
@ -353,7 +355,7 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
let body = cx.tcx.hir().body(eid);
Self::check_raw_ptr(cx, sig.header.unsafety, &sig.decl, body, item.hir_id());
if attr.is_none() && is_public && !is_proc_macro(cx.sess(), &item.attrs) {
if attr.is_none() && is_public && !is_proc_macro(cx.sess(), attrs) {
check_must_use_candidate(
cx,
&sig.decl,

View File

@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
_: Span,
hir_id: HirId,
) {
if let FnKind::Closure(_) = kind {
if let FnKind::Closure = kind {
return;
}
let ret_ty = utils::return_ty(cx, hir_id);

View File

@ -34,7 +34,8 @@ declare_lint_pass!(InlineFnWithoutBody => [INLINE_FN_WITHOUT_BODY]);
impl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody {
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
if let TraitItemKind::Fn(_, TraitFn::Required(_)) = item.kind {
check_attrs(cx, item.ident.name, &item.attrs);
let attrs = cx.tcx.hir().attrs(item.hir_id());
check_attrs(cx, item.ident.name, attrs);
}
}
}

View File

@ -578,7 +578,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops {
// also check for empty `loop {}` statements, skipping those in #[panic_handler]
if block.stmts.is_empty() && block.expr.is_none() && !is_in_panic_handler(cx, expr) {
let msg = "empty `loop {}` wastes CPU cycles";
let help = if is_no_std_crate(cx.tcx.hir().krate()) {
let help = if is_no_std_crate(cx) {
"you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body"
} else {
"you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body"

View File

@ -107,8 +107,8 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
if_chain! {
if cx.sess().opts.edition >= Edition::Edition2018;
if let hir::ItemKind::Use(path, _kind) = &item.kind;
if let Some(mac_attr) = item
.attrs
let attrs = cx.tcx.hir().attrs(item.hir_id());
if let Some(mac_attr) = attrs
.iter()
.find(|attr| attr.ident().map(|s| s.to_string()) == Some("macro_use".to_string()));
if let Res::Def(DefKind::Mod, id) = path.res;

View File

@ -32,8 +32,8 @@ pub struct MainRecursion {
impl_lint_pass!(MainRecursion => [MAIN_RECURSION]);
impl LateLintPass<'_> for MainRecursion {
fn check_crate(&mut self, _: &LateContext<'_>, krate: &Crate<'_>) {
self.has_no_std_attr = is_no_std_crate(krate);
fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) {
self.has_no_std_attr = is_no_std_crate(cx);
}
fn check_expr_post(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {

View File

@ -1207,11 +1207,11 @@ fn find_matches_sugg(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr
if b0 != b1;
let if_guard = &b0_arms[0].guard;
if if_guard.is_none() || b0_arms.len() == 1;
if b0_arms[0].attrs.is_empty();
if cx.tcx.hir().attrs(b0_arms[0].hir_id).is_empty();
if b0_arms[1..].iter()
.all(|arm| {
find_bool_lit(&arm.body.kind, desugared).map_or(false, |b| b == b0) &&
arm.guard.is_none() && arm.attrs.is_empty()
arm.guard.is_none() && cx.tcx.hir().attrs(arm.hir_id).is_empty()
});
then {
// The suggestion may be incorrect, because some arms can have `cfg` attributes

View File

@ -278,7 +278,7 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
span: Span,
_: HirId,
) {
if let FnKind::Closure(_) = k {
if let FnKind::Closure = k {
// Does not apply to closures
return;
}

View File

@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
return;
}
},
FnKind::Closure(..) => return,
FnKind::Closure => return,
}
let mir = cx.tcx.optimized_mir(def_id);

View File

@ -127,7 +127,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
}
fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) {
self.check_missing_docs_attrs(cx, &krate.item.attrs, krate.item.span, "the", "crate");
let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID);
self.check_missing_docs_attrs(cx, attrs, krate.item.span, "the", "crate");
}
fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
@ -160,13 +161,15 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
let (article, desc) = cx.tcx.article_and_description(it.def_id.to_def_id());
self.check_missing_docs_attrs(cx, &it.attrs, it.span, article, desc);
let attrs = cx.tcx.hir().attrs(it.hir_id());
self.check_missing_docs_attrs(cx, attrs, it.span, article, desc);
}
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx hir::TraitItem<'_>) {
let (article, desc) = cx.tcx.article_and_description(trait_item.def_id.to_def_id());
self.check_missing_docs_attrs(cx, &trait_item.attrs, trait_item.span, article, desc);
let attrs = cx.tcx.hir().attrs(trait_item.hir_id());
self.check_missing_docs_attrs(cx, attrs, trait_item.span, article, desc);
}
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
@ -181,16 +184,19 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
}
let (article, desc) = cx.tcx.article_and_description(impl_item.def_id.to_def_id());
self.check_missing_docs_attrs(cx, &impl_item.attrs, impl_item.span, article, desc);
let attrs = cx.tcx.hir().attrs(impl_item.hir_id());
self.check_missing_docs_attrs(cx, attrs, impl_item.span, article, desc);
}
fn check_struct_field(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::StructField<'_>) {
if !sf.is_positional() {
self.check_missing_docs_attrs(cx, &sf.attrs, sf.span, "a", "struct field");
let attrs = cx.tcx.hir().attrs(sf.hir_id);
self.check_missing_docs_attrs(cx, attrs, sf.span, "a", "struct field");
}
}
fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx hir::Variant<'_>) {
self.check_missing_docs_attrs(cx, &v.attrs, v.span, "a", "variant");
let attrs = cx.tcx.hir().attrs(v.id);
self.check_missing_docs_attrs(cx, attrs, v.span, "a", "variant");
}
}

View File

@ -93,7 +93,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
match it.kind {
hir::ItemKind::Fn(..) => {
let desc = "a function";
check_missing_inline_attrs(cx, &it.attrs, it.span, desc);
let attrs = cx.tcx.hir().attrs(it.hir_id());
check_missing_inline_attrs(cx, attrs, it.span, desc);
},
hir::ItemKind::Trait(ref _is_auto, ref _unsafe, ref _generics, ref _bounds, trait_items) => {
// note: we need to check if the trait is exported so we can't use
@ -108,7 +109,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
// an impl is not provided
let desc = "a default trait method";
let item = cx.tcx.hir().trait_item(tit.id);
check_missing_inline_attrs(cx, &item.attrs, item.span, desc);
let attrs = cx.tcx.hir().attrs(item.hir_id());
check_missing_inline_attrs(cx, attrs, item.span, desc);
}
},
}
@ -160,6 +162,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
}
}
check_missing_inline_attrs(cx, &impl_item.attrs, impl_item.span, desc);
let attrs = cx.tcx.hir().attrs(impl_item.hir_id());
check_missing_inline_attrs(cx, attrs, impl_item.span, desc);
}
}

View File

@ -115,8 +115,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrow {
}
}
fn check_item(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'_>) {
if is_automatically_derived(item.attrs) {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
let attrs = cx.tcx.hir().attrs(item.hir_id());
if is_automatically_derived(attrs) {
debug_assert!(self.derived_item.is_none());
self.derived_item = Some(item.def_id);
}

View File

@ -80,13 +80,14 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
}
match kind {
FnKind::ItemFn(.., header, _, attrs) => {
FnKind::ItemFn(.., header, _) => {
let attrs = cx.tcx.hir().attrs(hir_id);
if header.abi != Abi::Rust || requires_exact_signature(attrs) {
return;
}
},
FnKind::Method(..) => (),
FnKind::Closure(..) => return,
FnKind::Closure => return,
}
// Exclude non-inherent impls

View File

@ -43,9 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for PanicInResultFn {
span: Span,
hir_id: hir::HirId,
) {
if !matches!(fn_kind, FnKind::Closure(_))
&& is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym::result_type)
{
if !matches!(fn_kind, FnKind::Closure) && is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym::result_type) {
lint_impl_body(cx, span, body);
}
}

View File

@ -35,7 +35,8 @@ impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
if_chain! {
if let ItemKind::Impl(Impl { of_trait: Some(ref trait_ref), items: impl_items, .. }) = item.kind;
if !is_automatically_derived(&*item.attrs);
let attrs = cx.tcx.hir().attrs(item.hir_id());
if !is_automatically_derived(attrs);
if let Some(eq_trait) = cx.tcx.lang_items().eq_trait();
if trait_ref.path.res.def_id() == eq_trait;
then {

View File

@ -224,10 +224,11 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
}
match kind {
FnKind::ItemFn(.., header, _, attrs) => {
FnKind::ItemFn(.., header, _) => {
if header.abi != Abi::Rust {
return;
}
let attrs = cx.tcx.hir().attrs(hir_id);
for a in attrs {
if let Some(meta_items) = a.meta_item_list() {
if a.has_name(sym::proc_macro_derive)
@ -239,7 +240,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
}
},
FnKind::Method(..) => (),
FnKind::Closure(..) => return,
FnKind::Closure => return,
}
// Exclude non-inherent impls

View File

@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
if let Some(stmt) = block.stmts.iter().last();
if let StmtKind::Local(local) = &stmt.kind;
if local.ty.is_none();
if local.attrs.is_empty();
if cx.tcx.hir().attrs(local.hir_id).is_empty();
if let Some(initexpr) = &local.init;
if let PatKind::Binding(.., ident, _) = local.pat.kind;
if let ExprKind::Path(qpath) = &retexpr.kind;
@ -131,7 +131,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
_: HirId,
) {
match kind {
FnKind::Closure(_) => {
FnKind::Closure => {
// when returning without value in closure, replace this `return`
// with an empty block to prevent invalid suggestion (see #6501)
let replacement = if let ExprKind::Ret(None) = &body.value.kind {
@ -177,7 +177,8 @@ fn check_final_expr<'tcx>(
// simple return is always "bad"
ExprKind::Ret(ref inner) => {
// allow `#[cfg(a)] return a; #[cfg(b)] return b;`
if !expr.attrs.iter().any(attr_is_cfg) {
let attrs = cx.tcx.hir().attrs(expr.hir_id);
if !attrs.iter().any(attr_is_cfg) {
let borrows = inner.map_or(false, |inner| last_statement_borrows(cx, inner));
if !borrows {
emit_return_lint(

View File

@ -66,12 +66,12 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
) {
// Abort if public function/method or closure.
match fn_kind {
FnKind::ItemFn(.., visibility, _) | FnKind::Method(.., Some(visibility), _) => {
FnKind::ItemFn(.., visibility) | FnKind::Method(.., Some(visibility)) => {
if visibility.node.is_pub() {
return;
}
},
FnKind::Closure(..) => return,
FnKind::Closure => return,
_ => (),
}

View File

@ -2,7 +2,7 @@
//! to generate a clippy lint detecting said code automatically.
use crate::utils::get_attr;
use rustc_ast::ast::{Attribute, LitFloatType, LitKind};
use rustc_ast::ast::{LitFloatType, LitKind};
use rustc_ast::walk_list;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
@ -10,7 +10,6 @@ use rustc_hir::intravisit::{NestedVisitorMap, Visitor};
use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, Pat, PatKind, QPath, Stmt, StmtKind, TyKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::hir::map::Map;
use rustc_session::Session;
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
@ -66,7 +65,7 @@ fn done() {
impl<'tcx> LateLintPass<'tcx> for Author {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
if !has_attr(cx.sess(), &item.attrs) {
if !has_attr(cx, item.hir_id()) {
return;
}
prelude();
@ -75,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
}
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
if !has_attr(cx.sess(), &item.attrs) {
if !has_attr(cx, item.hir_id()) {
return;
}
prelude();
@ -84,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
}
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
if !has_attr(cx.sess(), &item.attrs) {
if !has_attr(cx, item.hir_id()) {
return;
}
prelude();
@ -93,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
}
fn check_variant(&mut self, cx: &LateContext<'tcx>, var: &'tcx hir::Variant<'_>) {
if !has_attr(cx.sess(), &var.attrs) {
if !has_attr(cx, var.id) {
return;
}
prelude();
@ -103,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
}
fn check_struct_field(&mut self, cx: &LateContext<'tcx>, field: &'tcx hir::StructField<'_>) {
if !has_attr(cx.sess(), &field.attrs) {
if !has_attr(cx, field.hir_id) {
return;
}
prelude();
@ -112,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
}
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
if !has_attr(cx.sess(), &expr.attrs) {
if !has_attr(cx, expr.hir_id) {
return;
}
prelude();
@ -121,7 +120,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
}
fn check_arm(&mut self, cx: &LateContext<'tcx>, arm: &'tcx hir::Arm<'_>) {
if !has_attr(cx.sess(), &arm.attrs) {
if !has_attr(cx, arm.hir_id) {
return;
}
prelude();
@ -130,7 +129,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
}
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx hir::Stmt<'_>) {
if !has_attr(cx.sess(), stmt.kind.attrs(|id| cx.tcx.hir().item(id))) {
if !has_attr(cx, stmt.hir_id) {
return;
}
prelude();
@ -139,7 +138,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
}
fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ForeignItem<'_>) {
if !has_attr(cx.sess(), &item.attrs) {
if !has_attr(cx, item.hir_id()) {
return;
}
prelude();
@ -719,8 +718,9 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
}
}
fn has_attr(sess: &Session, attrs: &[Attribute]) -> bool {
get_attr(sess, attrs, "author").count() > 0
fn has_attr(cx: &LateContext<'_>, hir_id: hir::HirId) -> bool {
let attrs = cx.tcx.hir().attrs(hir_id);
get_attr(cx.sess(), attrs, "author").count() > 0
}
#[must_use]

View File

@ -33,14 +33,14 @@ declare_lint_pass!(DeepCodeInspector => [DEEP_CODE_INSPECTION]);
impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
if !has_attr(cx.sess(), &item.attrs) {
if !has_attr(cx.sess(), cx.tcx.hir().attrs(item.hir_id())) {
return;
}
print_item(cx, item);
}
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
if !has_attr(cx.sess(), &item.attrs) {
if !has_attr(cx.sess(), cx.tcx.hir().attrs(item.hir_id())) {
return;
}
println!("impl item `{}`", item.ident.name);
@ -89,14 +89,14 @@ impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector {
//
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
if !has_attr(cx.sess(), &expr.attrs) {
if !has_attr(cx.sess(), cx.tcx.hir().attrs(expr.hir_id)) {
return;
}
print_expr(cx, expr, 0);
}
fn check_arm(&mut self, cx: &LateContext<'tcx>, arm: &'tcx hir::Arm<'_>) {
if !has_attr(cx.sess(), &arm.attrs) {
if !has_attr(cx.sess(), cx.tcx.hir().attrs(arm.hir_id)) {
return;
}
print_pat(cx, &arm.pat, 1);
@ -109,7 +109,7 @@ impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector {
}
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx hir::Stmt<'_>) {
if !has_attr(cx.sess(), stmt.kind.attrs(|id| cx.tcx.hir().item(id))) {
if !has_attr(cx.sess(), cx.tcx.hir().attrs(stmt.hir_id)) {
return;
}
match stmt.kind {

View File

@ -61,7 +61,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::Node;
use rustc_hir::{
def, Arm, Block, Body, Constness, Crate, Expr, ExprKind, FnDecl, HirId, ImplItem, ImplItemKind, Item, ItemKind,
def, Arm, Block, Body, Constness, Expr, ExprKind, FnDecl, HirId, ImplItem, ImplItemKind, Item, ItemKind,
MatchSource, Param, Pat, PatKind, Path, PathSegment, QPath, TraitItem, TraitItemKind, TraitRef, TyKind, Unsafety,
};
use rustc_infer::infer::TyCtxtInferExt;
@ -1510,8 +1510,8 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
did.map_or(false, |did| must_use_attr(&cx.tcx.get_attrs(did)).is_some())
}
pub fn is_no_std_crate(krate: &Crate<'_>) -> bool {
krate.item.attrs.iter().any(|attr| {
pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool {
cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| {
if let ast::AttrKind::Normal(ref attr, _) = attr.kind {
attr.path == sym::no_std
} else {