Skip to content

Commit cff90fe

Browse files
borsehuss
authored andcommitted
Auto merge of rust-lang#99860 - oli-obk:revert_97346, r=pnkfelix
Revert "Rollup merge of rust-lang#97346 - JohnTitor:remove-back-compat-hacks, … …r=oli-obk" This reverts commit c703d11, reversing changes made to 64eb9ab. it didn't apply cleanly, so now it works the same for RPIT and for TAIT instead of just working for RPIT, but we should keep those in sync anyway. It also exposed a TAIT bug (see the feature gated test that now ICEs). r? `@pnkfelix` fixes rust-lang#99536
1 parent 116e19f commit cff90fe

12 files changed

+69
-67
lines changed

compiler/rustc_infer/src/infer/opaque_types.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,25 @@ pub struct OpaqueTypeDecl<'tcx> {
4040
}
4141

4242
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
43-
pub fn replace_opaque_types_with_inference_vars(
43+
/// This is a backwards compatibility hack to prevent breaking changes from
44+
/// lazy TAIT around RPIT handling.
45+
pub fn replace_opaque_types_with_inference_vars<T: TypeFoldable<'tcx>>(
4446
&self,
45-
ty: Ty<'tcx>,
47+
value: T,
4648
body_id: HirId,
4749
span: Span,
4850
param_env: ty::ParamEnv<'tcx>,
49-
) -> InferOk<'tcx, Ty<'tcx>> {
50-
if !ty.has_opaque_types() {
51-
return InferOk { value: ty, obligations: vec![] };
51+
) -> InferOk<'tcx, T> {
52+
if !value.has_opaque_types() {
53+
return InferOk { value, obligations: vec![] };
5254
}
5355
let mut obligations = vec![];
5456
let replace_opaque_type = |def_id: DefId| {
5557
def_id
5658
.as_local()
5759
.map_or(false, |def_id| self.opaque_type_origin(def_id, span).is_some())
5860
};
59-
let value = ty.fold_with(&mut ty::fold::BottomUpFolder {
61+
let value = value.fold_with(&mut ty::fold::BottomUpFolder {
6062
tcx: self.tcx,
6163
lt_op: |lt| lt,
6264
ct_op: |ct| ct,

compiler/rustc_trait_selection/src/traits/project.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,20 @@ fn project_and_unify_type<'cx, 'tcx>(
252252
Err(InProgress) => return ProjectAndUnifyResult::Recursive,
253253
};
254254
debug!(?normalized, ?obligations, "project_and_unify_type result");
255-
match infcx
256-
.at(&obligation.cause, obligation.param_env)
257-
.eq(normalized, obligation.predicate.term)
258-
{
255+
let actual = obligation.predicate.term;
256+
// For an example where this is neccessary see src/test/ui/impl-trait/nested-return-type2.rs
257+
// This allows users to omit re-mentioning all bounds on an associated type and just use an
258+
// `impl Trait` for the assoc type to add more bounds.
259+
let InferOk { value: actual, obligations: new } =
260+
selcx.infcx().replace_opaque_types_with_inference_vars(
261+
actual,
262+
obligation.cause.body_id,
263+
obligation.cause.span,
264+
obligation.param_env,
265+
);
266+
obligations.extend(new);
267+
268+
match infcx.at(&obligation.cause, obligation.param_env).eq(normalized, actual) {
259269
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
260270
obligations.extend(inferred_obligations);
261271
ProjectAndUnifyResult::Holds(obligations)

src/test/ui/impl-trait/issues/issue-86800.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
#![feature(type_alias_impl_trait)]
22

33
// edition:2021
4+
// unset-rustc-env:RUST_BACKTRACE
5+
// compile-flags:-Z treat-err-as-bug=1
6+
// error-pattern:stack backtrace:
7+
// failure-status:101
8+
// normalize-stderr-test "note: .*" -> ""
9+
// normalize-stderr-test "thread 'rustc' .*" -> ""
10+
// normalize-stderr-test " +[0-9]+:.*\n" -> ""
11+
// normalize-stderr-test " +at .*\n" -> ""
412

513
use std::future::Future;
614

@@ -23,7 +31,6 @@ struct Context {
2331
type TransactionResult<O> = Result<O, ()>;
2432

2533
type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
26-
//~^ ERROR unconstrained opaque type
2734

2835
fn execute_transaction_fut<'f, F, O>(
2936
f: F,
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
1-
error: unconstrained opaque type
2-
--> $DIR/issue-86800.rs:25:34
3-
|
4-
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6-
|
7-
= note: `TransactionFuture` must be used in combination with a concrete type within the same module
81

9-
error: aborting due to previous error
2+
stack backtrace:
103

4+
error: internal compiler error: unexpected panic
5+
6+
7+
8+
9+
10+
11+
12+
13+
14+
query stack during panic:
15+
#0 [mir_borrowck] borrow-checking `execute_transaction_fut`
16+
#1 [type_of] computing type of `TransactionFuture::{opaque#0}`
17+
#2 [check_mod_item_types] checking item types in top-level module
18+
#3 [analysis] running analysis passes on this crate
19+
end of query stack

src/test/ui/impl-trait/nested-return-type2-tait.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#![feature(type_alias_impl_trait)]
22

3+
// check-pass
4+
35
trait Duh {}
46

57
impl Duh for i32 {}
@@ -17,13 +19,13 @@ impl<R: Duh, F: FnMut() -> R> Trait for F {
1719

1820
type Sendable = impl Send;
1921

20-
// The `Sendable` here is then later compared against the inference var
21-
// created, causing the inference var to be set to `Sendable` instead of
22+
// The `Sendable` here is converted to an inference var and then later compared
23+
// against the inference var created, causing the inference var to be set to
24+
// the hidden type of `Sendable` instead of
2225
// the hidden type. We already have obligations registered on the inference
2326
// var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
24-
// type does not implement `Duh`, even if its hidden type does. So we error out.
27+
// type does not implement `Duh`, but if its hidden type does.
2528
fn foo() -> impl Trait<Assoc = Sendable> {
26-
//~^ ERROR `Sendable: Duh` is not satisfied
2729
|| 42
2830
}
2931

src/test/ui/impl-trait/nested-return-type2-tait.stderr

-16
This file was deleted.

src/test/ui/impl-trait/nested-return-type2-tait2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ type Traitable = impl Trait<Assoc = Sendable>;
2424
// var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
2525
// type does not implement `Duh`, even if its hidden type does. So we error out.
2626
fn foo() -> Traitable {
27-
//~^ ERROR `Sendable: Duh` is not satisfied
2827
|| 42
28+
//~^ ERROR `Sendable: Duh` is not satisfied
2929
}
3030

3131
fn main() {

src/test/ui/impl-trait/nested-return-type2-tait2.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0277]: the trait bound `Sendable: Duh` is not satisfied
2-
--> $DIR/nested-return-type2-tait2.rs:26:13
2+
--> $DIR/nested-return-type2-tait2.rs:27:5
33
|
4-
LL | fn foo() -> Traitable {
5-
| ^^^^^^^^^ the trait `Duh` is not implemented for `Sendable`
4+
LL | || 42
5+
| ^^^^^ the trait `Duh` is not implemented for `Sendable`
66
|
77
= help: the trait `Duh` is implemented for `i32`
8-
note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2-tait2.rs:28:5: 28:7]`
8+
note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2-tait2.rs:27:5: 27:7]`
99
--> $DIR/nested-return-type2-tait2.rs:14:31
1010
|
1111
LL | impl<R: Duh, F: FnMut() -> R> Trait for F {

src/test/ui/impl-trait/nested-return-type2-tait3.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ type Traitable = impl Trait<Assoc = impl Send>;
2323
// var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
2424
// type does not implement `Duh`, even if its hidden type does. So we error out.
2525
fn foo() -> Traitable {
26-
//~^ ERROR `impl Send: Duh` is not satisfied
2726
|| 42
27+
//~^ ERROR `impl Send: Duh` is not satisfied
2828
}
2929

3030
fn main() {

src/test/ui/impl-trait/nested-return-type2-tait3.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0277]: the trait bound `impl Send: Duh` is not satisfied
2-
--> $DIR/nested-return-type2-tait3.rs:25:13
2+
--> $DIR/nested-return-type2-tait3.rs:26:5
33
|
4-
LL | fn foo() -> Traitable {
5-
| ^^^^^^^^^ the trait `Duh` is not implemented for `impl Send`
4+
LL | || 42
5+
| ^^^^^ the trait `Duh` is not implemented for `impl Send`
66
|
77
= help: the trait `Duh` is implemented for `i32`
8-
note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2-tait3.rs:27:5: 27:7]`
8+
note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2-tait3.rs:26:5: 26:7]`
99
--> $DIR/nested-return-type2-tait3.rs:14:31
1010
|
1111
LL | impl<R: Duh, F: FnMut() -> R> Trait for F {

src/test/ui/impl-trait/nested-return-type2.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// check-pass
2+
13
trait Duh {}
24

35
impl Duh for i32 {}
@@ -18,9 +20,11 @@ impl<R: Duh, F: FnMut() -> R> Trait for F {
1820
// the hidden type. We already have obligations registered on the inference
1921
// var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
2022
// type does not implement `Duh`, even if its hidden type does.
23+
// Lazy TAIT would error out, but we inserted a hack to make it work again,
24+
// keeping backwards compatibility.
2125
fn foo() -> impl Trait<Assoc = impl Send> {
22-
//~^ ERROR `impl Send: Duh` is not satisfied
2326
|| 42
2427
}
2528

26-
fn main() {}
29+
fn main() {
30+
}

src/test/ui/impl-trait/nested-return-type2.stderr

-16
This file was deleted.

0 commit comments

Comments
 (0)