From d18d94d8a0416f9013ad6e59ffae3d9e57382add Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 20 Aug 2025 16:49:04 +0000 Subject: [PATCH] Instantiate higher-ranked binder with erased when checking IntoIterator predicate query instability --- compiler/rustc_lint/src/internal.rs | 23 +++++++++++-------- .../higher-ranked-query-instability.rs | 11 +++++++++ 2 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 tests/ui/lint/internal/higher-ranked-query-instability.rs diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index e1fbe39222b66..929fc8207b03a 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -4,7 +4,7 @@ use rustc_hir::def::Res; use rustc_hir::def_id::DefId; use rustc_hir::{Expr, ExprKind, HirId}; -use rustc_middle::ty::{self, ClauseKind, GenericArgsRef, PredicatePolarity, TraitPredicate, Ty}; +use rustc_middle::ty::{self, GenericArgsRef, PredicatePolarity, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::{Span, sym}; @@ -129,18 +129,23 @@ fn has_unstable_into_iter_predicate<'tcx>( }; let predicates = cx.tcx.predicates_of(callee_def_id).instantiate(cx.tcx, generic_args); for (predicate, _) in predicates { - let ClauseKind::Trait(TraitPredicate { trait_ref, polarity: PredicatePolarity::Positive }) = - predicate.kind().skip_binder() - else { + let Some(trait_pred) = predicate.as_trait_clause() else { continue; }; - // Does the function or method require any of its arguments to implement `IntoIterator`? - if trait_ref.def_id != into_iterator_def_id { + if trait_pred.def_id() != into_iterator_def_id + || trait_pred.polarity() != PredicatePolarity::Positive + { continue; } - let Ok(Some(instance)) = - ty::Instance::try_resolve(cx.tcx, cx.typing_env(), into_iter_fn_def_id, trait_ref.args) - else { + // `IntoIterator::into_iter` has no additional method args. + let into_iter_fn_args = + cx.tcx.instantiate_bound_regions_with_erased(trait_pred).trait_ref.args; + let Ok(Some(instance)) = ty::Instance::try_resolve( + cx.tcx, + cx.typing_env(), + into_iter_fn_def_id, + into_iter_fn_args, + ) else { continue; }; // Does the input type's `IntoIterator` implementation have the diff --git a/tests/ui/lint/internal/higher-ranked-query-instability.rs b/tests/ui/lint/internal/higher-ranked-query-instability.rs new file mode 100644 index 0000000000000..4407baac0c678 --- /dev/null +++ b/tests/ui/lint/internal/higher-ranked-query-instability.rs @@ -0,0 +1,11 @@ +//@ check-pass +//@ compile-flags: -Zunstable-options + +// Make sure we don't try to resolve instances for trait refs that have escaping +// bound vars when computing the query instability lint. + +fn foo() where for<'a> &'a [T]: IntoIterator {} + +fn main() { + foo::<()>(); +}