diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index c9a5541585fc7..43b93d03ff6fb 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -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::>(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::>().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 = __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 } } } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 8b740b7774089..777d3a5060b92 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -217,44 +217,41 @@ impl<'hir> LoweringContext<'_, 'hir> { pub fn lower_item(&mut self, i: &Item) -> Option> { 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, ¶m.attrs); hir::Param { - attrs: self.lower_attrs(¶m.attrs), - hir_id: self.lower_node_id(param.id), + hir_id, pat: self.lower_pat(¶m.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(¶meter.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, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 756caf18ec5eb..057e4d81f80fd 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -114,6 +114,8 @@ struct LoweringContext<'a, 'hir: 'a> { generator_kind: Option, + attrs: BTreeMap, + /// 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, @@ -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::>().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, ¶m.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(¶m.attrs, sym::may_dangle), - attrs: self.lower_attrs(¶m.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))) } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 7b8ce157fc2b4..854aaac757fb0 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -433,12 +433,10 @@ pub fn start_async_codegen( 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!( diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 1938cdd1e46f4..8f61adcd8e288 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -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, pub trait_map: BTreeMap>, + + /// Collected attributes from HIR nodes. + pub attrs: BTreeMap, } 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 : = ;`). #[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); } diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index e24eb5e449002..e0b3d9026a07c 100644 --- a/compiler/rustc_hir/src/hir_id.rs +++ b/compiler/rustc_hir/src/hir_id.rs @@ -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 { + map: IndexVec>, +} + +impl HirIdVec { + 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 { + &self.map[id] + } + + pub fn iter(&self) -> impl Iterator { + self.map.iter().flat_map(|la| la.iter()) + } + + pub fn iter_enumerated(&self) -> impl Iterator { + self.map.iter_enumerated().flat_map(|(owner, la)| { + la.iter_enumerated().map(move |(local_id, attr)| (HirId { owner, local_id }, attr)) + }) + } +} + +impl std::ops::Index for HirIdVec { + type Output = T; + + fn index(&self, id: HirId) -> &T { + &self.map[id.owner][id.local_id] + } +} + +impl std::ops::IndexMut for HirIdVec { + fn index_mut(&mut self, id: HirId) -> &mut T { + &mut self.map[id.owner][id.local_id] + } +} diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 6a2719c2d6677..df63f0d48c3dd 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -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(¶m.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>) { diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 5fb4b8a58c210..55e87663a1ee7 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -139,11 +139,10 @@ impl HashStable for VisibilityKind<'_> impl HashStable 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 HashStable for TraitItem<'_> { impl HashStable 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 HashStable for ImplItem<'_> { impl HashStable 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 HashStable for ForeignItem<'_> { impl HashStable 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 HashStable for Item<'_> { impl HashStable 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); diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 416918e3344ee..9c2766a16318d 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -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>, + attrs: &'a BTreeMap, 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, 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(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 { diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index 1162379d3d981..89a5836d6dfe7 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -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); } } diff --git a/compiler/rustc_incremental/src/assert_module_sources.rs b/compiler/rustc_incremental/src/assert_module_sources.rs index 17d8ac9c88297..5fb2c1cb9c923 100644 --- a/compiler/rustc_incremental/src/assert_module_sources.rs +++ b/compiler/rustc_incremental/src/assert_module_sources.rs @@ -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); } }) diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index 8a83149d73235..0b544b8ab415e 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -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) { + fn report_unchecked_attrs(&self, mut checked_attrs: FxHashSet) { 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); } diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 7cc4a5e9785e5..3882818952c33 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -695,9 +695,7 @@ impl IndexVec { pub fn convert_index_type(self) -> IndexVec { IndexVec { raw: self.raw, _marker: PhantomData } } -} -impl IndexVec { /// 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 IndexVec { } } - #[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 IndexVec { } } +impl IndexVec { + #[inline] + pub fn resize(&mut self, new_len: usize, value: T) { + self.raw.resize(new_len, value) + } +} + impl IndexVec { #[inline] pub fn binary_search(&self, value: &T) -> Result { diff --git a/compiler/rustc_interface/src/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs index d0262935c894c..4637055a82ded 100644 --- a/compiler/rustc_interface/src/proc_macro_decls.rs +++ b/compiler/rustc_interface/src/proc_macro_decls.rs @@ -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()); } } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 4258a4b4237a8..dca5e470e7fb9 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -508,8 +508,7 @@ impl MissingDoc { fn check_missing_docs_attrs( &self, cx: &LateContext<'_>, - id: Option, - 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() }); diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 26e536e8f1ddb..9b1a339572ec3 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -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; } diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index e019b621aa359..9a64737f3a25d 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -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(&mut self, id: hir::HirId, attrs: &'tcx [ast::Attribute], f: F) + fn with_lint_attrs(&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, ¶m.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); diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index dbcab72ddf2eb..b3bdaf5bdc7d0 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -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(&mut self, id: hir::HirId, attrs: &[ast::Attribute], f: F) + fn with_lint_attrs(&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, ¶m.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); }); } diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 121dde325f74b..be9c6eafb6fdb 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -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(..) => { diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 997b91363201f..67946dfb292a6 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -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? diff --git a/compiler/rustc_metadata/src/link_args.rs b/compiler/rustc_metadata/src/link_args.rs index d088288c50767..9e1ac33368c7f 100644 --- a/compiler/rustc_metadata/src/link_args.rs +++ b/compiler/rustc_metadata/src/link_args.rs @@ -8,7 +8,7 @@ crate fn collect(tcx: TyCtxt<'_>) -> Vec { 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); } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 4d63b6d074af0..523e016eeb9f2 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -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, diff --git a/compiler/rustc_middle/src/hir/map/blocks.rs b/compiler/rustc_middle/src/hir/map/blocks.rs index 9222ce1015eba..706c79009496b 100644 --- a/compiler/rustc_middle/src/hir/map/blocks.rs +++ b/compiler/rustc_middle/src/hir/map/blocks.rs @@ -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"), }, diff --git a/compiler/rustc_middle/src/hir/map/collector.rs b/compiler/rustc_middle/src/hir/map/collector.rs index a5ffa9c7a54b0..b1dd405a6be68 100644 --- a/compiler/rustc_middle/src/hir/map/collector.rs +++ b/compiler/rustc_middle/src/hir/map/collector.rs @@ -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) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 5c2bd575e7d55..41ecffb9c5604 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -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. diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 5f9cf8771eada..cf4e473d8aca1 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -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> for OwnerNodes<'tcx> { } } +#[derive(Copy, Clone)] +pub struct AttributeMap<'tcx> { + map: &'tcx BTreeMap, + prefix: LocalDefId, +} + +impl<'a, 'tcx> HashStable> 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::>()[..]) + .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(); diff --git a/compiler/rustc_middle/src/ich/impls_hir.rs b/compiler/rustc_middle/src/ich/impls_hir.rs index 5ef70a89051ea..abf56832329b2 100644 --- a/compiler/rustc_middle/src/ich/impls_hir.rs +++ b/compiler/rustc_middle/src/ich/impls_hir.rs @@ -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); }) } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index a8600af1de28e..b03b26d64606c 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -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. /// diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index 576b537c01766..ef8bd20d51098 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -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; } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 6cc649c1180c5..c7b266f18bf8d 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -62,12 +62,12 @@ impl CheckAttrVisitor<'tcx> { fn check_attributes( &self, hir_id: HirId, - attrs: &'hir [Attribute], span: &Span, target: Target, item: Option>, ) { 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, - ¯o_def.span, - Target::MacroDef, - None, - ); + self.check_attributes(macro_def.hir_id(), ¯o_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, ¶m.span, Target::Param, None); + self.check_attributes(param.hir_id, ¶m.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()); } } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 62a95aa57c29f..ca25445486d40 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -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. diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index 3ec7ea39248bf..8dd3700e5b6af 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -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 { 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 diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index 0d3a7ea3a8a00..57848208f945e 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -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"); } } diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index a2b6dd17ad9ba..ccbfc6b166160 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -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); } diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index 8e2ad7f783e9b..7e6bb9779f077 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -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() { diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs index 02b20e45d000c..3dfe317a4bd17 100644 --- a/compiler/rustc_passes/src/lib_features.rs +++ b/compiler/rustc_passes/src/lib_features.rs @@ -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 diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index 93fb23c018bf0..89bc2e1a9870f 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -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); diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index c4c1034374360..3e957aabd7763 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -97,7 +97,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { fn annotate( &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); diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index daff94cb6d355..de369ba9bbbe2 100644 --- a/compiler/rustc_passes/src/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs @@ -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) diff --git a/compiler/rustc_plugin_impl/src/build.rs b/compiler/rustc_plugin_impl/src/build.rs index d5c287fb3bcb3..a49afa35e4624 100644 --- a/compiler/rustc_plugin_impl/src/build.rs +++ b/compiler/rustc_plugin_impl/src/build.rs @@ -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)); } } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 6e0e1c5eeef15..72be266b338ba 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -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 diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 493f25f4992d1..4f92532e3a698 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -1239,7 +1239,8 @@ fn compute_object_lifetime_defaults(tcx: TyCtxt<'_>) -> HirIdMap 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), }, ); } diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index b3f281bcabcec..042f3183796d3 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -139,6 +139,7 @@ impl<'tcx> SaveContext<'tcx> { pub fn get_extern_item_data(&self, item: &hir::ForeignItem<'_>) -> Option { 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 { 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); } ( diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index e6c551ff4d41b..13757ac41325b 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -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()); } diff --git a/compiler/rustc_typeck/src/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs index 88e8dd3cb129a..55c6420ae5e2e 100644 --- a/compiler/rustc_typeck/src/check/regionck.rs +++ b/compiler/rustc_typeck/src/check/regionck.rs @@ -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" ); diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index 6ddc26efeae35..0fc49c4ae2f48 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -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( diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 29eb67f023f0b..539895feddd42 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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( diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 27ce064669d2c..64375964e7068 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -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( &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(), - ¯o_def.attrs, macro_def.hir_id(), macro_def.span, |_| (), diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index ba6bb359b9135..b6782fb75df35 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -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)) } diff --git a/src/test/incremental/hashes/enum_defs.rs b/src/test/incremental/hashes/enum_defs.rs index 624870cc9ec8f..c73c03ca14e56 100644 --- a/src/test/incremental/hashes/enum_defs.rs +++ b/src/test/incremental/hashes/enum_defs.rs @@ -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 { diff --git a/src/test/incremental/hashes/extern_mods.rs b/src/test/incremental/hashes/extern_mods.rs index dd7751677579c..7a923134331a6 100644 --- a/src/test/incremental/hashes/extern_mods.rs +++ b/src/test/incremental/hashes/extern_mods.rs @@ -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" { diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs index 706cbcf4caf34..ed67b2dcb0480 100644 --- a/src/test/incremental/hashes/function_interfaces.rs +++ b/src/test/incremental/hashes/function_interfaces.rs @@ -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() {} diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs index 2e98abae58b3d..ae8f2ace217dc 100644 --- a/src/test/incremental/hashes/inherent_impls.rs +++ b/src/test/incremental/hashes/inherent_impls.rs @@ -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) { } diff --git a/src/test/incremental/hashes/statics.rs b/src/test/incremental/hashes/statics.rs index caf4e12cc4b76..6f4089c60fe23 100644 --- a/src/test/incremental/hashes/statics.rs +++ b/src/test/incremental/hashes/statics.rs @@ -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; diff --git a/src/test/incremental/hashes/struct_defs.rs b/src/test/incremental/hashes/struct_defs.rs index a42bd9261f95d..1339a1e5bf216 100644 --- a/src/test/incremental/hashes/struct_defs.rs +++ b/src/test/incremental/hashes/struct_defs.rs @@ -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")] diff --git a/src/test/incremental/hashes/trait_impls.rs b/src/test/incremental/hashes/trait_impls.rs index ddec6ff8eecdd..e9118da5a6137 100644 --- a/src/test/incremental/hashes/trait_impls.rs +++ b/src/test/incremental/hashes/trait_impls.rs @@ -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 } diff --git a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs index 4e9d4d342734c..124dd670d0931 100644 --- a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs +++ b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs @@ -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() }); diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs index 736a8633dac53..8b1a3887f157f 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs @@ -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() diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs index bd477b793fc70..c9269d2b9baa8 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs @@ -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) diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index c908d2589cf49..c864ccc868665 100644 --- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -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 | @@ -872,16 +908,16 @@ LL | #[no_std] impl S { } | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:458:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:659:1 | -LL | #[no_std] - | ^^^^^^^^^ +LL | #[crate_name = "0900"] + | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:458:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:659:1 | -LL | #[no_std] - | ^^^^^^^^^ +LL | #[crate_name = "0900"] + | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute --> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:17 @@ -944,15 +980,15 @@ LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:659:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:1 | -LL | #[crate_name = "0900"] +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:659:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:1 | -LL | #[crate_name = "0900"] +LL | #[crate_type = "0800"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute @@ -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 diff --git a/src/test/ui/unused/unused-attr.stderr b/src/test/ui/unused/unused-attr.stderr index fd7412db2257c..707521b7802f0 100644 --- a/src/test/ui/unused/unused-attr.stderr +++ b/src/test/ui/unused/unused-attr.stderr @@ -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 @@ -11,16 +11,16 @@ LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr.rs:9:1 + --> $DIR/unused-attr.rs:6:1 | LL | #[rustc_dummy] | ^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr.rs:14:5 + --> $DIR/unused-attr.rs:9:1 | -LL | #[rustc_dummy] - | ^^^^^^^^^^^^^^ +LL | #[rustc_dummy] + | ^^^^^^^^^^^^^^ error: unused attribute --> $DIR/unused-attr.rs:12:1 @@ -29,10 +29,16 @@ LL | #[rustc_dummy] | ^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr.rs:22:9 + --> $DIR/unused-attr.rs:14:5 | -LL | #[rustc_dummy] - | ^^^^^^^^^^^^^^ +LL | #[rustc_dummy] + | ^^^^^^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr.rs:18:1 + | +LL | #[rustc_dummy] + | ^^^^^^^^^^^^^^ error: unused attribute --> $DIR/unused-attr.rs:20:5 @@ -41,7 +47,13 @@ LL | #[rustc_dummy] | ^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr.rs:18:1 + --> $DIR/unused-attr.rs:22:9 + | +LL | #[rustc_dummy] + | ^^^^^^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr.rs:27:1 | LL | #[rustc_dummy] | ^^^^^^^^^^^^^^ @@ -53,7 +65,7 @@ LL | #[rustc_dummy] | ^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr.rs:27:1 + --> $DIR/unused-attr.rs:35:1 | LL | #[rustc_dummy] | ^^^^^^^^^^^^^^ @@ -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 diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs index 652d1fa16b6de..78f0846e88e7d 100644 --- a/src/tools/clippy/clippy_lints/src/attrs.rs +++ b/src/tools/clippy/clippy_lints/src/attrs.rs @@ -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())) } } } diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs index f21a734bb439f..658d445dfec54 100644 --- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs +++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs @@ -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('|')?; diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index e8510bde9adcd..66cf6682f8501 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -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); diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs index 39a202f281cb7..23c99e45ca7fc 100644 --- a/src/tools/clippy/clippy_lints/src/doc.rs +++ b/src/tools/clippy/clippy_lints/src/doc.rs @@ -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; } diff --git a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs index ab9be3398bfa6..316f748486280 100644 --- a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs +++ b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs @@ -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()) { diff --git a/src/tools/clippy/clippy_lints/src/functions.rs b/src/tools/clippy/clippy_lints/src/functions.rs index e4b3a9009f612..234cb0f53aa0c 100644 --- a/src/tools/clippy/clippy_lints/src/functions.rs +++ b/src/tools/clippy/clippy_lints/src/functions.rs @@ -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, diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index 7208e66ff7be1..9e1a8864a3ebe 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -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); diff --git a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs index d1c3fdc71461b..00acbd6cc3f76 100644 --- a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs +++ b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs @@ -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); } } } diff --git a/src/tools/clippy/clippy_lints/src/loops.rs b/src/tools/clippy/clippy_lints/src/loops.rs index c89a087657509..9b626d81ebd81 100644 --- a/src/tools/clippy/clippy_lints/src/loops.rs +++ b/src/tools/clippy/clippy_lints/src/loops.rs @@ -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" diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs index 40f04bd677d52..6d9c78393c8c4 100644 --- a/src/tools/clippy/clippy_lints/src/macro_use.rs +++ b/src/tools/clippy/clippy_lints/src/macro_use.rs @@ -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; diff --git a/src/tools/clippy/clippy_lints/src/main_recursion.rs b/src/tools/clippy/clippy_lints/src/main_recursion.rs index 1ed3f3de83908..1b274c79d3820 100644 --- a/src/tools/clippy/clippy_lints/src/main_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/main_recursion.rs @@ -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<'_>) { diff --git a/src/tools/clippy/clippy_lints/src/matches.rs b/src/tools/clippy/clippy_lints/src/matches.rs index efc8b13942507..9c87759d51d2d 100644 --- a/src/tools/clippy/clippy_lints/src/matches.rs +++ b/src/tools/clippy/clippy_lints/src/matches.rs @@ -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 diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs index 2ef5c6aa2a4e2..35b4c3d5b03ab 100644 --- a/src/tools/clippy/clippy_lints/src/misc.rs +++ b/src/tools/clippy/clippy_lints/src/misc.rs @@ -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; } diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs index 6ebeaced62a33..b0998a80128ce 100644 --- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs +++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs @@ -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); diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 761b9261772b2..6ec4c38d0f9cc 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -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"); } } diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 47d7c5306c433..9b604471573d9 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -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); } } diff --git a/src/tools/clippy/clippy_lints/src/needless_borrow.rs b/src/tools/clippy/clippy_lints/src/needless_borrow.rs index 1453ea6e8975d..1aadcfd87b60f 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrow.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrow.rs @@ -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); } diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 54033f4087140..cac4b2075114a 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -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 diff --git a/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs b/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs index 37e2b50def17a..207423a186149 100644 --- a/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs +++ b/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs @@ -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); } } diff --git a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs index 3d6129aa78d4c..aca1ed5ca6563 100644 --- a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs +++ b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs @@ -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 { diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index b9ba32001b513..ff700aa514607 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -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 diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs index e438f92b136ac..40c0f1f45895b 100644 --- a/src/tools/clippy/clippy_lints/src/returns.rs +++ b/src/tools/clippy/clippy_lints/src/returns.rs @@ -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( diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs index 1e58576d0599c..8e076397c119a 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs @@ -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, _ => (), } diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 6e3d4fde10777..3dd190ba44018 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -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] diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs index 9c1d98cd70745..9e3973e1d51fc 100644 --- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs @@ -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 { diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 42512cadfb18d..4cd7ed5c45da3 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -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 {