Skip to content

Commit 28b6373

Browse files
Fall back when relating two opaques by substs in MIR typeck
1 parent 34a6cae commit 28b6373

File tree

5 files changed

+95
-24
lines changed

5 files changed

+95
-24
lines changed

compiler/rustc_infer/src/infer/nll_relate/mod.rs

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,32 @@ where
396396

397397
generalizer.relate(value, value)
398398
}
399+
400+
fn relate_opaques(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
401+
let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
402+
let mut generalize = |ty, ty_is_expected| {
403+
let var = self.infcx.next_ty_var_id_in_universe(
404+
TypeVariableOrigin {
405+
kind: TypeVariableOriginKind::MiscVariable,
406+
span: self.delegate.span(),
407+
},
408+
ty::UniverseIndex::ROOT,
409+
);
410+
if ty_is_expected {
411+
self.relate_ty_var((ty, var))
412+
} else {
413+
self.relate_ty_var((var, ty))
414+
}
415+
};
416+
let (a, b) = match (a.kind(), b.kind()) {
417+
(&ty::Opaque(..), _) => (a, generalize(b, false)?),
418+
(_, &ty::Opaque(..)) => (generalize(a, true)?, b),
419+
_ => unreachable!(),
420+
};
421+
self.delegate.register_opaque_type(a, b, true)?;
422+
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
423+
Ok(a)
424+
}
399425
}
400426

401427
/// When we instantiate an inference variable with a value in
@@ -572,32 +598,12 @@ where
572598
(&ty::Infer(ty::TyVar(vid)), _) => self.relate_ty_var((vid, b)),
573599

574600
(&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => {
575-
self.infcx.super_combine_tys(self, a, b)
601+
infcx.commit_if_ok(|_| infcx.super_combine_tys(self, a, b)).or_else(|err| {
602+
if a_def_id.is_local() { self.relate_opaques(a, b) } else { Err(err) }
603+
})
576604
}
577605
(&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) if did.is_local() => {
578-
let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
579-
let mut generalize = |ty, ty_is_expected| {
580-
let var = infcx.next_ty_var_id_in_universe(
581-
TypeVariableOrigin {
582-
kind: TypeVariableOriginKind::MiscVariable,
583-
span: self.delegate.span(),
584-
},
585-
ty::UniverseIndex::ROOT,
586-
);
587-
if ty_is_expected {
588-
self.relate_ty_var((ty, var))
589-
} else {
590-
self.relate_ty_var((var, ty))
591-
}
592-
};
593-
let (a, b) = match (a.kind(), b.kind()) {
594-
(&ty::Opaque(..), _) => (a, generalize(b, false)?),
595-
(_, &ty::Opaque(..)) => (generalize(a, true)?, b),
596-
_ => unreachable!(),
597-
};
598-
self.delegate.register_opaque_type(a, b, true)?;
599-
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
600-
Ok(a)
606+
self.relate_opaques(a, b)
601607
}
602608

603609
(&ty::Projection(projection_ty), _)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn opaque<T>(t: T) -> impl Sized {
2+
//~^ ERROR cannot resolve opaque type
3+
//~| WARNING function cannot return without recursing
4+
opaque(Some(t))
5+
}
6+
7+
#[allow(dead_code)]
8+
fn main() {}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
warning: function cannot return without recursing
2+
--> $DIR/issue-100075-2.rs:1:1
3+
|
4+
LL | fn opaque<T>(t: T) -> impl Sized {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
6+
...
7+
LL | opaque(Some(t))
8+
| --------------- recursive call site
9+
|
10+
= note: `#[warn(unconditional_recursion)]` on by default
11+
= help: a `loop` may express intention better if this is on purpose
12+
13+
error[E0720]: cannot resolve opaque type
14+
--> $DIR/issue-100075-2.rs:1:23
15+
|
16+
LL | fn opaque<T>(t: T) -> impl Sized {
17+
| ^^^^^^^^^^ recursive opaque type
18+
...
19+
LL | opaque(Some(t))
20+
| --------------- returning here with type `impl Sized`
21+
22+
error: aborting due to previous error; 1 warning emitted
23+
24+
For more information about this error, try `rustc --explain E0720`.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
trait Marker {}
2+
impl<T> Marker for T {}
3+
4+
fn maybe<T>(
5+
_t: T,
6+
) -> Option<
7+
//removing the line below makes it compile
8+
&'static T,
9+
> {
10+
None
11+
}
12+
13+
fn _g<T>(t: &'static T) -> &'static impl Marker {
14+
//~^ ERROR cannot resolve opaque type
15+
if let Some(t) = maybe(t) {
16+
return _g(t);
17+
}
18+
todo!()
19+
}
20+
21+
fn main() {}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0720]: cannot resolve opaque type
2+
--> $DIR/issue-100075.rs:13:37
3+
|
4+
LL | fn _g<T>(t: &'static T) -> &'static impl Marker {
5+
| ^^^^^^^^^^^ recursive opaque type
6+
...
7+
LL | return _g(t);
8+
| ----- returning here with type `&impl Marker`
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0720`.

0 commit comments

Comments
 (0)