mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 06:35:27 +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)
|
||||
}
|
||||
|
||||
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
|
||||
@ -572,32 +598,12 @@ where
|
||||
(&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 => {
|
||||
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() => {
|
||||
let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
|
||||
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)
|
||||
self.relate_opaques(a, b)
|
||||
}
|
||||
|
||||
(&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