mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Fix mixing lazy TAIT and RPIT in their defining scopes
This commit is contained in:
parent
4f6e27d4cf
commit
2aa49d4005
@ -95,6 +95,45 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
|
||||
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
|
||||
ty::Opaque(def_id, substs) => {
|
||||
let origin = if self.defining_use_anchor.is_some() {
|
||||
// Check that this is `impl Trait` type is
|
||||
// declared by `parent_def_id` -- i.e., one whose
|
||||
// value we are inferring. At present, this is
|
||||
// always true during the first phase of
|
||||
// type-check, but not always true later on during
|
||||
// NLL. Once we support named opaque types more fully,
|
||||
// this same scenario will be able to arise during all phases.
|
||||
//
|
||||
// Here is an example using type alias `impl Trait`
|
||||
// that indicates the distinction we are checking for:
|
||||
//
|
||||
// ```rust
|
||||
// mod a {
|
||||
// pub type Foo = impl Iterator;
|
||||
// pub fn make_foo() -> Foo { .. }
|
||||
// }
|
||||
//
|
||||
// mod b {
|
||||
// fn foo() -> a::Foo { a::make_foo() }
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// Here, the return type of `foo` references an
|
||||
// `Opaque` indeed, but not one whose value is
|
||||
// presently being inferred. You can get into a
|
||||
// similar situation with closure return types
|
||||
// today:
|
||||
//
|
||||
// ```rust
|
||||
// fn foo() -> impl Iterator { .. }
|
||||
// fn bar() {
|
||||
// let x = || foo(); // returns the Opaque assoc with `foo`
|
||||
// }
|
||||
// ```
|
||||
self.opaque_type_origin(def_id, cause.span)?
|
||||
} else {
|
||||
self.opaque_ty_origin_unchecked(def_id, cause.span)
|
||||
};
|
||||
if let ty::Opaque(did2, _) = *b.kind() {
|
||||
// We could accept this, but there are various ways to handle this situation, and we don't
|
||||
// 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> {
|
||||
cause.clone(),
|
||||
param_env,
|
||||
b,
|
||||
if self.defining_use_anchor.is_some() {
|
||||
// Check that this is `impl Trait` type is
|
||||
// declared by `parent_def_id` -- i.e., one whose
|
||||
// value we are inferring. At present, this is
|
||||
// always true during the first phase of
|
||||
// type-check, but not always true later on during
|
||||
// NLL. Once we support named opaque types more fully,
|
||||
// this same scenario will be able to arise during all phases.
|
||||
//
|
||||
// Here is an example using type alias `impl Trait`
|
||||
// that indicates the distinction we are checking for:
|
||||
//
|
||||
// ```rust
|
||||
// mod a {
|
||||
// pub type Foo = impl Iterator;
|
||||
// pub fn make_foo() -> Foo { .. }
|
||||
// }
|
||||
//
|
||||
// mod b {
|
||||
// fn foo() -> a::Foo { a::make_foo() }
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// Here, the return type of `foo` references an
|
||||
// `Opaque` indeed, but not one whose value is
|
||||
// presently being inferred. You can get into a
|
||||
// similar situation with closure return types
|
||||
// today:
|
||||
//
|
||||
// ```rust
|
||||
// fn foo() -> impl Iterator { .. }
|
||||
// fn bar() {
|
||||
// let x = || foo(); // returns the Opaque assoc with `foo`
|
||||
// }
|
||||
// ```
|
||||
self.opaque_type_origin(def_id, cause.span)?
|
||||
} else {
|
||||
self.opaque_ty_origin_unchecked(def_id, cause.span)
|
||||
},
|
||||
origin,
|
||||
))
|
||||
}
|
||||
_ => None,
|
||||
|
28
src/test/ui/impl-trait/async_scope_creep.rs
Normal file
28
src/test/ui/impl-trait/async_scope_creep.rs
Normal file
@ -0,0 +1,28 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
// edition:2021
|
||||
// check-pass
|
||||
|
||||
struct Pending {}
|
||||
|
||||
struct CantOpen {}
|
||||
|
||||
trait AsyncRead {}
|
||||
|
||||
impl AsyncRead for i32 {}
|
||||
|
||||
type PendingReader<'a> = impl AsyncRead + 'a;
|
||||
|
||||
type OpeningReadFuture<'a> =
|
||||
impl std::future::Future<Output = Result<PendingReader<'a>, CantOpen>>;
|
||||
|
||||
impl Pending {
|
||||
async fn read(&mut self) -> Result<impl AsyncRead + '_, CantOpen> {
|
||||
Ok(42)
|
||||
}
|
||||
|
||||
fn read_fut(&mut self) -> OpeningReadFuture<'_> {
|
||||
self.read()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user