Skip to content

Commit 71cef76

Browse files
authoredJan 20, 2024
Rollup merge of #120000 - smoelius:fix-clippy, r=fee1-dead
Ensure `callee_id`s are body owners This PR makes the `callee_id` argument of Clippy's `implements_trait_with_env` optional, and when it is passed, ensures it is a body owner. #118661 added the `callee_id` parameter to alleviate an ICE. Specifically, the `callee_id` is used to determine an "effect arg" in certain situations. Frankly, I [do not completely understand](#118661 (comment)) what an "effect arg" is. But the code that determines it seems to require that `callee_id` is a body owner: - https://github.com/rust-lang/rust/blob/1ead4761e9e2f056385768614c23ffa7acb6a19e/src/tools/clippy/clippy_utils/src/ty.rs#L286-L288 - https://github.com/rust-lang/rust/blob/1ead4761e9e2f056385768614c23ffa7acb6a19e/compiler/rustc_middle/src/ty/util.rs#L834 - https://github.com/rust-lang/rust/blob/1ead4761e9e2f056385768614c23ffa7acb6a19e/compiler/rustc_middle/src/hir/map/mod.rs#L372 In the current head, some def ids passed as `callee_id`s are not body owners. This PR fixes that. cc ``@rust-lang/clippy`` r? ``@fee1-dead``
2 parents 1236fa2 + 96b8eb7 commit 71cef76

File tree

3 files changed

+15
-23
lines changed

3 files changed

+15
-23
lines changed
 

‎src/tools/clippy/clippy_lints/src/derive.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -451,12 +451,12 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
451451
&& let Some(def_id) = trait_ref.trait_def_id()
452452
&& cx.tcx.is_diagnostic_item(sym::PartialEq, def_id)
453453
&& let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
454-
&& !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, adt.did(),&[])
454+
&& !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[])
455455
// If all of our fields implement `Eq`, we can implement `Eq` too
456456
&& adt
457457
.all_fields()
458458
.map(|f| f.ty(cx.tcx, args))
459-
.all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, adt.did(), &[]))
459+
.all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[]))
460460
{
461461
span_lint_and_sugg(
462462
cx,

‎src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ fn is_ref_iterable<'tcx>(
118118
.liberate_late_bound_regions(fn_id, cx.tcx.fn_sig(fn_id).skip_binder())
119119
&& let &[req_self_ty, req_res_ty] = &**sig.inputs_and_output
120120
&& let param_env = cx.tcx.param_env(fn_id)
121-
&& implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, fn_id, &[])
121+
&& implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, Some(fn_id), &[])
122122
&& let Some(into_iter_ty) =
123123
make_normalized_projection_with_regions(cx.tcx, param_env, trait_id, sym!(IntoIter), [req_self_ty])
124124
&& let req_res_ty = normalize_with_regions(cx.tcx, param_env, req_res_ty)

‎src/tools/clippy/clippy_utils/src/ty.rs

+12-20
Original file line numberDiff line numberDiff line change
@@ -214,36 +214,21 @@ pub fn implements_trait<'tcx>(
214214
trait_id: DefId,
215215
args: &[GenericArg<'tcx>],
216216
) -> bool {
217-
let callee_id = cx
218-
.enclosing_body
219-
.map(|body| cx.tcx.hir().body_owner(body).owner.to_def_id());
220-
implements_trait_with_env_from_iter(
221-
cx.tcx,
222-
cx.param_env,
223-
ty,
224-
trait_id,
225-
callee_id,
226-
args.iter().map(|&x| Some(x)),
227-
)
217+
implements_trait_with_env_from_iter(cx.tcx, cx.param_env, ty, trait_id, None, args.iter().map(|&x| Some(x)))
228218
}
229219

230220
/// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.
221+
///
222+
/// The `callee_id` argument is used to determine whether this is a function call in a `const fn` environment, used for checking const traits.
231223
pub fn implements_trait_with_env<'tcx>(
232224
tcx: TyCtxt<'tcx>,
233225
param_env: ParamEnv<'tcx>,
234226
ty: Ty<'tcx>,
235227
trait_id: DefId,
236-
callee_id: DefId,
228+
callee_id: Option<DefId>,
237229
args: &[GenericArg<'tcx>],
238230
) -> bool {
239-
implements_trait_with_env_from_iter(
240-
tcx,
241-
param_env,
242-
ty,
243-
trait_id,
244-
Some(callee_id),
245-
args.iter().map(|&x| Some(x)),
246-
)
231+
implements_trait_with_env_from_iter(tcx, param_env, ty, trait_id, callee_id, args.iter().map(|&x| Some(x)))
247232
}
248233

249234
/// Same as `implements_trait_from_env` but takes the arguments as an iterator.
@@ -258,6 +243,13 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
258243
// Clippy shouldn't have infer types
259244
assert!(!ty.has_infer());
260245

246+
// If a `callee_id` is passed, then we assert that it is a body owner
247+
// through calling `body_owner_kind`, which would panic if the callee
248+
// does not have a body.
249+
if let Some(callee_id) = callee_id {
250+
let _ = tcx.hir().body_owner_kind(callee_id);
251+
}
252+
261253
let ty = tcx.erase_regions(ty);
262254
if ty.has_escaping_bound_vars() {
263255
return false;

0 commit comments

Comments
 (0)
Please sign in to comment.