diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index bbf36fef1ddb..2a70c711e051 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -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 diff --git a/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-88022.rs b/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-88022.rs index 99eb92f432c2..76f6aaee6dce 100644 --- a/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-88022.rs +++ b/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-88022.rs @@ -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 { //~^ error: the trait bound - //~^^ error: unconstrained generic constant + //~| error: unconstrained generic constant + //~| error: the trait bound + //~| error: unconstrained generic constant None } } diff --git a/tests/ui/dropck/explicit-drop-bounds.bad1.stderr b/tests/ui/dropck/explicit-drop-bounds.bad1.stderr index 12d7f5b6cd30..28d7546d0c9b 100644 --- a/tests/ui/dropck/explicit-drop-bounds.bad1.stderr +++ b/tests/ui/dropck/explicit-drop-bounds.bad1.stderr @@ -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); + | ^^^^ 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`. diff --git a/tests/ui/dropck/explicit-drop-bounds.bad2.stderr b/tests/ui/dropck/explicit-drop-bounds.bad2.stderr index 5851731e8346..c363676edea3 100644 --- a/tests/ui/dropck/explicit-drop-bounds.bad2.stderr +++ b/tests/ui/dropck/explicit-drop-bounds.bad2.stderr @@ -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 Drop for DropMe | ^^^^^^^^^ the trait `Copy` is not implemented for `T` @@ -15,7 +15,23 @@ LL | impl Drop for DropMe | +++++++++++++++++++ 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); + | ^^^^ required by this bound in `DropMe` +help: consider restricting type parameter `T` with trait `Copy` + | +LL | impl Drop for DropMe + | +++++++++++++++++++ + +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 Drop for DropMe | +++++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/dropck/explicit-drop-bounds.rs b/tests/ui/dropck/explicit-drop-bounds.rs index 6ddac4d314f4..cd1d89ed9dbd 100644 --- a/tests/ui/dropck/explicit-drop-bounds.rs +++ b/tests/ui/dropck/explicit-drop-bounds.rs @@ -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 Drop for DropMe { 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() {} diff --git a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.rs b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.rs index 6380449124ff..3b297a9a6629 100644 --- a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.rs +++ b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.rs @@ -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()); diff --git a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr index 3b051ef9a882..32a564e466be 100644 --- a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr +++ b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr @@ -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 FnMut for CachedFun | ^^^^^^^^ 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`.