Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow instantiating trait object binder in ptr-to-ptr casts #130944

Merged
merged 2 commits into from
Sep 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2437,7 +2437,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {

debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj);

self.eq_types(
self.sub_types(
src_obj,
dst_obj,
location.to_locations(),
Expand Down
6 changes: 6 additions & 0 deletions tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ fn change_lt_ba<'a, 'b: 'a>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> {
x as _ //~ error: lifetime may not live long enough
}

fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> {
x as _ //~ error: lifetime may not live long enough
//~^ error: mismatched types
//~| one type is more general than the other
}

trait Assocked {
type Assoc: ?Sized;
}
Expand Down
35 changes: 29 additions & 6 deletions tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,29 @@ LL | x as _
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance

error: lifetime may not live long enough
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:25:5
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:19:5
|
LL | fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> {
| -- lifetime `'a` defined here
LL | x as _
| ^^^^^^ cast requires that `'a` must outlive `'static`
|
help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound
|
LL | fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> + 'a {
| ++++

error[E0308]: mismatched types
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:19:5
|
LL | x as _
| ^^^^^^ one type is more general than the other
|
= note: expected trait object `dyn for<'b> Trait<'b>`
found trait object `dyn Trait<'_>`

error: lifetime may not live long enough
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:31:5
|
LL | fn change_assoc_0<'a, 'b>(
| -- -- lifetime `'b` defined here
Expand All @@ -77,7 +99,7 @@ LL | x as _
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance

error: lifetime may not live long enough
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:25:5
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:31:5
|
LL | fn change_assoc_0<'a, 'b>(
| -- -- lifetime `'b` defined here
Expand All @@ -97,7 +119,7 @@ help: `'b` and `'a` must be the same: replace one with the other
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: lifetime may not live long enough
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:38:5
|
LL | fn change_assoc_1<'a, 'b>(
| -- -- lifetime `'b` defined here
Expand All @@ -113,7 +135,7 @@ LL | x as _
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance

error: lifetime may not live long enough
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:38:5
|
LL | fn change_assoc_1<'a, 'b>(
| -- -- lifetime `'b` defined here
Expand All @@ -133,12 +155,13 @@ help: `'b` and `'a` must be the same: replace one with the other
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: lifetime may not live long enough
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:20
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:45:20
|
LL | fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) {
| -- lifetime `'a` defined here
LL | require_static(ptr as _)
| ^^^^^^^^ cast requires that `'a` must outlive `'static`

error: aborting due to 9 previous errors
error: aborting due to 11 previous errors

For more information about this error, try `rustc --explain E0308`.
29 changes: 29 additions & 0 deletions tests/ui/cast/ptr-to-trait-obj-ok.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,37 @@ fn cast_inherent_lt<'a, 'b>(x: *mut (dyn Trait<'static> + 'a)) -> *mut (dyn Trai
x as _
}

fn cast_away_higher_ranked<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut dyn Trait<'a> {
x as _
}

fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) {
x as _
}

// If it is possible to coerce from the source to the target type modulo
// regions, then we skip the HIR checks for ptr-to-ptr casts and possibly
// insert an unsizing coercion into the MIR before the ptr-to-ptr cast.
// By wrapping the target type, we ensure that no coercion happens
// and also test the non-coercion cast behavior.
struct Wrapper<T: ?Sized>(T);

fn remove_auto_wrap<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut Wrapper<dyn Trait<'a>> {
x as _
}

fn cast_inherent_lt_wrap<'a, 'b>(
x: *mut (dyn Trait<'static> + 'a),
) -> *mut Wrapper<dyn Trait<'static> + 'b> {
x as _
}

fn cast_away_higher_ranked_wrap<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut Wrapper<dyn Trait<'a>> {
x as _
}

fn unprincipled_wrap<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Sync + 'b> {
x as _
}

fn main() {}
Loading