Remove manual WF hack
This commit is contained in:
parent
3ef8e64ce9
commit
df47958894
7 changed files with 89 additions and 72 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue