Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 86e1860

Browse files
committed
Revert to inference variable based hidden type computation for RPIT
1 parent 3136bfe commit 86e1860

File tree

57 files changed

+640
-267
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+640
-267
lines changed

compiler/rustc_infer/src/infer/opaque_types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ impl UseKind {
510510

511511
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
512512
#[instrument(skip(self), level = "debug")]
513-
fn register_hidden_type(
513+
pub fn register_hidden_type(
514514
&self,
515515
opaque_type_key: OpaqueTypeKey<'tcx>,
516516
cause: ObligationCause<'tcx>,

compiler/rustc_typeck/src/check/check.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use super::compare_method::check_type_bounds;
33
use super::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
44
use super::*;
55

6+
use hir::OpaqueTyOrigin;
67
use rustc_attr as attr;
78
use rustc_errors::{Applicability, ErrorGuaranteed};
89
use rustc_hir as hir;
@@ -12,8 +13,9 @@ use rustc_hir::lang_items::LangItem;
1213
use rustc_hir::{def::Res, ItemKind, Node, PathSegment};
1314
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
1415
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
16+
use rustc_infer::traits::ObligationCause;
1517
use rustc_middle::hir::nested_filter;
16-
use rustc_middle::ty::fold::TypeFoldable;
18+
use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable};
1719
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
1820
use rustc_middle::ty::subst::GenericArgKind;
1921
use rustc_middle::ty::util::{Discr, IntTypeExt};
@@ -95,7 +97,46 @@ pub(super) fn check_fn<'a, 'tcx>(
9597

9698
let declared_ret_ty = fn_sig.output();
9799

98-
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(declared_ret_ty)));
100+
let ret_ty = declared_ret_ty.fold_with(&mut BottomUpFolder {
101+
tcx: fcx.tcx,
102+
ty_op: |ty| match *ty.kind() {
103+
ty::Opaque(def_id, substs) => {
104+
let span = tcx.def_span(def_id);
105+
if let Some(origin @ OpaqueTyOrigin::FnReturn(_)) =
106+
fcx.infcx.opaque_type_origin(def_id, span)
107+
{
108+
let hidden_ty = fcx.infcx.next_ty_var(TypeVariableOrigin {
109+
kind: TypeVariableOriginKind::MiscVariable,
110+
span: span,
111+
});
112+
113+
let cause = ObligationCause::misc(span, body.value.hir_id);
114+
match fcx.infcx.register_hidden_type(
115+
ty::OpaqueTypeKey { def_id, substs },
116+
cause.clone(),
117+
param_env,
118+
hidden_ty,
119+
origin,
120+
) {
121+
Ok(infer_ok) => {
122+
fcx.register_infer_ok_obligations(infer_ok);
123+
hidden_ty
124+
}
125+
Err(err) => {
126+
fcx.report_mismatched_types(&cause, ty, hidden_ty, err).emit();
127+
tcx.ty_error()
128+
}
129+
}
130+
} else {
131+
ty
132+
}
133+
}
134+
_ => ty,
135+
},
136+
lt_op: |lt| lt,
137+
ct_op: |ct| ct,
138+
});
139+
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
99140
fcx.ret_type_span = Some(decl.output.span());
100141

101142
let span = body.value.span;

compiler/rustc_typeck/src/check/writeback.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use rustc_span::symbol::sym;
2020
use rustc_span::Span;
2121

2222
use std::mem;
23+
use std::ops::ControlFlow;
2324

2425
///////////////////////////////////////////////////////////////////////////
2526
// Entry point
@@ -503,7 +504,28 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
503504
for (opaque_type_key, decl) in opaque_types {
504505
let hidden_type = match decl.origin {
505506
hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) => {
506-
Some(self.resolve(decl.hidden_type.ty, &decl.hidden_type.span))
507+
let ty = self.resolve(decl.hidden_type.ty, &decl.hidden_type.span);
508+
struct RecursionChecker {
509+
def_id: DefId,
510+
}
511+
impl<'tcx> ty::TypeVisitor<'tcx> for RecursionChecker {
512+
type BreakTy = ();
513+
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
514+
if let ty::Opaque(def_id, _) = *t.kind() {
515+
if def_id == self.def_id {
516+
return ControlFlow::Break(());
517+
}
518+
}
519+
t.super_visit_with(self)
520+
}
521+
}
522+
if ty
523+
.visit_with(&mut RecursionChecker { def_id: opaque_type_key.def_id })
524+
.is_break()
525+
{
526+
return;
527+
}
528+
Some(ty)
507529
}
508530
hir::OpaqueTyOrigin::TyAlias => None,
509531
};

src/test/ui/associated-types/impl-trait-return-missing-constraint.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ fn bar() -> impl Bar {
2323
}
2424

2525
fn baz() -> impl Bar<Item = i32> {
26-
bar()
2726
//~^ ERROR type mismatch resolving `<impl Bar as Foo>::Item == i32`
27+
//~| ERROR type mismatch resolving `<impl Bar as Foo>::Item == i32`
28+
bar()
2829
}
2930

3031
fn main() {
Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0271]: type mismatch resolving `<impl Bar as Foo>::Item == i32`
2-
--> $DIR/impl-trait-return-missing-constraint.rs:26:5
2+
--> $DIR/impl-trait-return-missing-constraint.rs:25:13
33
|
44
LL | fn bar() -> impl Bar {
55
| -------- the expected opaque type
66
...
7-
LL | bar()
8-
| ^^^^^ expected associated type, found `i32`
7+
LL | fn baz() -> impl Bar<Item = i32> {
8+
| ^^^^^^^^^^^^^^^^^^^^ expected associated type, found `i32`
99
|
1010
= note: expected associated type `<impl Bar as Foo>::Item`
1111
found type `i32`
@@ -16,6 +16,29 @@ help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i3
1616
LL | fn bar() -> impl Bar<Item = i32> {
1717
| ++++++++++++
1818

19-
error: aborting due to previous error
19+
error[E0271]: type mismatch resolving `<impl Bar as Foo>::Item == i32`
20+
--> $DIR/impl-trait-return-missing-constraint.rs:25:34
21+
|
22+
LL | fn bar() -> impl Bar {
23+
| -------- the expected opaque type
24+
...
25+
LL | fn baz() -> impl Bar<Item = i32> {
26+
| __________________________________^
27+
LL | |
28+
LL | |
29+
LL | | bar()
30+
LL | | }
31+
| |_^ expected associated type, found `i32`
32+
|
33+
= note: expected associated type `<impl Bar as Foo>::Item`
34+
found type `i32`
35+
= help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32` or calling a method that returns `<impl Bar as Foo>::Item`
36+
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
37+
help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32`
38+
|
39+
LL | fn bar() -> impl Bar<Item = i32> {
40+
| ++++++++++++
41+
42+
error: aborting due to 2 previous errors
2043

2144
For more information about this error, try `rustc --explain E0271`.

src/test/ui/async-await/issue-64130-4-async-move.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ impl Client {
1313
async fn get() { }
1414

1515
pub fn foo() -> impl Future + Send {
16+
//~^ ERROR future cannot be sent between threads safely
1617
let client = Client(Box::new(true));
1718
async move {
18-
//~^ ERROR future cannot be sent between threads safely
1919
match client.status() {
2020
200 => {
2121
let _x = get().await;

src/test/ui/async-await/issue-64130-4-async-move.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: future cannot be sent between threads safely
2-
--> $DIR/issue-64130-4-async-move.rs:17:5
2+
--> $DIR/issue-64130-4-async-move.rs:15:17
33
|
4-
LL | async move {
5-
| ^^^^^^^^^^ future created by async block is not `Send`
4+
LL | pub fn foo() -> impl Future + Send {
5+
| ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
66
|
77
= help: the trait `Sync` is not implemented for `(dyn Any + Send + 'static)`
88
note: future is not `Send` as this value is used across an await

src/test/ui/async-await/issue-70818.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
use std::future::Future;
44
fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
5-
async { (ty, ty1) }
65
//~^ Error future cannot be sent between threads safely
6+
async { (ty, ty1) }
77
}
88

99
fn main() {}

src/test/ui/async-await/issue-70818.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: future cannot be sent between threads safely
2-
--> $DIR/issue-70818.rs:5:5
2+
--> $DIR/issue-70818.rs:4:38
33
|
4-
LL | async { (ty, ty1) }
5-
| ^^^^^ future created by async block is not `Send`
4+
LL | fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
66
|
77
note: captured value is not `Send`
8-
--> $DIR/issue-70818.rs:5:18
8+
--> $DIR/issue-70818.rs:6:18
99
|
1010
LL | async { (ty, ty1) }
1111
| ^^^ has type `U` which is not `Send`

src/test/ui/async-await/issue-70935-complex-spans.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
88
}
99

1010
fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send {
11+
//~^ ERROR: future cannot be sent between threads safely
1112
async move {
12-
//~^ ERROR: future cannot be sent between threads safely
1313
baz(|| async{
1414
foo(tx.clone());
1515
}).await;

0 commit comments

Comments
 (0)