Skip to content

Commit 2aa49d4

Browse files
committed
Fix mixing lazy TAIT and RPIT in their defining scopes
1 parent 4f6e27d commit 2aa49d4

File tree

2 files changed

+68
-39
lines changed

2 files changed

+68
-39
lines changed

compiler/rustc_infer/src/infer/opaque_types.rs

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,45 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
9595
let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
9696
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
9797
ty::Opaque(def_id, substs) => {
98+
let origin = if self.defining_use_anchor.is_some() {
99+
// Check that this is `impl Trait` type is
100+
// declared by `parent_def_id` -- i.e., one whose
101+
// value we are inferring. At present, this is
102+
// always true during the first phase of
103+
// type-check, but not always true later on during
104+
// NLL. Once we support named opaque types more fully,
105+
// this same scenario will be able to arise during all phases.
106+
//
107+
// Here is an example using type alias `impl Trait`
108+
// that indicates the distinction we are checking for:
109+
//
110+
// ```rust
111+
// mod a {
112+
// pub type Foo = impl Iterator;
113+
// pub fn make_foo() -> Foo { .. }
114+
// }
115+
//
116+
// mod b {
117+
// fn foo() -> a::Foo { a::make_foo() }
118+
// }
119+
// ```
120+
//
121+
// Here, the return type of `foo` references an
122+
// `Opaque` indeed, but not one whose value is
123+
// presently being inferred. You can get into a
124+
// similar situation with closure return types
125+
// today:
126+
//
127+
// ```rust
128+
// fn foo() -> impl Iterator { .. }
129+
// fn bar() {
130+
// let x = || foo(); // returns the Opaque assoc with `foo`
131+
// }
132+
// ```
133+
self.opaque_type_origin(def_id, cause.span)?
134+
} else {
135+
self.opaque_ty_origin_unchecked(def_id, cause.span)
136+
};
98137
if let ty::Opaque(did2, _) = *b.kind() {
99138
// We could accept this, but there are various ways to handle this situation, and we don't
100139
// want to make a decision on it right now. Likely this case is so super rare anyway, that
@@ -126,45 +165,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
126165
cause.clone(),
127166
param_env,
128167
b,
129-
if self.defining_use_anchor.is_some() {
130-
// Check that this is `impl Trait` type is
131-
// declared by `parent_def_id` -- i.e., one whose
132-
// value we are inferring. At present, this is
133-
// always true during the first phase of
134-
// type-check, but not always true later on during
135-
// NLL. Once we support named opaque types more fully,
136-
// this same scenario will be able to arise during all phases.
137-
//
138-
// Here is an example using type alias `impl Trait`
139-
// that indicates the distinction we are checking for:
140-
//
141-
// ```rust
142-
// mod a {
143-
// pub type Foo = impl Iterator;
144-
// pub fn make_foo() -> Foo { .. }
145-
// }
146-
//
147-
// mod b {
148-
// fn foo() -> a::Foo { a::make_foo() }
149-
// }
150-
// ```
151-
//
152-
// Here, the return type of `foo` references an
153-
// `Opaque` indeed, but not one whose value is
154-
// presently being inferred. You can get into a
155-
// similar situation with closure return types
156-
// today:
157-
//
158-
// ```rust
159-
// fn foo() -> impl Iterator { .. }
160-
// fn bar() {
161-
// let x = || foo(); // returns the Opaque assoc with `foo`
162-
// }
163-
// ```
164-
self.opaque_type_origin(def_id, cause.span)?
165-
} else {
166-
self.opaque_ty_origin_unchecked(def_id, cause.span)
167-
},
168+
origin,
168169
))
169170
}
170171
_ => None,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#![feature(type_alias_impl_trait)]
2+
// edition:2021
3+
// check-pass
4+
5+
struct Pending {}
6+
7+
struct CantOpen {}
8+
9+
trait AsyncRead {}
10+
11+
impl AsyncRead for i32 {}
12+
13+
type PendingReader<'a> = impl AsyncRead + 'a;
14+
15+
type OpeningReadFuture<'a> =
16+
impl std::future::Future<Output = Result<PendingReader<'a>, CantOpen>>;
17+
18+
impl Pending {
19+
async fn read(&mut self) -> Result<impl AsyncRead + '_, CantOpen> {
20+
Ok(42)
21+
}
22+
23+
fn read_fut(&mut self) -> OpeningReadFuture<'_> {
24+
self.read()
25+
}
26+
}
27+
28+
fn main() {}

0 commit comments

Comments
 (0)