Skip to content

Commit 1b99dca

Browse files
Remove manual WF hack
1 parent 0e517d3 commit 1b99dca

6 files changed

+86
-71
lines changed

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+10-57
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::borrow::Cow;
33
use std::iter;
44

55
use hir::def_id::{DefId, DefIdMap, LocalDefId};
6-
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
6+
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
77
use rustc_errors::codes::*;
88
use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err};
99
use rustc_hir::def::{DefKind, Res};
@@ -345,7 +345,7 @@ fn compare_method_predicate_entailment<'tcx>(
345345

346346
let emitted = report_trait_method_mismatch(
347347
infcx,
348-
cause,
348+
cause.clone(),
349349
param_env,
350350
terr,
351351
(trait_m, trait_sig),
@@ -356,61 +356,14 @@ fn compare_method_predicate_entailment<'tcx>(
356356
}
357357

358358
if !(impl_sig, trait_sig).references_error() {
359-
// Select obligations to make progress on inference before processing
360-
// the wf obligation below.
361-
// FIXME(-Znext-solver): Not needed when the hack below is removed.
362-
let errors = ocx.select_where_possible();
363-
if !errors.is_empty() {
364-
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
365-
return Err(reported);
366-
}
367-
368-
// See #108544. Annoying, we can end up in cases where, because of winnowing,
369-
// we pick param env candidates over a more general impl, leading to more
370-
// stricter lifetime requirements than we would otherwise need. This can
371-
// trigger the lint. Instead, let's only consider type outlives and
372-
// region outlives obligations.
373-
//
374-
// FIXME(-Znext-solver): Try removing this hack again once the new
375-
// solver is stable. We should just be able to register a WF pred for
376-
// the fn sig.
377-
let mut wf_args: smallvec::SmallVec<[_; 4]> =
378-
unnormalized_impl_sig.inputs_and_output.iter().map(|ty| ty.into()).collect();
379-
// Annoyingly, asking for the WF predicates of an array (with an unevaluated const (only?))
380-
// will give back the well-formed predicate of the same array.
381-
let mut wf_args_seen: FxHashSet<_> = wf_args.iter().copied().collect();
382-
while let Some(term) = wf_args.pop() {
383-
let Some(obligations) = rustc_trait_selection::traits::wf::obligations(
384-
infcx,
385-
param_env,
386-
impl_m_def_id,
387-
0,
388-
term,
389-
impl_m_span,
390-
) else {
391-
continue;
392-
};
393-
for obligation in obligations {
394-
debug!(?obligation);
395-
match obligation.predicate.kind().skip_binder() {
396-
// We need to register Projection oblgiations too, because we may end up with
397-
// an implied `X::Item: 'a`, which gets desugared into `X::Item = ?0`, `?0: 'a`.
398-
// If we only register the region outlives obligation, this leads to an unconstrained var.
399-
// See `implied_bounds_entailment_alias_var.rs` test.
400-
ty::PredicateKind::Clause(
401-
ty::ClauseKind::RegionOutlives(..)
402-
| ty::ClauseKind::TypeOutlives(..)
403-
| ty::ClauseKind::Projection(..),
404-
) => ocx.register_obligation(obligation),
405-
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => {
406-
if wf_args_seen.insert(term) {
407-
wf_args.push(term)
408-
}
409-
}
410-
_ => {}
411-
}
412-
}
413-
}
359+
ocx.register_obligation(traits::Obligation::new(
360+
infcx.tcx,
361+
cause.clone(),
362+
param_env,
363+
ty::ClauseKind::WellFormed(
364+
Ty::new_fn_ptr(tcx, ty::Binder::dummy(unnormalized_impl_sig)).into(),
365+
),
366+
));
414367
}
415368

416369
// Check that all obligations are satisfied by the implementation's

tests/ui/dropck/explicit-drop-bounds.bad1.stderr

+17-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,22 @@ help: consider further restricting type parameter `T` with trait `Copy`
1414
LL | [T; 1]: Copy, T: std::marker::Copy // But `[T; 1]: Copy` does not imply `T: Copy`
1515
| ++++++++++++++++++++
1616

17+
error[E0277]: the trait bound `T: Copy` is not satisfied
18+
--> $DIR/explicit-drop-bounds.rs:32:5
19+
|
20+
LL | fn drop(&mut self) {}
21+
| ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
22+
|
23+
note: required by a bound in `DropMe`
24+
--> $DIR/explicit-drop-bounds.rs:7:18
25+
|
26+
LL | struct DropMe<T: Copy>(T);
27+
| ^^^^ required by this bound in `DropMe`
28+
help: consider further restricting type parameter `T` with trait `Copy`
29+
|
30+
LL | [T; 1]: Copy, T: std::marker::Copy // But `[T; 1]: Copy` does not imply `T: Copy`
31+
| ++++++++++++++++++++
32+
1733
error[E0277]: the trait bound `T: Copy` is not satisfied
1834
--> $DIR/explicit-drop-bounds.rs:32:18
1935
|
@@ -30,6 +46,6 @@ help: consider further restricting type parameter `T` with trait `Copy`
3046
LL | [T; 1]: Copy, T: std::marker::Copy // But `[T; 1]: Copy` does not imply `T: Copy`
3147
| ++++++++++++++++++++
3248

33-
error: aborting due to 2 previous errors
49+
error: aborting due to 3 previous errors
3450

3551
For more information about this error, try `rustc --explain E0277`.

tests/ui/dropck/explicit-drop-bounds.bad2.stderr

+19-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0277]: the trait bound `T: Copy` is not satisfied
2-
--> $DIR/explicit-drop-bounds.rs:37:18
2+
--> $DIR/explicit-drop-bounds.rs:38:18
33
|
44
LL | impl<T> Drop for DropMe<T>
55
| ^^^^^^^^^ the trait `Copy` is not implemented for `T`
@@ -15,7 +15,23 @@ LL | impl<T: std::marker::Copy> Drop for DropMe<T>
1515
| +++++++++++++++++++
1616

1717
error[E0277]: the trait bound `T: Copy` is not satisfied
18-
--> $DIR/explicit-drop-bounds.rs:40:18
18+
--> $DIR/explicit-drop-bounds.rs:41:5
19+
|
20+
LL | fn drop(&mut self) {}
21+
| ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
22+
|
23+
note: required by a bound in `DropMe`
24+
--> $DIR/explicit-drop-bounds.rs:7:18
25+
|
26+
LL | struct DropMe<T: Copy>(T);
27+
| ^^^^ required by this bound in `DropMe`
28+
help: consider restricting type parameter `T` with trait `Copy`
29+
|
30+
LL | impl<T: std::marker::Copy> Drop for DropMe<T>
31+
| +++++++++++++++++++
32+
33+
error[E0277]: the trait bound `T: Copy` is not satisfied
34+
--> $DIR/explicit-drop-bounds.rs:41:18
1935
|
2036
LL | fn drop(&mut self) {}
2137
| ^^^^ the trait `Copy` is not implemented for `T`
@@ -30,6 +46,6 @@ help: consider restricting type parameter `T` with trait `Copy`
3046
LL | impl<T: std::marker::Copy> Drop for DropMe<T>
3147
| +++++++++++++++++++
3248

33-
error: aborting due to 2 previous errors
49+
error: aborting due to 3 previous errors
3450

3551
For more information about this error, try `rustc --explain E0277`.

tests/ui/dropck/explicit-drop-bounds.rs

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ where
3131
{
3232
fn drop(&mut self) {}
3333
//[bad1]~^ ERROR the trait bound `T: Copy` is not satisfied
34+
//[bad1]~| ERROR the trait bound `T: Copy` is not satisfied
3435
}
3536

3637
#[cfg(bad2)]
@@ -39,6 +40,7 @@ impl<T> Drop for DropMe<T>
3940
{
4041
fn drop(&mut self) {}
4142
//[bad2]~^ ERROR the trait bound `T: Copy` is not satisfied
43+
//[bad2]~| ERROR the trait bound `T: Copy` is not satisfied
4244
}
4345

4446
fn main() {}

tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ where
3030
type Output = B;
3131
extern "rust-call" fn call_once(mut self, a: A) -> Self::Output {
3232
//~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
33-
self.call_mut(a)
33+
//~| ERROR type parameter to bare `FnOnce` trait must be a tuple
34+
self.call_mut(a)
3435
//~^ ERROR `A` is not a tuple
3536
}
3637
}
@@ -43,6 +44,7 @@ where
4344
{
4445
extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output {
4546
//~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
47+
//~| ERROR type parameter to bare `FnOnce` trait must be a tuple
4648
self.cache.get(&a).map(|a| a.clone()).unwrap_or_else(|| {
4749
let b = (self.fun)(self, a.clone());
4850
self.cache.insert(a, b.clone());

tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr

+35-9
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,21 @@ help: consider further restricting type parameter `A` with unstable trait `Tuple
1111
LL | A: Eq + Hash + Clone + std::marker::Tuple,
1212
| ++++++++++++++++++++
1313

14+
error[E0059]: type parameter to bare `FnOnce` trait must be a tuple
15+
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:31:5
16+
|
17+
LL | extern "rust-call" fn call_once(mut self, a: A) -> Self::Output {
18+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A`
19+
|
20+
note: required by a bound in `FnOnce`
21+
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
22+
help: consider further restricting type parameter `A` with unstable trait `Tuple`
23+
|
24+
LL | A: Eq + Hash + Clone + std::marker::Tuple,
25+
| ++++++++++++++++++++
26+
1427
error[E0059]: type parameter to bare `FnMut` trait must be a tuple
15-
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:38:12
28+
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:39:12
1629
|
1730
LL | impl<A, B> FnMut<A> for CachedFun<A, B>
1831
| ^^^^^^^^ the trait `Tuple` is not implemented for `A`
@@ -24,6 +37,19 @@ help: consider further restricting type parameter `A` with unstable trait `Tuple
2437
LL | A: Eq + Hash + Clone + std::marker::Tuple,
2538
| ++++++++++++++++++++
2639

40+
error[E0059]: type parameter to bare `FnOnce` trait must be a tuple
41+
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:45:5
42+
|
43+
LL | extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output {
44+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A`
45+
|
46+
note: required by a bound in `FnOnce`
47+
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
48+
help: consider further restricting type parameter `A` with unstable trait `Tuple`
49+
|
50+
LL | A: Eq + Hash + Clone + std::marker::Tuple,
51+
| ++++++++++++++++++++
52+
2753
error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument
2854
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:31:5
2955
|
@@ -36,7 +62,7 @@ LL | A: Eq + Hash + Clone + std::marker::Tuple,
3662
| ++++++++++++++++++++
3763

3864
error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument
39-
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:44:5
65+
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:45:5
4066
|
4167
LL | extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output {
4268
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A`
@@ -47,12 +73,12 @@ LL | A: Eq + Hash + Clone + std::marker::Tuple,
4773
| ++++++++++++++++++++
4874

4975
error[E0277]: `A` is not a tuple
50-
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:33:23
76+
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:34:19
5177
|
52-
LL | self.call_mut(a)
53-
| -------- ^ the trait `Tuple` is not implemented for `A`
54-
| |
55-
| required by a bound introduced by this call
78+
LL | self.call_mut(a)
79+
| -------- ^ the trait `Tuple` is not implemented for `A`
80+
| |
81+
| required by a bound introduced by this call
5682
|
5783
note: required by a bound in `call_mut`
5884
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
@@ -62,7 +88,7 @@ LL | A: Eq + Hash + Clone + std::marker::Tuple,
6288
| ++++++++++++++++++++
6389

6490
error[E0277]: `i32` is not a tuple
65-
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:57:26
91+
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:59:26
6692
|
6793
LL | cachedcoso.call_once(1);
6894
| --------- ^ the trait `Tuple` is not implemented for `i32`
@@ -76,7 +102,7 @@ help: use a unary tuple instead
76102
LL | cachedcoso.call_once((1,));
77103
| + ++
78104

79-
error: aborting due to 6 previous errors
105+
error: aborting due to 8 previous errors
80106

81107
Some errors have detailed explanations: E0059, E0277.
82108
For more information about an error, try `rustc --explain E0059`.

0 commit comments

Comments
 (0)