X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=sidebyside;f=compiler%2Frustc_lint%2Fsrc%2Fbuiltin.rs;h=697e90fdaa95aba13d8a08ce1f6145aa6c30112a;hb=fd649a3cc5e9f17c8aee070227e8c71f094560b7;hp=f27fd90c55c2a9527972be0ab8353705d7eff02d;hpb=d667105681726fe84ef6256b8a75b2e770bed3e6;p=rust.git diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index f27fd90c55c..697e90fdaa9 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -56,9 +56,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID}; use rustc_hir::intravisit::FnKind as HirFnKind; -use rustc_hir::{ - Body, FnDecl, ForeignItemKind, GenericParamKind, HirId, Node, PatKind, PredicateOrigin, -}; +use rustc_hir::{Body, FnDecl, ForeignItemKind, GenericParamKind, Node, PatKind, PredicateOrigin}; use rustc_index::vec::Idx; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::layout::{LayoutError, LayoutOf}; @@ -582,26 +580,28 @@ fn check_trait_item(&mut self, cx: &LateContext<'_>, trait_item: &hir::TraitItem } fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) { - // If the method is an impl for a trait, don't doc. - if method_context(cx, impl_item.hir_id()) == MethodLateContext::TraitImpl { - return; - } - - // If the method is an impl for an item with docs_hidden, don't doc. - if method_context(cx, impl_item.hir_id()) == MethodLateContext::PlainImpl { - let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()); - let impl_ty = cx.tcx.type_of(parent); - let outerdef = match impl_ty.kind() { - ty::Adt(def, _) => Some(def.did()), - ty::Foreign(def_id) => Some(*def_id), - _ => None, - }; - let is_hidden = match outerdef { - Some(id) => cx.tcx.is_doc_hidden(id), - None => false, - }; - if is_hidden { - return; + let context = method_context(cx, impl_item.owner_id.def_id); + + match context { + // If the method is an impl for a trait, don't doc. + MethodLateContext::TraitImpl => return, + MethodLateContext::TraitAutoImpl => {} + // If the method is an impl for an item with docs_hidden, don't doc. + MethodLateContext::PlainImpl => { + let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()); + let impl_ty = cx.tcx.type_of(parent); + let outerdef = match impl_ty.kind() { + ty::Adt(def, _) => Some(def.did()), + ty::Foreign(def_id) => Some(*def_id), + _ => None, + }; + let is_hidden = match outerdef { + Some(id) => cx.tcx.is_doc_hidden(id), + None => false, + }; + if is_hidden { + return; + } } } @@ -1296,19 +1296,18 @@ fn check_fn( _: &'tcx FnDecl<'_>, _: &'tcx Body<'_>, span: Span, - hir_id: HirId, + def_id: LocalDefId, ) { if fn_kind.asyncness() == IsAsync::Async && !cx.tcx.features().closure_track_caller - && let attrs = cx.tcx.hir().attrs(hir_id) // Now, check if the function has the `#[track_caller]` attribute - && let Some(attr) = attrs.iter().find(|attr| attr.has_name(sym::track_caller)) - { - cx.emit_spanned_lint(UNGATED_ASYNC_FN_TRACK_CALLER, attr.span, BuiltinUngatedAsyncFnTrackCaller { - label: span, - parse_sess: &cx.tcx.sess.parse_sess, - }); - } + && let Some(attr) = cx.tcx.get_attr(def_id.to_def_id(), sym::track_caller) + { + cx.emit_spanned_lint(UNGATED_ASYNC_FN_TRACK_CALLER, attr.span, BuiltinUngatedAsyncFnTrackCaller { + label: span, + parse_sess: &cx.tcx.sess.parse_sess, + }); + } } } @@ -2175,13 +2174,31 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { dropped_predicate_count += 1; } - if drop_predicate && !in_where_clause { - lint_spans.push(predicate_span); - } else if drop_predicate && i + 1 < num_predicates { - // If all the bounds on a predicate were inferable and there are - // further predicates, we want to eat the trailing comma. - let next_predicate_span = hir_generics.predicates[i + 1].span(); - where_lint_spans.push(predicate_span.to(next_predicate_span.shrink_to_lo())); + if drop_predicate { + if !in_where_clause { + lint_spans.push(predicate_span); + } else if predicate_span.from_expansion() { + // Don't try to extend the span if it comes from a macro expansion. + where_lint_spans.push(predicate_span); + } else if i + 1 < num_predicates { + // If all the bounds on a predicate were inferable and there are + // further predicates, we want to eat the trailing comma. + let next_predicate_span = hir_generics.predicates[i + 1].span(); + if next_predicate_span.from_expansion() { + where_lint_spans.push(predicate_span); + } else { + where_lint_spans + .push(predicate_span.to(next_predicate_span.shrink_to_lo())); + } + } else { + // Eat the optional trailing comma after the last predicate. + let where_span = hir_generics.where_clause_span; + if where_span.from_expansion() { + where_lint_spans.push(predicate_span); + } else { + where_lint_spans.push(predicate_span.to(where_span.shrink_to_hi())); + } + } } else { where_lint_spans.extend(self.consolidate_outlives_bound_spans( predicate_span.shrink_to_lo(), @@ -2225,6 +2242,11 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { Applicability::MaybeIncorrect }; + // Due to macros, there might be several predicates with the same span + // and we only want to suggest removing them once. + lint_spans.sort_unstable(); + lint_spans.dedup(); + cx.emit_spanned_lint( EXPLICIT_OUTLIVES_REQUIREMENTS, lint_spans.clone(), @@ -2661,7 +2683,7 @@ pub struct ClashingExternDeclarations { /// the symbol should be reported as a clashing declaration. // FIXME: Technically, we could just store a &'tcx str here without issue; however, the // `impl_lint_pass` macro doesn't currently support lints parametric over a lifetime. - seen_decls: FxHashMap, + seen_decls: FxHashMap, } /// Differentiate between whether the name for an extern decl came from the link_name attribute or @@ -2687,19 +2709,20 @@ impl ClashingExternDeclarations { pub(crate) fn new() -> Self { ClashingExternDeclarations { seen_decls: FxHashMap::default() } } + /// Insert a new foreign item into the seen set. If a symbol with the same name already exists /// for the item, return its HirId without updating the set. - fn insert(&mut self, tcx: TyCtxt<'_>, fi: &hir::ForeignItem<'_>) -> Option { + fn insert(&mut self, tcx: TyCtxt<'_>, fi: &hir::ForeignItem<'_>) -> Option { let did = fi.owner_id.to_def_id(); let instance = Instance::new(did, ty::List::identity_for_item(tcx, did)); let name = Symbol::intern(tcx.symbol_name(instance).name); - if let Some(&hir_id) = self.seen_decls.get(&name) { + if let Some(&existing_id) = self.seen_decls.get(&name) { // Avoid updating the map with the new entry when we do find a collision. We want to // make sure we're always pointing to the first definition as the previous declaration. // This lets us avoid emitting "knock-on" diagnostics. - Some(hir_id) + Some(existing_id) } else { - self.seen_decls.insert(name, fi.hir_id()) + self.seen_decls.insert(name, fi.owner_id) } } @@ -2926,16 +2949,16 @@ fn structurally_same_type_impl<'tcx>( impl_lint_pass!(ClashingExternDeclarations => [CLASHING_EXTERN_DECLARATIONS]); impl<'tcx> LateLintPass<'tcx> for ClashingExternDeclarations { + #[instrument(level = "trace", skip(self, cx))] fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, this_fi: &hir::ForeignItem<'_>) { - trace!("ClashingExternDeclarations: check_foreign_item: {:?}", this_fi); if let ForeignItemKind::Fn(..) = this_fi.kind { let tcx = cx.tcx; - if let Some(existing_hid) = self.insert(tcx, this_fi) { - let existing_decl_ty = tcx.type_of(tcx.hir().local_def_id(existing_hid)); + if let Some(existing_did) = self.insert(tcx, this_fi) { + let existing_decl_ty = tcx.type_of(existing_did); let this_decl_ty = tcx.type_of(this_fi.owner_id); debug!( "ClashingExternDeclarations: Comparing existing {:?}: {:?} to this {:?}: {:?}", - existing_hid, existing_decl_ty, this_fi.owner_id, this_decl_ty + existing_did, existing_decl_ty, this_fi.owner_id, this_decl_ty ); // Check that the declarations match. if !Self::structurally_same_type( @@ -2944,7 +2967,7 @@ fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, this_fi: &hir::ForeignI this_decl_ty, CItemKind::Declaration, ) { - let orig_fi = tcx.hir().expect_foreign_item(existing_hid.expect_owner()); + let orig_fi = tcx.hir().expect_foreign_item(existing_did); let orig = Self::name_of_extern_decl(tcx, orig_fi); // We want to ensure that we use spans for both decls that include where the