mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 22:53:28 +00:00
Fall back when relating two opaques by substs in MIR typeck
This commit is contained in:
parent
34a6cae28e
commit
28b6373b1d
@ -396,6 +396,32 @@ where
|
|||||||
|
|
||||||
generalizer.relate(value, value)
|
generalizer.relate(value, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn relate_opaques(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||||
|
let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
|
||||||
|
let mut generalize = |ty, ty_is_expected| {
|
||||||
|
let var = self.infcx.next_ty_var_id_in_universe(
|
||||||
|
TypeVariableOrigin {
|
||||||
|
kind: TypeVariableOriginKind::MiscVariable,
|
||||||
|
span: self.delegate.span(),
|
||||||
|
},
|
||||||
|
ty::UniverseIndex::ROOT,
|
||||||
|
);
|
||||||
|
if ty_is_expected {
|
||||||
|
self.relate_ty_var((ty, var))
|
||||||
|
} else {
|
||||||
|
self.relate_ty_var((var, ty))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let (a, b) = match (a.kind(), b.kind()) {
|
||||||
|
(&ty::Opaque(..), _) => (a, generalize(b, false)?),
|
||||||
|
(_, &ty::Opaque(..)) => (generalize(a, true)?, b),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
self.delegate.register_opaque_type(a, b, true)?;
|
||||||
|
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
|
||||||
|
Ok(a)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When we instantiate an inference variable with a value in
|
/// When we instantiate an inference variable with a value in
|
||||||
@ -572,32 +598,12 @@ where
|
|||||||
(&ty::Infer(ty::TyVar(vid)), _) => self.relate_ty_var((vid, b)),
|
(&ty::Infer(ty::TyVar(vid)), _) => self.relate_ty_var((vid, b)),
|
||||||
|
|
||||||
(&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => {
|
(&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => {
|
||||||
self.infcx.super_combine_tys(self, a, b)
|
infcx.commit_if_ok(|_| infcx.super_combine_tys(self, a, b)).or_else(|err| {
|
||||||
|
if a_def_id.is_local() { self.relate_opaques(a, b) } else { Err(err) }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
(&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) if did.is_local() => {
|
(&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) if did.is_local() => {
|
||||||
let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
|
self.relate_opaques(a, b)
|
||||||
let mut generalize = |ty, ty_is_expected| {
|
|
||||||
let var = infcx.next_ty_var_id_in_universe(
|
|
||||||
TypeVariableOrigin {
|
|
||||||
kind: TypeVariableOriginKind::MiscVariable,
|
|
||||||
span: self.delegate.span(),
|
|
||||||
},
|
|
||||||
ty::UniverseIndex::ROOT,
|
|
||||||
);
|
|
||||||
if ty_is_expected {
|
|
||||||
self.relate_ty_var((ty, var))
|
|
||||||
} else {
|
|
||||||
self.relate_ty_var((var, ty))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let (a, b) = match (a.kind(), b.kind()) {
|
|
||||||
(&ty::Opaque(..), _) => (a, generalize(b, false)?),
|
|
||||||
(_, &ty::Opaque(..)) => (generalize(a, true)?, b),
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
self.delegate.register_opaque_type(a, b, true)?;
|
|
||||||
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
|
|
||||||
Ok(a)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(&ty::Projection(projection_ty), _)
|
(&ty::Projection(projection_ty), _)
|
||||||
|
8
src/test/ui/impl-trait/issue-100075-2.rs
Normal file
8
src/test/ui/impl-trait/issue-100075-2.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fn opaque<T>(t: T) -> impl Sized {
|
||||||
|
//~^ ERROR cannot resolve opaque type
|
||||||
|
//~| WARNING function cannot return without recursing
|
||||||
|
opaque(Some(t))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn main() {}
|
24
src/test/ui/impl-trait/issue-100075-2.stderr
Normal file
24
src/test/ui/impl-trait/issue-100075-2.stderr
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
warning: function cannot return without recursing
|
||||||
|
--> $DIR/issue-100075-2.rs:1:1
|
||||||
|
|
|
||||||
|
LL | fn opaque<T>(t: T) -> impl Sized {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
|
||||||
|
...
|
||||||
|
LL | opaque(Some(t))
|
||||||
|
| --------------- recursive call site
|
||||||
|
|
|
||||||
|
= note: `#[warn(unconditional_recursion)]` on by default
|
||||||
|
= help: a `loop` may express intention better if this is on purpose
|
||||||
|
|
||||||
|
error[E0720]: cannot resolve opaque type
|
||||||
|
--> $DIR/issue-100075-2.rs:1:23
|
||||||
|
|
|
||||||
|
LL | fn opaque<T>(t: T) -> impl Sized {
|
||||||
|
| ^^^^^^^^^^ recursive opaque type
|
||||||
|
...
|
||||||
|
LL | opaque(Some(t))
|
||||||
|
| --------------- returning here with type `impl Sized`
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0720`.
|
21
src/test/ui/impl-trait/issue-100075.rs
Normal file
21
src/test/ui/impl-trait/issue-100075.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
trait Marker {}
|
||||||
|
impl<T> Marker for T {}
|
||||||
|
|
||||||
|
fn maybe<T>(
|
||||||
|
_t: T,
|
||||||
|
) -> Option<
|
||||||
|
//removing the line below makes it compile
|
||||||
|
&'static T,
|
||||||
|
> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _g<T>(t: &'static T) -> &'static impl Marker {
|
||||||
|
//~^ ERROR cannot resolve opaque type
|
||||||
|
if let Some(t) = maybe(t) {
|
||||||
|
return _g(t);
|
||||||
|
}
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
12
src/test/ui/impl-trait/issue-100075.stderr
Normal file
12
src/test/ui/impl-trait/issue-100075.stderr
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
error[E0720]: cannot resolve opaque type
|
||||||
|
--> $DIR/issue-100075.rs:13:37
|
||||||
|
|
|
||||||
|
LL | fn _g<T>(t: &'static T) -> &'static impl Marker {
|
||||||
|
| ^^^^^^^^^^^ recursive opaque type
|
||||||
|
...
|
||||||
|
LL | return _g(t);
|
||||||
|
| ----- returning here with type `&impl Marker`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0720`.
|
Loading…
Reference in New Issue
Block a user