Merge branch 'master' into patch-2
This commit is contained in:
commit
0a528b16fc
2627 changed files with 58235 additions and 31211 deletions
|
@ -40,7 +40,7 @@ use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, Gate
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID};
|
||||
use rustc_hir::{ForeignItemKind, GenericParamKind, HirId, PatKind, PredicateOrigin};
|
||||
use rustc_hir::{ForeignItemKind, GenericParamKind, HirId, Node, PatKind, PredicateOrigin};
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::layout::{LayoutError, LayoutOf};
|
||||
|
@ -177,7 +177,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxPointers {
|
|||
| hir::ItemKind::Enum(..)
|
||||
| hir::ItemKind::Struct(..)
|
||||
| hir::ItemKind::Union(..) => {
|
||||
self.check_heap_type(cx, it.span, cx.tcx.type_of(it.def_id))
|
||||
self.check_heap_type(cx, it.span, cx.tcx.type_of(it.owner_id))
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
@ -563,7 +563,7 @@ impl MissingDoc {
|
|||
// It's an option so the crate root can also use this function (it doesn't
|
||||
// have a `NodeId`).
|
||||
if def_id != CRATE_DEF_ID {
|
||||
if !cx.access_levels.is_exported(def_id) {
|
||||
if !cx.effective_visibilities.is_exported(def_id) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -606,9 +606,9 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
|||
match it.kind {
|
||||
hir::ItemKind::Trait(..) => {
|
||||
// Issue #11592: traits are always considered exported, even when private.
|
||||
if cx.tcx.visibility(it.def_id)
|
||||
if cx.tcx.visibility(it.owner_id)
|
||||
== ty::Visibility::Restricted(
|
||||
cx.tcx.parent_module_from_def_id(it.def_id.def_id).to_def_id(),
|
||||
cx.tcx.parent_module_from_def_id(it.owner_id.def_id).to_def_id(),
|
||||
)
|
||||
{
|
||||
return;
|
||||
|
@ -627,15 +627,15 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
|||
_ => return,
|
||||
};
|
||||
|
||||
let (article, desc) = cx.tcx.article_and_description(it.def_id.to_def_id());
|
||||
let (article, desc) = cx.tcx.article_and_description(it.owner_id.to_def_id());
|
||||
|
||||
self.check_missing_docs_attrs(cx, it.def_id.def_id, article, desc);
|
||||
self.check_missing_docs_attrs(cx, it.owner_id.def_id, article, desc);
|
||||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &LateContext<'_>, trait_item: &hir::TraitItem<'_>) {
|
||||
let (article, desc) = cx.tcx.article_and_description(trait_item.def_id.to_def_id());
|
||||
let (article, desc) = cx.tcx.article_and_description(trait_item.owner_id.to_def_id());
|
||||
|
||||
self.check_missing_docs_attrs(cx, trait_item.def_id.def_id, article, desc);
|
||||
self.check_missing_docs_attrs(cx, trait_item.owner_id.def_id, article, desc);
|
||||
}
|
||||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
|
||||
|
@ -662,13 +662,13 @@ 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.def_id.def_id, article, desc);
|
||||
let (article, desc) = cx.tcx.article_and_description(impl_item.owner_id.to_def_id());
|
||||
self.check_missing_docs_attrs(cx, impl_item.owner_id.def_id, 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, foreign_item.def_id.def_id, article, desc);
|
||||
let (article, desc) = cx.tcx.article_and_description(foreign_item.owner_id.to_def_id());
|
||||
self.check_missing_docs_attrs(cx, foreign_item.owner_id.def_id, article, desc);
|
||||
}
|
||||
|
||||
fn check_field_def(&mut self, cx: &LateContext<'_>, sf: &hir::FieldDef<'_>) {
|
||||
|
@ -721,7 +721,7 @@ declare_lint_pass!(MissingCopyImplementations => [MISSING_COPY_IMPLEMENTATIONS])
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
|
||||
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
|
||||
if !cx.access_levels.is_reachable(item.def_id.def_id) {
|
||||
if !cx.effective_visibilities.is_reachable(item.owner_id.def_id) {
|
||||
return;
|
||||
}
|
||||
let (def, ty) = match item.kind {
|
||||
|
@ -729,21 +729,21 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
|
|||
if !ast_generics.params.is_empty() {
|
||||
return;
|
||||
}
|
||||
let def = cx.tcx.adt_def(item.def_id);
|
||||
let def = cx.tcx.adt_def(item.owner_id);
|
||||
(def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
|
||||
}
|
||||
hir::ItemKind::Union(_, ref ast_generics) => {
|
||||
if !ast_generics.params.is_empty() {
|
||||
return;
|
||||
}
|
||||
let def = cx.tcx.adt_def(item.def_id);
|
||||
let def = cx.tcx.adt_def(item.owner_id);
|
||||
(def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
|
||||
}
|
||||
hir::ItemKind::Enum(_, ref ast_generics) => {
|
||||
if !ast_generics.params.is_empty() {
|
||||
return;
|
||||
}
|
||||
let def = cx.tcx.adt_def(item.def_id);
|
||||
let def = cx.tcx.adt_def(item.owner_id);
|
||||
(def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
|
||||
}
|
||||
_ => return,
|
||||
|
@ -752,7 +752,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
|
|||
return;
|
||||
}
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
if ty.is_copy_modulo_regions(cx.tcx.at(item.span), param_env) {
|
||||
if ty.is_copy_modulo_regions(cx.tcx, param_env) {
|
||||
return;
|
||||
}
|
||||
if can_type_implement_copy(
|
||||
|
@ -814,7 +814,7 @@ impl_lint_pass!(MissingDebugImplementations => [MISSING_DEBUG_IMPLEMENTATIONS]);
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
|
||||
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
|
||||
if !cx.access_levels.is_reachable(item.def_id.def_id) {
|
||||
if !cx.effective_visibilities.is_reachable(item.owner_id.def_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -841,7 +841,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
|
|||
debug!("{:?}", self.impling_types);
|
||||
}
|
||||
|
||||
if !self.impling_types.as_ref().unwrap().contains(&item.def_id.def_id) {
|
||||
if !self.impling_types.as_ref().unwrap().contains(&item.owner_id.def_id) {
|
||||
cx.struct_span_lint(
|
||||
MISSING_DEBUG_IMPLEMENTATIONS,
|
||||
item.span,
|
||||
|
@ -1226,7 +1226,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
|
|||
check_no_mangle_on_generic_fn(
|
||||
no_mangle_attr,
|
||||
Some(generics),
|
||||
cx.tcx.hir().get_generics(it.id.def_id.def_id).unwrap(),
|
||||
cx.tcx.hir().get_generics(it.id.owner_id.def_id).unwrap(),
|
||||
it.span,
|
||||
);
|
||||
}
|
||||
|
@ -1385,7 +1385,8 @@ impl UnreachablePub {
|
|||
exportable: bool,
|
||||
) {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
if cx.tcx.visibility(def_id).is_public() && !cx.access_levels.is_reachable(def_id) {
|
||||
if cx.tcx.visibility(def_id).is_public() && !cx.effective_visibilities.is_reachable(def_id)
|
||||
{
|
||||
if vis_span.from_expansion() {
|
||||
applicability = Applicability::MaybeIncorrect;
|
||||
}
|
||||
|
@ -1414,22 +1415,26 @@ impl<'tcx> LateLintPass<'tcx> for UnreachablePub {
|
|||
if let hir::ItemKind::Use(_, hir::UseKind::ListStem) = &item.kind {
|
||||
return;
|
||||
}
|
||||
self.perform_lint(cx, "item", item.def_id.def_id, item.vis_span, true);
|
||||
self.perform_lint(cx, "item", item.owner_id.def_id, item.vis_span, true);
|
||||
}
|
||||
|
||||
fn check_foreign_item(&mut self, cx: &LateContext<'_>, foreign_item: &hir::ForeignItem<'tcx>) {
|
||||
self.perform_lint(cx, "item", foreign_item.def_id.def_id, foreign_item.vis_span, true);
|
||||
self.perform_lint(cx, "item", foreign_item.owner_id.def_id, foreign_item.vis_span, true);
|
||||
}
|
||||
|
||||
fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) {
|
||||
let def_id = cx.tcx.hir().local_def_id(field.hir_id);
|
||||
let map = cx.tcx.hir();
|
||||
let def_id = map.local_def_id(field.hir_id);
|
||||
if matches!(map.get(map.get_parent_node(field.hir_id)), Node::Variant(_)) {
|
||||
return;
|
||||
}
|
||||
self.perform_lint(cx, "field", def_id, field.vis_span, false);
|
||||
}
|
||||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
|
||||
// Only lint inherent impl items.
|
||||
if cx.tcx.associated_item(impl_item.def_id).trait_item_def_id.is_none() {
|
||||
self.perform_lint(cx, "item", impl_item.def_id.def_id, impl_item.vis_span, false);
|
||||
if cx.tcx.associated_item(impl_item.owner_id).trait_item_def_id.is_none() {
|
||||
self.perform_lint(cx, "item", impl_item.owner_id.def_id, impl_item.vis_span, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1638,7 +1643,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
|
|||
use rustc_middle::ty::PredicateKind::*;
|
||||
|
||||
if cx.tcx.features().trivial_bounds {
|
||||
let predicates = cx.tcx.predicates_of(item.def_id);
|
||||
let predicates = cx.tcx.predicates_of(item.owner_id);
|
||||
for &(predicate, span) in predicates.predicates {
|
||||
let predicate_kind_name = match predicate.kind().skip_binder() {
|
||||
Trait(..) => "trait",
|
||||
|
@ -1881,7 +1886,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnameableTestItems {
|
|||
if let hir::ItemKind::Mod(..) = it.kind {
|
||||
} else {
|
||||
self.items_nameable = false;
|
||||
self.boundary = Some(it.def_id);
|
||||
self.boundary = Some(it.owner_id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1898,7 +1903,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnameableTestItems {
|
|||
}
|
||||
|
||||
fn check_item_post(&mut self, _cx: &LateContext<'_>, it: &hir::Item<'_>) {
|
||||
if !self.items_nameable && self.boundary == Some(it.def_id) {
|
||||
if !self.items_nameable && self.boundary == Some(it.owner_id) {
|
||||
self.items_nameable = true;
|
||||
}
|
||||
}
|
||||
|
@ -2164,7 +2169,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
|
|||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
|
||||
use rustc_middle::middle::resolve_lifetime::Region;
|
||||
|
||||
let def_id = item.def_id.def_id;
|
||||
let def_id = item.owner_id.def_id;
|
||||
if let hir::ItemKind::Struct(_, ref hir_generics)
|
||||
| hir::ItemKind::Enum(_, ref hir_generics)
|
||||
| hir::ItemKind::Union(_, ref hir_generics) = item.kind
|
||||
|
@ -2743,7 +2748,7 @@ impl ClashingExternDeclarations {
|
|||
/// 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<HirId> {
|
||||
let did = fi.def_id.to_def_id();
|
||||
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) {
|
||||
|
@ -2761,14 +2766,14 @@ impl ClashingExternDeclarations {
|
|||
/// symbol's name.
|
||||
fn name_of_extern_decl(tcx: TyCtxt<'_>, fi: &hir::ForeignItem<'_>) -> SymbolName {
|
||||
if let Some((overridden_link_name, overridden_link_name_span)) =
|
||||
tcx.codegen_fn_attrs(fi.def_id).link_name.map(|overridden_link_name| {
|
||||
tcx.codegen_fn_attrs(fi.owner_id).link_name.map(|overridden_link_name| {
|
||||
// FIXME: Instead of searching through the attributes again to get span
|
||||
// information, we could have codegen_fn_attrs also give span information back for
|
||||
// where the attribute was defined. However, until this is found to be a
|
||||
// bottleneck, this does just fine.
|
||||
(
|
||||
overridden_link_name,
|
||||
tcx.get_attr(fi.def_id.to_def_id(), sym::link_name).unwrap().span,
|
||||
tcx.get_attr(fi.owner_id.to_def_id(), sym::link_name).unwrap().span,
|
||||
)
|
||||
})
|
||||
{
|
||||
|
@ -2985,10 +2990,10 @@ impl<'tcx> LateLintPass<'tcx> for ClashingExternDeclarations {
|
|||
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));
|
||||
let this_decl_ty = tcx.type_of(this_fi.def_id);
|
||||
let this_decl_ty = tcx.type_of(this_fi.owner_id);
|
||||
debug!(
|
||||
"ClashingExternDeclarations: Comparing existing {:?}: {:?} to this {:?}: {:?}",
|
||||
existing_hid, existing_decl_ty, this_fi.def_id, this_decl_ty
|
||||
existing_hid, existing_decl_ty, this_fi.owner_id, this_decl_ty
|
||||
);
|
||||
// Check that the declarations match.
|
||||
if !Self::structurally_same_type(
|
||||
|
|
|
@ -31,7 +31,7 @@ use rustc_hir as hir;
|
|||
use rustc_hir::def::Res;
|
||||
use rustc_hir::def_id::{CrateNum, DefId};
|
||||
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
|
||||
use rustc_middle::middle::privacy::AccessLevels;
|
||||
use rustc_middle::middle::privacy::EffectiveVisibilities;
|
||||
use rustc_middle::middle::stability;
|
||||
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
|
@ -542,7 +542,7 @@ pub struct LateContext<'tcx> {
|
|||
pub param_env: ty::ParamEnv<'tcx>,
|
||||
|
||||
/// Items accessible from the crate being checked.
|
||||
pub access_levels: &'tcx AccessLevels,
|
||||
pub effective_visibilities: &'tcx EffectiveVisibilities,
|
||||
|
||||
/// The store of registered lints and the lint levels.
|
||||
pub lint_store: &'tcx LintStore,
|
||||
|
@ -579,6 +579,7 @@ pub trait LintContext: Sized {
|
|||
/// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
|
||||
///
|
||||
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
|
||||
#[rustc_lint_diagnostics]
|
||||
fn lookup_with_diagnostics(
|
||||
&self,
|
||||
lint: &'static Lint,
|
||||
|
@ -882,6 +883,7 @@ pub trait LintContext: Sized {
|
|||
/// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
|
||||
///
|
||||
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
|
||||
#[rustc_lint_diagnostics]
|
||||
fn lookup<S: Into<MultiSpan>>(
|
||||
&self,
|
||||
lint: &'static Lint,
|
||||
|
@ -908,6 +910,7 @@ pub trait LintContext: Sized {
|
|||
/// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
|
||||
///
|
||||
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
|
||||
#[rustc_lint_diagnostics]
|
||||
fn struct_span_lint<S: Into<MultiSpan>>(
|
||||
&self,
|
||||
lint: &'static Lint,
|
||||
|
@ -933,6 +936,7 @@ pub trait LintContext: Sized {
|
|||
/// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
|
||||
///
|
||||
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
|
||||
#[rustc_lint_diagnostics]
|
||||
fn lint(
|
||||
&self,
|
||||
lint: &'static Lint,
|
||||
|
|
|
@ -83,7 +83,7 @@ pub struct UnknownToolInScopedLint {
|
|||
pub struct BuiltinEllpisisInclusiveRangePatterns {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion_short(code = "{replace}", applicability = "machine-applicable")]
|
||||
#[suggestion(style = "short", code = "{replace}", applicability = "machine-applicable")]
|
||||
pub suggestion: Span,
|
||||
pub replace: String,
|
||||
}
|
||||
|
|
|
@ -3,11 +3,9 @@ use crate::{LateContext, LateLintPass, LintContext};
|
|||
use hir::{Expr, Pat};
|
||||
use rustc_errors::{Applicability, DelayDm};
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::traits::TraitEngine;
|
||||
use rustc_infer::{infer::TyCtxtInferExt, traits::ObligationCause};
|
||||
use rustc_middle::ty::{self, List};
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_trait_selection::traits::TraitEngineExt;
|
||||
|
||||
declare_lint! {
|
||||
/// The `for_loops_over_fallibles` lint checks for `for` loops over `Option` or `Result` values.
|
||||
|
@ -160,24 +158,19 @@ fn suggest_question_mark<'tcx>(
|
|||
|
||||
let ty = substs.type_at(0);
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
|
||||
|
||||
let cause = ObligationCause::new(
|
||||
span,
|
||||
body_id.hir_id,
|
||||
rustc_infer::traits::ObligationCauseCode::MiscObligation,
|
||||
);
|
||||
fulfill_cx.register_bound(
|
||||
let errors = rustc_trait_selection::traits::fully_solve_bound(
|
||||
&infcx,
|
||||
cause,
|
||||
ty::ParamEnv::empty(),
|
||||
// Erase any region vids from the type, which may not be resolved
|
||||
infcx.tcx.erase_regions(ty),
|
||||
into_iterator_did,
|
||||
cause,
|
||||
);
|
||||
|
||||
// Select all, including ambiguous predicates
|
||||
let errors = fulfill_cx.select_all_or_error(&infcx);
|
||||
|
||||
errors.is_empty()
|
||||
}
|
||||
|
|
|
@ -338,14 +338,14 @@ fn late_lint_mod_pass<'tcx, T: LateLintPass<'tcx>>(
|
|||
module_def_id: LocalDefId,
|
||||
pass: T,
|
||||
) {
|
||||
let access_levels = &tcx.privacy_access_levels(());
|
||||
let effective_visibilities = &tcx.effective_visibilities(());
|
||||
|
||||
let context = LateContext {
|
||||
tcx,
|
||||
enclosing_body: None,
|
||||
cached_typeck_results: Cell::new(None),
|
||||
param_env: ty::ParamEnv::empty(),
|
||||
access_levels,
|
||||
effective_visibilities,
|
||||
lint_store: unerased_lint_store(tcx),
|
||||
last_node_with_lint_attrs: tcx.hir().local_def_id_to_hir_id(module_def_id),
|
||||
generics: None,
|
||||
|
@ -386,14 +386,14 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx>>(
|
|||
}
|
||||
|
||||
fn late_lint_pass_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, pass: T) {
|
||||
let access_levels = &tcx.privacy_access_levels(());
|
||||
let effective_visibilities = &tcx.effective_visibilities(());
|
||||
|
||||
let context = LateContext {
|
||||
tcx,
|
||||
enclosing_body: None,
|
||||
cached_typeck_results: Cell::new(None),
|
||||
param_env: ty::ParamEnv::empty(),
|
||||
access_levels,
|
||||
effective_visibilities,
|
||||
lint_store: unerased_lint_store(tcx),
|
||||
last_node_with_lint_attrs: hir::CRATE_HIR_ID,
|
||||
generics: None,
|
||||
|
|
|
@ -11,6 +11,7 @@ declare_lint! {
|
|||
/// scope.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust
|
||||
/// struct SomeStruct;
|
||||
/// impl Drop for SomeStruct {
|
||||
|
|
|
@ -163,7 +163,7 @@ fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLe
|
|||
// Otherwise, we need to visit the attributes in source code order, so we fetch HIR and do
|
||||
// a standard visit.
|
||||
// FIXME(#102522) Just iterate on attrs once that iteration order matches HIR's.
|
||||
_ => match tcx.hir().expect_owner(owner) {
|
||||
_ => match tcx.hir().owner(owner) {
|
||||
hir::OwnerNode::Item(item) => levels.visit_item(item),
|
||||
hir::OwnerNode::ForeignItem(item) => levels.visit_foreign_item(item),
|
||||
hir::OwnerNode::TraitItem(item) => levels.visit_trait_item(item),
|
||||
|
@ -1073,6 +1073,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
|
|||
/// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
|
||||
///
|
||||
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
|
||||
#[rustc_lint_diagnostics]
|
||||
pub(crate) fn struct_lint(
|
||||
&self,
|
||||
lint: &'static Lint,
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#![feature(let_chains)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(never_type)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -212,7 +213,7 @@ macro_rules! late_lint_mod_passes {
|
|||
TypeLimits: TypeLimits::new(),
|
||||
NonSnakeCase: NonSnakeCase,
|
||||
InvalidNoMangleItems: InvalidNoMangleItems,
|
||||
// Depends on access levels
|
||||
// Depends on effective visibilities
|
||||
UnreachablePub: UnreachablePub,
|
||||
ExplicitOutlivesRequirements: ExplicitOutlivesRequirements,
|
||||
InvalidValue: InvalidValue,
|
||||
|
|
|
@ -65,7 +65,7 @@ declare_lint_pass!(OpaqueHiddenInferredBound => [OPAQUE_HIDDEN_INFERRED_BOUND]);
|
|||
impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||
let hir::ItemKind::OpaqueTy(_) = &item.kind else { return; };
|
||||
let def_id = item.def_id.def_id.to_def_id();
|
||||
let def_id = item.owner_id.def_id.to_def_id();
|
||||
let infcx = &cx.tcx.infer_ctxt().build();
|
||||
// For every projection predicate in the opaque type's explicit bounds,
|
||||
// check that the type that we're assigning actually satisfies the bounds
|
||||
|
@ -154,8 +154,9 @@ struct OpaqueHiddenInferredBoundLint<'tcx> {
|
|||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion_verbose(
|
||||
#[suggestion(
|
||||
lint_opaque_hidden_inferred_bound_sugg,
|
||||
style = "verbose",
|
||||
applicability = "machine-applicable",
|
||||
code = " + {trait_ref}"
|
||||
)]
|
||||
|
|
|
@ -89,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
|
|||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||
use rustc_middle::ty::PredicateKind::*;
|
||||
|
||||
let predicates = cx.tcx.explicit_predicates_of(item.def_id);
|
||||
let predicates = cx.tcx.explicit_predicates_of(item.owner_id);
|
||||
for &(predicate, span) in predicates.predicates {
|
||||
let Trait(trait_predicate) = predicate.kind().skip_binder() else {
|
||||
continue
|
||||
|
|
|
@ -11,7 +11,7 @@ use rustc_middle::ty::subst::SubstsRef;
|
|||
use rustc_middle::ty::{self, AdtKind, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
|
||||
use rustc_span::source_map;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{Span, Symbol, DUMMY_SP};
|
||||
use rustc_span::{Span, Symbol};
|
||||
use rustc_target::abi::{Abi, WrappingRange};
|
||||
use rustc_target::abi::{Integer, TagEncoding, Variants};
|
||||
use rustc_target::spec::abi::Abi as SpecAbi;
|
||||
|
@ -360,7 +360,7 @@ fn lint_int_literal<'tcx>(
|
|||
}
|
||||
|
||||
if lint_overflowing_range_endpoint(cx, lit, v, max, e, t.name_str()) {
|
||||
// The overflowing literal lint was emited by `lint_overflowing_range_endpoint`.
|
||||
// The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -429,7 +429,7 @@ fn lint_uint_literal<'tcx>(
|
|||
}
|
||||
}
|
||||
if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, t.name_str()) {
|
||||
// The overflowing literal lint was emited by `lint_overflowing_range_endpoint`.
|
||||
// The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
|
||||
return;
|
||||
}
|
||||
if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
|
||||
|
@ -931,7 +931,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
match *ty.kind() {
|
||||
ty::Adt(def, substs) => {
|
||||
if def.is_box() && matches!(self.mode, CItemKind::Definition) {
|
||||
if ty.boxed_ty().is_sized(tcx.at(DUMMY_SP), self.cx.param_env) {
|
||||
if ty.boxed_ty().is_sized(tcx, self.cx.param_env) {
|
||||
return FfiSafe;
|
||||
} else {
|
||||
return FfiUnsafe {
|
||||
|
@ -1082,7 +1082,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _)
|
||||
if {
|
||||
matches!(self.mode, CItemKind::Definition)
|
||||
&& ty.is_sized(self.cx.tcx.at(DUMMY_SP), self.cx.param_env)
|
||||
&& ty.is_sized(self.cx.tcx, self.cx.param_env)
|
||||
} =>
|
||||
{
|
||||
FfiSafe
|
||||
|
@ -1195,35 +1195,30 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
|
||||
struct ProhibitOpaqueTypes<'a, 'tcx> {
|
||||
cx: &'a LateContext<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ty::visit::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'a, 'tcx> {
|
||||
struct ProhibitOpaqueTypes;
|
||||
impl<'tcx> ty::visit::TypeVisitor<'tcx> for ProhibitOpaqueTypes {
|
||||
type BreakTy = Ty<'tcx>;
|
||||
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
match ty.kind() {
|
||||
ty::Opaque(..) => ControlFlow::Break(ty),
|
||||
// Consider opaque types within projections FFI-safe if they do not normalize
|
||||
// to more opaque types.
|
||||
ty::Projection(..) => {
|
||||
let ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, ty);
|
||||
if !ty.has_opaque_types() {
|
||||
return ControlFlow::CONTINUE;
|
||||
}
|
||||
|
||||
// If `ty` is an opaque type directly then `super_visit_with` won't invoke
|
||||
// this function again.
|
||||
if ty.has_opaque_types() {
|
||||
self.visit_ty(ty)
|
||||
} else {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
_ => ty.super_visit_with(self),
|
||||
if let ty::Opaque(..) = ty.kind() {
|
||||
ControlFlow::Break(ty)
|
||||
} else {
|
||||
ty.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ty) = ty.visit_with(&mut ProhibitOpaqueTypes { cx: self.cx }).break_value() {
|
||||
if let Some(ty) = self
|
||||
.cx
|
||||
.tcx
|
||||
.normalize_erasing_regions(self.cx.param_env, ty)
|
||||
.visit_with(&mut ProhibitOpaqueTypes)
|
||||
.break_value()
|
||||
{
|
||||
self.emit_ffi_unsafe_type_lint(ty, sp, fluent::lint_improper_ctypes_opaque, None);
|
||||
true
|
||||
} else {
|
||||
|
@ -1360,7 +1355,7 @@ declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]);
|
|||
impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences {
|
||||
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
|
||||
if let hir::ItemKind::Enum(ref enum_definition, _) = it.kind {
|
||||
let t = cx.tcx.type_of(it.def_id);
|
||||
let t = cx.tcx.type_of(it.owner_id);
|
||||
let ty = cx.tcx.erase_regions(t);
|
||||
let Ok(layout) = cx.layout_of(ty) else { return };
|
||||
let Variants::Multiple {
|
||||
|
|
|
@ -9,7 +9,7 @@ use rustc_hir::def::{DefKind, Res};
|
|||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::traits::util::elaborate_predicates_with_span;
|
||||
use rustc_middle::ty::adjustment;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_middle::ty::{self, DefIdTree, Ty};
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::symbol::{kw, sym};
|
||||
use rustc_span::{BytePos, Span};
|
||||
|
@ -87,17 +87,33 @@ declare_lint_pass!(UnusedResults => [UNUSED_MUST_USE, UNUSED_RESULTS]);
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) {
|
||||
let expr = match s.kind {
|
||||
hir::StmtKind::Semi(ref expr) => &**expr,
|
||||
_ => return,
|
||||
};
|
||||
let hir::StmtKind::Semi(expr) = s.kind else { return; };
|
||||
|
||||
if let hir::ExprKind::Ret(..) = expr.kind {
|
||||
return;
|
||||
}
|
||||
|
||||
if let hir::ExprKind::Match(await_expr, _arms, hir::MatchSource::AwaitDesugar) = expr.kind
|
||||
&& let ty = cx.typeck_results().expr_ty(&await_expr)
|
||||
&& let ty::Opaque(future_def_id, _) = ty.kind()
|
||||
&& cx.tcx.ty_is_opaque_future(ty)
|
||||
// FIXME: This also includes non-async fns that return `impl Future`.
|
||||
&& let async_fn_def_id = cx.tcx.parent(*future_def_id)
|
||||
&& check_must_use_def(
|
||||
cx,
|
||||
async_fn_def_id,
|
||||
expr.span,
|
||||
"output of future returned by ",
|
||||
"",
|
||||
)
|
||||
{
|
||||
// We have a bare `foo().await;` on an opaque type from an async function that was
|
||||
// annotated with `#[must_use]`.
|
||||
return;
|
||||
}
|
||||
|
||||
let ty = cx.typeck_results().expr_ty(&expr);
|
||||
let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "", 1);
|
||||
let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, expr.span, "", "", 1);
|
||||
|
||||
let mut fn_warned = false;
|
||||
let mut op_warned = false;
|
||||
|
@ -119,7 +135,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
_ => None,
|
||||
};
|
||||
if let Some(def_id) = maybe_def_id {
|
||||
fn_warned = check_must_use_def(cx, def_id, s.span, "return value of ", "");
|
||||
fn_warned = check_must_use_def(cx, def_id, expr.span, "return value of ", "");
|
||||
} else if type_permits_lack_of_use {
|
||||
// We don't warn about unused unit or uninhabited types.
|
||||
// (See https://github.com/rust-lang/rust/issues/43806 for details.)
|
||||
|
@ -565,10 +581,24 @@ trait UnusedDelimLint {
|
|||
lint.set_arg("delim", Self::DELIM_STR);
|
||||
lint.set_arg("item", msg);
|
||||
if let Some((lo, hi)) = spans {
|
||||
let replacement = vec![
|
||||
(lo, if keep_space.0 { " ".into() } else { "".into() }),
|
||||
(hi, if keep_space.1 { " ".into() } else { "".into() }),
|
||||
];
|
||||
let sm = cx.sess().source_map();
|
||||
let lo_replace =
|
||||
if keep_space.0 &&
|
||||
let Ok(snip) = sm.span_to_prev_source(lo) && !snip.ends_with(" ") {
|
||||
" ".to_string()
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
|
||||
let hi_replace =
|
||||
if keep_space.1 &&
|
||||
let Ok(snip) = sm.span_to_next_source(hi) && !snip.starts_with(" ") {
|
||||
" ".to_string()
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
|
||||
let replacement = vec![(lo, lo_replace), (hi, hi_replace)];
|
||||
lint.multipart_suggestion(
|
||||
fluent::suggestion,
|
||||
replacement,
|
||||
|
@ -765,6 +795,7 @@ impl UnusedParens {
|
|||
value: &ast::Pat,
|
||||
avoid_or: bool,
|
||||
avoid_mut: bool,
|
||||
keep_space: (bool, bool),
|
||||
) {
|
||||
use ast::{BindingAnnotation, PatKind};
|
||||
|
||||
|
@ -789,7 +820,7 @@ impl UnusedParens {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
self.emit_unused_delims(cx, value.span, spans, "pattern", (false, false));
|
||||
self.emit_unused_delims(cx, value.span, spans, "pattern", keep_space);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -798,7 +829,7 @@ impl EarlyLintPass for UnusedParens {
|
|||
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
|
||||
match e.kind {
|
||||
ExprKind::Let(ref pat, _, _) | ExprKind::ForLoop(ref pat, ..) => {
|
||||
self.check_unused_parens_pat(cx, pat, false, false);
|
||||
self.check_unused_parens_pat(cx, pat, false, false, (true, true));
|
||||
}
|
||||
// We ignore parens in cases like `if (((let Some(0) = Some(1))))` because we already
|
||||
// handle a hard error for them during AST lowering in `lower_expr_mut`, but we still
|
||||
|
@ -842,6 +873,7 @@ impl EarlyLintPass for UnusedParens {
|
|||
|
||||
fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
|
||||
use ast::{Mutability, PatKind::*};
|
||||
let keep_space = (false, false);
|
||||
match &p.kind {
|
||||
// Do not lint on `(..)` as that will result in the other arms being useless.
|
||||
Paren(_)
|
||||
|
@ -849,33 +881,33 @@ impl EarlyLintPass for UnusedParens {
|
|||
| Wild | Rest | Lit(..) | MacCall(..) | Range(..) | Ident(.., None) | Path(..) => {},
|
||||
// These are list-like patterns; parens can always be removed.
|
||||
TupleStruct(_, _, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
|
||||
self.check_unused_parens_pat(cx, p, false, false);
|
||||
self.check_unused_parens_pat(cx, p, false, false, keep_space);
|
||||
},
|
||||
Struct(_, _, fps, _) => for f in fps {
|
||||
self.check_unused_parens_pat(cx, &f.pat, false, false);
|
||||
self.check_unused_parens_pat(cx, &f.pat, false, false, keep_space);
|
||||
},
|
||||
// Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106.
|
||||
Ident(.., Some(p)) | Box(p) => self.check_unused_parens_pat(cx, p, true, false),
|
||||
Ident(.., Some(p)) | Box(p) => self.check_unused_parens_pat(cx, p, true, false, keep_space),
|
||||
// Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342.
|
||||
// Also avoid linting on `& mut? (p0 | .. | pn)`, #64106.
|
||||
Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Not),
|
||||
Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Not, keep_space),
|
||||
}
|
||||
}
|
||||
|
||||
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
|
||||
if let StmtKind::Local(ref local) = s.kind {
|
||||
self.check_unused_parens_pat(cx, &local.pat, true, false);
|
||||
self.check_unused_parens_pat(cx, &local.pat, true, false, (false, false));
|
||||
}
|
||||
|
||||
<Self as UnusedDelimLint>::check_stmt(self, cx, s)
|
||||
}
|
||||
|
||||
fn check_param(&mut self, cx: &EarlyContext<'_>, param: &ast::Param) {
|
||||
self.check_unused_parens_pat(cx, ¶m.pat, true, false);
|
||||
self.check_unused_parens_pat(cx, ¶m.pat, true, false, (false, false));
|
||||
}
|
||||
|
||||
fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) {
|
||||
self.check_unused_parens_pat(cx, &arm.pat, false, false);
|
||||
self.check_unused_parens_pat(cx, &arm.pat, false, false, (false, false));
|
||||
}
|
||||
|
||||
fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue