Skip to content

Commit dd1ff40

Browse files
committed
Track if a where bound comes from a impl Trait desugar
With #93803 `impl Trait` function arguments get desugared to hidden where bounds. However, Clippy needs to know if a bound was originally a impl Trait or an actual bound. This adds a field to the `WhereBoundPredicate` struct to keep track of this information during HIR lowering.
1 parent f47d2b3 commit dd1ff40

File tree

7 files changed

+34
-12
lines changed

7 files changed

+34
-12
lines changed

compiler/rustc_ast_lowering/src/item.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_errors::struct_span_err;
1111
use rustc_hir as hir;
1212
use rustc_hir::def::{DefKind, Res};
1313
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
14+
use rustc_hir::PredicateOrigin;
1415
use rustc_index::vec::{Idx, IndexVec};
1516
use rustc_session::utils::NtToTokenstream;
1617
use rustc_session::Session;
@@ -1346,7 +1347,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
13461347
let mut predicates = SmallVec::new();
13471348
predicates.extend(generics.params.iter().filter_map(|param| {
13481349
let bounds = self.lower_param_bounds(&param.bounds, itctx.reborrow());
1349-
self.lower_generic_bound_predicate(param.ident, param.id, &param.kind, bounds)
1350+
self.lower_generic_bound_predicate(
1351+
param.ident,
1352+
param.id,
1353+
&param.kind,
1354+
bounds,
1355+
PredicateOrigin::GenericParam,
1356+
)
13501357
}));
13511358
predicates.extend(
13521359
generics
@@ -1380,6 +1387,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
13801387
id: NodeId,
13811388
kind: &GenericParamKind,
13821389
bounds: &'hir [hir::GenericBound<'hir>],
1390+
origin: PredicateOrigin,
13831391
) -> Option<hir::WherePredicate<'hir>> {
13841392
// Do not create a clause if we do not have anything inside it.
13851393
if bounds.is_empty() {
@@ -1419,7 +1427,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14191427
bounds,
14201428
span,
14211429
bound_generic_params: &[],
1422-
in_where_clause: false,
1430+
origin,
14231431
}))
14241432
}
14251433
GenericParamKind::Lifetime => {
@@ -1458,7 +1466,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14581466
)
14591467
})),
14601468
span: self.lower_span(span),
1461-
in_where_clause: true,
1469+
origin: PredicateOrigin::WhereClause,
14621470
}),
14631471
WherePredicate::RegionPredicate(WhereRegionPredicate {
14641472
ref lifetime,

compiler/rustc_ast_lowering/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12981298
def_node_id,
12991299
&GenericParamKind::Type { default: None },
13001300
hir_bounds,
1301+
hir::PredicateOrigin::ImplTrait,
13011302
) {
13021303
in_band_ty_bounds.push(preds)
13031304
}

compiler/rustc_hir/src/hir.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ impl<'hir> WherePredicate<'hir> {
706706

707707
pub fn in_where_clause(&self) -> bool {
708708
match self {
709-
WherePredicate::BoundPredicate(p) => p.in_where_clause,
709+
WherePredicate::BoundPredicate(p) => p.origin == PredicateOrigin::WhereClause,
710710
WherePredicate::RegionPredicate(p) => p.in_where_clause,
711711
WherePredicate::EqPredicate(_) => false,
712712
}
@@ -721,11 +721,19 @@ impl<'hir> WherePredicate<'hir> {
721721
}
722722
}
723723

724+
#[derive(Debug, HashStable_Generic, PartialEq, Eq)]
725+
pub enum PredicateOrigin {
726+
WhereClause,
727+
GenericParam,
728+
ImplTrait,
729+
}
730+
724731
/// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
725732
#[derive(Debug, HashStable_Generic)]
726733
pub struct WhereBoundPredicate<'hir> {
727734
pub span: Span,
728-
pub in_where_clause: bool,
735+
/// Origin of the predicate.
736+
pub origin: PredicateOrigin,
729737
/// Any generics from a `for` binding.
730738
pub bound_generic_params: &'hir [GenericParam<'hir>],
731739
/// The type being bounded.

compiler/rustc_lint/src/builtin.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, Gate
3636
use rustc_hir as hir;
3737
use rustc_hir::def::{DefKind, Res};
3838
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID};
39-
use rustc_hir::{ForeignItemKind, GenericParamKind, HirId, PatKind};
39+
use rustc_hir::{ForeignItemKind, GenericParamKind, HirId, PatKind, PredicateOrigin};
4040
use rustc_index::vec::Idx;
4141
use rustc_middle::lint::LintDiagnosticBuilder;
4242
use rustc_middle::ty::layout::{LayoutError, LayoutOf};
@@ -2226,7 +2226,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
22262226
Self::lifetimes_outliving_type(inferred_outlives, index),
22272227
&predicate.bounds,
22282228
predicate.span,
2229-
predicate.in_where_clause,
2229+
predicate.origin == PredicateOrigin::WhereClause,
22302230
)
22312231
}
22322232
_ => {

src/librustdoc/clean/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1616
use rustc_hir as hir;
1717
use rustc_hir::def::{CtorKind, DefKind, Res};
1818
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
19+
use rustc_hir::PredicateOrigin;
1920
use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
2021
use rustc_middle::middle::resolve_lifetime as rl;
2122
use rustc_middle::ty::fold::TypeFolder;
@@ -493,7 +494,7 @@ fn clean_generic_param(
493494
let bounds = if let Some(generics) = generics {
494495
generics
495496
.bounds_for_param(did)
496-
.filter(|bp| !bp.in_where_clause)
497+
.filter(|bp| bp.origin != PredicateOrigin::WhereClause)
497498
.flat_map(|bp| bp.bounds)
498499
.filter_map(|x| x.clean(cx))
499500
.collect()

src/tools/clippy/clippy_lints/src/lifetimes.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use rustc_hir::intravisit::{
99
use rustc_hir::FnRetTy::Return;
1010
use rustc_hir::{
1111
BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem,
12-
ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, ParamName, PolyTraitRef, TraitBoundModifier,
13-
TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
12+
ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, ParamName, PolyTraitRef, PredicateOrigin,
13+
TraitBoundModifier, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
1414
};
1515
use rustc_lint::{LateContext, LateLintPass};
1616
use rustc_middle::hir::nested_filter as middle_nested_filter;
@@ -145,7 +145,7 @@ fn check_fn_inner<'tcx>(
145145
.filter(|param| matches!(param.kind, GenericParamKind::Type { .. }));
146146
for typ in types {
147147
for pred in generics.bounds_for_param(cx.tcx.hir().local_def_id(typ.hir_id)) {
148-
if pred.in_where_clause {
148+
if pred.origin == PredicateOrigin::WhereClause {
149149
// has_where_lifetimes checked that this predicate contains no lifetime.
150150
continue;
151151
}

src/tools/clippy/clippy_lints/src/trait_bounds.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ use rustc_data_structures::unhash::UnhashMap;
88
use rustc_errors::Applicability;
99
use rustc_hir::def::Res;
1010
use rustc_hir::{
11-
GenericBound, Generics, Item, ItemKind, Node, Path, PathSegment, QPath, TraitItem, Ty, TyKind, WherePredicate,
11+
GenericBound, Generics, Item, ItemKind, Node, Path, PathSegment, PredicateOrigin, QPath, TraitItem, Ty, TyKind,
12+
WherePredicate,
1213
};
1314
use rustc_lint::{LateContext, LateLintPass};
1415
use rustc_session::{declare_tool_lint, impl_lint_pass};
@@ -95,6 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
9596
for predicate in item.generics.predicates {
9697
if_chain! {
9798
if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate;
99+
if bound_predicate.origin != PredicateOrigin::ImplTrait;
98100
if !bound_predicate.span.from_expansion();
99101
if let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind;
100102
if let Some(PathSegment {
@@ -168,6 +170,7 @@ impl TraitBounds {
168170
for bound in gen.predicates {
169171
if_chain! {
170172
if let WherePredicate::BoundPredicate(ref p) = bound;
173+
if p.origin != PredicateOrigin::ImplTrait;
171174
if p.bounds.len() as u64 <= self.max_trait_bounds;
172175
if !p.span.from_expansion();
173176
if let Some(ref v) = map.insert(
@@ -223,6 +226,7 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
223226
for predicate in gen.predicates {
224227
if_chain! {
225228
if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate;
229+
if bound_predicate.origin != PredicateOrigin::ImplTrait;
226230
if !bound_predicate.span.from_expansion();
227231
if let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind;
228232
if let Some(segment) = segments.first();

0 commit comments

Comments
 (0)