nll-relate: improve hr opaque types support

This commit is contained in:
lcnr
2025-06-05 15:22:25 +02:00
parent 425a9c0a0e
commit f5e43d5ee3
6 changed files with 32 additions and 26 deletions

View File

@@ -124,8 +124,13 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
// by using `ty_vid rel B` and then finally and end by equating `ty_vid` to
// the opaque.
let mut enable_subtyping = |ty, opaque_is_expected| {
let ty_vid = infcx.next_ty_var_id_in_universe(self.span(), ty::UniverseIndex::ROOT);
// We create the fresh inference variable in the highest universe.
// In theory we could limit it to the highest universe in the args of
// the opaque but that isn't really worth the effort.
//
// We'll make sure that the opaque type can actually name everything
// in its hidden type later on.
let ty_vid = infcx.next_ty_vid(self.span());
let variance = if opaque_is_expected {
self.ambient_variance
} else {

View File

@@ -782,22 +782,30 @@ impl<'tcx> InferCtxt<'tcx> {
self.inner.borrow_mut().type_variables().num_vars()
}
pub fn next_ty_vid(&self, span: Span) -> TyVid {
self.next_ty_vid_with_origin(TypeVariableOrigin { span, param_def_id: None })
}
pub fn next_ty_vid_with_origin(&self, origin: TypeVariableOrigin) -> TyVid {
self.inner.borrow_mut().type_variables().new_var(self.universe(), origin)
}
pub fn next_ty_vid_in_universe(&self, span: Span, universe: ty::UniverseIndex) -> TyVid {
let origin = TypeVariableOrigin { span, param_def_id: None };
self.inner.borrow_mut().type_variables().new_var(universe, origin)
}
pub fn next_ty_var(&self, span: Span) -> Ty<'tcx> {
self.next_ty_var_with_origin(TypeVariableOrigin { span, param_def_id: None })
}
pub fn next_ty_var_with_origin(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
let vid = self.inner.borrow_mut().type_variables().new_var(self.universe(), origin);
let vid = self.next_ty_vid_with_origin(origin);
Ty::new_var(self.tcx, vid)
}
pub fn next_ty_var_id_in_universe(&self, span: Span, universe: ty::UniverseIndex) -> TyVid {
let origin = TypeVariableOrigin { span, param_def_id: None };
self.inner.borrow_mut().type_variables().new_var(universe, origin)
}
pub fn next_ty_var_in_universe(&self, span: Span, universe: ty::UniverseIndex) -> Ty<'tcx> {
let vid = self.next_ty_var_id_in_universe(span, universe);
let vid = self.next_ty_vid_in_universe(span, universe);
Ty::new_var(self.tcx, vid)
}

View File

@@ -24,8 +24,7 @@ type Successors<'a> = impl std::fmt::Debug + 'a;
impl Terminator {
#[define_opaque(Successors, Tait)]
fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> {
f = g;
//~^ ERROR mismatched types
f = g; //~ ERROR expected generic lifetime parameter, found `'x`
}
}

View File

@@ -1,15 +1,12 @@
error[E0308]: mismatched types
error[E0792]: expected generic lifetime parameter, found `'x`
--> $DIR/higher_kinded_params3.rs:27:9
|
LL | type Tait<'a> = impl std::fmt::Debug + 'a;
| ------------------------- the expected opaque type
| -- this generic parameter must be used with a generic lifetime parameter
...
LL | f = g;
| ^^^^^ one type is more general than the other
|
= note: expected fn pointer `for<'x> fn(&'x ()) -> Tait<'x>`
found fn pointer `for<'a> fn(&'a ()) -> &'a ()`
| ^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.
For more information about this error, try `rustc --explain E0792`.

View File

@@ -8,7 +8,7 @@ fn foo<'a>(x: &'a ()) -> &'a () {
#[define_opaque(Opaque)]
fn test() -> for<'a> fn(&'a ()) -> Opaque<'a> {
foo //~ ERROR: mismatched types
foo //~ ERROR: expected generic lifetime parameter, found `'a`
}
fn main() {}

View File

@@ -1,15 +1,12 @@
error[E0308]: mismatched types
error[E0792]: expected generic lifetime parameter, found `'a`
--> $DIR/hkl_forbidden3.rs:11:5
|
LL | type Opaque<'a> = impl Sized + 'a;
| --------------- the expected opaque type
| -- this generic parameter must be used with a generic lifetime parameter
...
LL | foo
| ^^^ one type is more general than the other
|
= note: expected fn pointer `for<'a> fn(&'a ()) -> Opaque<'a>`
found fn pointer `for<'a> fn(&'a ()) -> &'a ()`
| ^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.
For more information about this error, try `rustc --explain E0792`.