Remove manual WF hack

This commit is contained in:
Michael Goulet 2025-05-01 16:31:47 +00:00
parent 3ef8e64ce9
commit df47958894
7 changed files with 89 additions and 72 deletions

View file

@ -3,7 +3,7 @@ use std::borrow::Cow;
use std::iter;
use hir::def_id::{DefId, DefIdMap, LocalDefId};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_errors::codes::*;
use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err};
use rustc_hir::def::{DefKind, Res};
@ -356,61 +356,14 @@ fn compare_method_predicate_entailment<'tcx>(
}
if !(impl_sig, trait_sig).references_error() {
// Select obligations to make progress on inference before processing
// the wf obligation below.
// FIXME(-Znext-solver): Not needed when the hack below is removed.
let errors = ocx.select_where_possible();
if !errors.is_empty() {
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
return Err(reported);
}
// See #108544. Annoying, we can end up in cases where, because of winnowing,
// we pick param env candidates over a more general impl, leading to more
// stricter lifetime requirements than we would otherwise need. This can
// trigger the lint. Instead, let's only consider type outlives and
// region outlives obligations.
//
// FIXME(-Znext-solver): Try removing this hack again once the new
// solver is stable. We should just be able to register a WF pred for
// the fn sig.
let mut wf_args: smallvec::SmallVec<[_; 4]> =
unnormalized_impl_sig.inputs_and_output.iter().map(|ty| ty.into()).collect();
// Annoyingly, asking for the WF predicates of an array (with an unevaluated const (only?))
// will give back the well-formed predicate of the same array.
let mut wf_args_seen: FxHashSet<_> = wf_args.iter().copied().collect();
while let Some(term) = wf_args.pop() {
let Some(obligations) = rustc_trait_selection::traits::wf::obligations(
infcx,
param_env,
impl_m_def_id,
0,
term,
impl_m_span,
) else {
continue;
};
for obligation in obligations {
debug!(?obligation);
match obligation.predicate.kind().skip_binder() {
// We need to register Projection oblgiations too, because we may end up with
// an implied `X::Item: 'a`, which gets desugared into `X::Item = ?0`, `?0: 'a`.
// If we only register the region outlives obligation, this leads to an unconstrained var.
// See `implied_bounds_entailment_alias_var.rs` test.
ty::PredicateKind::Clause(
ty::ClauseKind::RegionOutlives(..)
| ty::ClauseKind::TypeOutlives(..)
| ty::ClauseKind::Projection(..),
) => ocx.register_obligation(obligation),
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => {
if wf_args_seen.insert(term) {
wf_args.push(term)
}
}
_ => {}
}
}
}
ocx.register_obligation(traits::Obligation::new(
infcx.tcx,
cause,
param_env,
ty::ClauseKind::WellFormed(
Ty::new_fn_ptr(tcx, ty::Binder::dummy(unnormalized_impl_sig)).into(),
),
));
}
// Check that all obligations are satisfied by the implementation's

View file

@ -15,12 +15,14 @@ where
impl<'a, T, const S: usize> Iterator for BufferIter<'a, T, S> {
//~^ error: the trait bound
//~^^ error: unconstrained generic constant
//~| error: unconstrained generic constant
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
//~^ error: the trait bound
//~^^ error: unconstrained generic constant
//~| error: unconstrained generic constant
//~| error: the trait bound
//~| error: unconstrained generic constant
None
}
}

View file

@ -14,6 +14,22 @@ help: consider further restricting type parameter `T` with trait `Copy`
LL | [T; 1]: Copy, T: std::marker::Copy // But `[T; 1]: Copy` does not imply `T: Copy`
| ++++++++++++++++++++
error[E0277]: the trait bound `T: Copy` is not satisfied
--> $DIR/explicit-drop-bounds.rs:32:5
|
LL | fn drop(&mut self) {}
| ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
|
note: required by a bound in `DropMe`
--> $DIR/explicit-drop-bounds.rs:7:18
|
LL | struct DropMe<T: Copy>(T);
| ^^^^ required by this bound in `DropMe`
help: consider further restricting type parameter `T` with trait `Copy`
|
LL | [T; 1]: Copy, T: std::marker::Copy // But `[T; 1]: Copy` does not imply `T: Copy`
| ++++++++++++++++++++
error[E0277]: the trait bound `T: Copy` is not satisfied
--> $DIR/explicit-drop-bounds.rs:32:18
|
@ -30,6 +46,6 @@ help: consider further restricting type parameter `T` with trait `Copy`
LL | [T; 1]: Copy, T: std::marker::Copy // But `[T; 1]: Copy` does not imply `T: Copy`
| ++++++++++++++++++++
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,5 +1,5 @@
error[E0277]: the trait bound `T: Copy` is not satisfied
--> $DIR/explicit-drop-bounds.rs:37:18
--> $DIR/explicit-drop-bounds.rs:38:18
|
LL | impl<T> Drop for DropMe<T>
| ^^^^^^^^^ the trait `Copy` is not implemented for `T`
@ -15,7 +15,23 @@ LL | impl<T: std::marker::Copy> Drop for DropMe<T>
| +++++++++++++++++++
error[E0277]: the trait bound `T: Copy` is not satisfied
--> $DIR/explicit-drop-bounds.rs:40:18
--> $DIR/explicit-drop-bounds.rs:41:5
|
LL | fn drop(&mut self) {}
| ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
|
note: required by a bound in `DropMe`
--> $DIR/explicit-drop-bounds.rs:7:18
|
LL | struct DropMe<T: Copy>(T);
| ^^^^ required by this bound in `DropMe`
help: consider restricting type parameter `T` with trait `Copy`
|
LL | impl<T: std::marker::Copy> Drop for DropMe<T>
| +++++++++++++++++++
error[E0277]: the trait bound `T: Copy` is not satisfied
--> $DIR/explicit-drop-bounds.rs:41:18
|
LL | fn drop(&mut self) {}
| ^^^^ the trait `Copy` is not implemented for `T`
@ -30,6 +46,6 @@ help: consider restricting type parameter `T` with trait `Copy`
LL | impl<T: std::marker::Copy> Drop for DropMe<T>
| +++++++++++++++++++
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -31,6 +31,7 @@ where
{
fn drop(&mut self) {}
//[bad1]~^ ERROR the trait bound `T: Copy` is not satisfied
//[bad1]~| ERROR the trait bound `T: Copy` is not satisfied
}
#[cfg(bad2)]
@ -39,6 +40,7 @@ impl<T> Drop for DropMe<T>
{
fn drop(&mut self) {}
//[bad2]~^ ERROR the trait bound `T: Copy` is not satisfied
//[bad2]~| ERROR the trait bound `T: Copy` is not satisfied
}
fn main() {}

View file

@ -30,7 +30,8 @@ where
type Output = B;
extern "rust-call" fn call_once(mut self, a: A) -> Self::Output {
//~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
self.call_mut(a)
//~| ERROR type parameter to bare `FnOnce` trait must be a tuple
self.call_mut(a)
//~^ ERROR `A` is not a tuple
}
}
@ -43,6 +44,7 @@ where
{
extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output {
//~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
//~| ERROR type parameter to bare `FnOnce` trait must be a tuple
self.cache.get(&a).map(|a| a.clone()).unwrap_or_else(|| {
let b = (self.fun)(self, a.clone());
self.cache.insert(a, b.clone());

View file

@ -11,8 +11,21 @@ help: consider further restricting type parameter `A` with unstable trait `Tuple
LL | A: Eq + Hash + Clone + std::marker::Tuple,
| ++++++++++++++++++++
error[E0059]: type parameter to bare `FnOnce` trait must be a tuple
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:31:5
|
LL | extern "rust-call" fn call_once(mut self, a: A) -> Self::Output {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A`
|
note: required by a bound in `FnOnce`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
help: consider further restricting type parameter `A` with unstable trait `Tuple`
|
LL | A: Eq + Hash + Clone + std::marker::Tuple,
| ++++++++++++++++++++
error[E0059]: type parameter to bare `FnMut` trait must be a tuple
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:38:12
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:39:12
|
LL | impl<A, B> FnMut<A> for CachedFun<A, B>
| ^^^^^^^^ the trait `Tuple` is not implemented for `A`
@ -24,6 +37,19 @@ help: consider further restricting type parameter `A` with unstable trait `Tuple
LL | A: Eq + Hash + Clone + std::marker::Tuple,
| ++++++++++++++++++++
error[E0059]: type parameter to bare `FnOnce` trait must be a tuple
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:45:5
|
LL | extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A`
|
note: required by a bound in `FnOnce`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
help: consider further restricting type parameter `A` with unstable trait `Tuple`
|
LL | A: Eq + Hash + Clone + std::marker::Tuple,
| ++++++++++++++++++++
error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:31:5
|
@ -36,7 +62,7 @@ LL | A: Eq + Hash + Clone + std::marker::Tuple,
| ++++++++++++++++++++
error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:44:5
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:45:5
|
LL | extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A`
@ -47,12 +73,12 @@ LL | A: Eq + Hash + Clone + std::marker::Tuple,
| ++++++++++++++++++++
error[E0277]: `A` is not a tuple
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:33:23
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:34:19
|
LL | self.call_mut(a)
| -------- ^ the trait `Tuple` is not implemented for `A`
| |
| required by a bound introduced by this call
LL | self.call_mut(a)
| -------- ^ the trait `Tuple` is not implemented for `A`
| |
| required by a bound introduced by this call
|
note: required by a bound in `call_mut`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
@ -62,7 +88,7 @@ LL | A: Eq + Hash + Clone + std::marker::Tuple,
| ++++++++++++++++++++
error[E0277]: `i32` is not a tuple
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:57:26
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:59:26
|
LL | cachedcoso.call_once(1);
| --------- ^ the trait `Tuple` is not implemented for `i32`
@ -76,7 +102,7 @@ help: use a unary tuple instead
LL | cachedcoso.call_once((1,));
| + ++
error: aborting due to 6 previous errors
error: aborting due to 8 previous errors
Some errors have detailed explanations: E0059, E0277.
For more information about an error, try `rustc --explain E0059`.