mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 03:38:29 +00:00
Fix mixing lazy TAIT and RPIT in their defining scopes
This commit is contained in:
parent
4f6e27d4cf
commit
2aa49d4005
@ -95,38 +95,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
|
let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
|
||||||
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
|
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
|
||||||
ty::Opaque(def_id, substs) => {
|
ty::Opaque(def_id, substs) => {
|
||||||
if let ty::Opaque(did2, _) = *b.kind() {
|
let origin = if self.defining_use_anchor.is_some() {
|
||||||
// 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
|
|
||||||
// no one encounters it in practice.
|
|
||||||
// It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
|
|
||||||
// where it is of no concern, so we only check for TAITs.
|
|
||||||
if let Some(OpaqueTyOrigin::TyAlias) = self.opaque_type_origin(did2, cause.span)
|
|
||||||
{
|
|
||||||
self.tcx
|
|
||||||
.sess
|
|
||||||
.struct_span_err(
|
|
||||||
cause.span,
|
|
||||||
"opaque type's hidden type cannot be another opaque type from the same scope",
|
|
||||||
)
|
|
||||||
.span_label(cause.span, "one of the two opaque types used here has to be outside its defining scope")
|
|
||||||
.span_note(
|
|
||||||
self.tcx.def_span(def_id),
|
|
||||||
"opaque type whose hidden type is being assigned",
|
|
||||||
)
|
|
||||||
.span_note(
|
|
||||||
self.tcx.def_span(did2),
|
|
||||||
"opaque type being used as hidden type",
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(self.register_hidden_type(
|
|
||||||
OpaqueTypeKey { def_id, substs },
|
|
||||||
cause.clone(),
|
|
||||||
param_env,
|
|
||||||
b,
|
|
||||||
if self.defining_use_anchor.is_some() {
|
|
||||||
// Check that this is `impl Trait` type is
|
// Check that this is `impl Trait` type is
|
||||||
// declared by `parent_def_id` -- i.e., one whose
|
// declared by `parent_def_id` -- i.e., one whose
|
||||||
// value we are inferring. At present, this is
|
// value we are inferring. At present, this is
|
||||||
@ -164,7 +133,39 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
self.opaque_type_origin(def_id, cause.span)?
|
self.opaque_type_origin(def_id, cause.span)?
|
||||||
} else {
|
} else {
|
||||||
self.opaque_ty_origin_unchecked(def_id, cause.span)
|
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
|
||||||
|
// no one encounters it in practice.
|
||||||
|
// It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
|
||||||
|
// where it is of no concern, so we only check for TAITs.
|
||||||
|
if let Some(OpaqueTyOrigin::TyAlias) = self.opaque_type_origin(did2, cause.span)
|
||||||
|
{
|
||||||
|
self.tcx
|
||||||
|
.sess
|
||||||
|
.struct_span_err(
|
||||||
|
cause.span,
|
||||||
|
"opaque type's hidden type cannot be another opaque type from the same scope",
|
||||||
|
)
|
||||||
|
.span_label(cause.span, "one of the two opaque types used here has to be outside its defining scope")
|
||||||
|
.span_note(
|
||||||
|
self.tcx.def_span(def_id),
|
||||||
|
"opaque type whose hidden type is being assigned",
|
||||||
|
)
|
||||||
|
.span_note(
|
||||||
|
self.tcx.def_span(did2),
|
||||||
|
"opaque type being used as hidden type",
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(self.register_hidden_type(
|
||||||
|
OpaqueTypeKey { def_id, substs },
|
||||||
|
cause.clone(),
|
||||||
|
param_env,
|
||||||
|
b,
|
||||||
|
origin,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => 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