Skip to content

Commit 81eec23

Browse files
author
Lukas Markeffsky
committed
improve normalization of Pointee:Metadata
1 parent f84dd1b commit 81eec23

File tree

5 files changed

+25
-37
lines changed

5 files changed

+25
-37
lines changed

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2759,9 +2759,19 @@ impl<'tcx> Ty<'tcx> {
27592759
(tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()]), false)
27602760
},
27612761

2762-
// type parameters only have unit metadata if they're sized, so return true
2763-
// to make sure we double check this during confirmation
2764-
ty::Param(_) | ty::Alias(..) => (tcx.types.unit, true),
2762+
ty::Param(_) | ty::Alias(..) => {
2763+
if self == tail {
2764+
// type parameters only have unit metadata if they're sized, so return true
2765+
// to make sure we double check this during confirmation
2766+
(tcx.types.unit, true)
2767+
} else {
2768+
// normalize from `Wrapper<T>::Metadata` to `T::Metadata` to allow
2769+
// casting between `*mut Wrapper<T>` and `*mut T`
2770+
let metadata = tcx.require_lang_item(LangItem::Metadata, None);
2771+
let project = Ty::new_projection(tcx, metadata, [tail]);
2772+
(project, false)
2773+
}
2774+
},
27652775

27662776
ty::Infer(ty::TyVar(_))
27672777
| ty::Bound(..)

compiler/rustc_trait_selection/src/traits/project.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1919,7 +1919,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
19191919
// type parameters, opaques, and unnormalized projections have pointer
19201920
// metadata if they're known (e.g. by the param_env) to be sized
19211921
ty::Param(_) | ty::Alias(..)
1922-
if selcx.infcx.predicate_must_hold_modulo_regions(
1922+
if self_ty != tail || selcx.infcx.predicate_must_hold_modulo_regions(
19231923
&obligation.with(
19241924
selcx.tcx(),
19251925
ty::TraitRef::from_lang_item(selcx.tcx(), LangItem::Sized, obligation.cause.span(),[self_ty]),

tests/ui/traits/metadata-cast-fail-traits.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,3 @@ fn do_casts<'a>(thin: &mut i32, slice: &mut [i32], trait_object: &mut dyn Trait)
4343
// may be allowed in the future
4444
let _: *mut dyn Send = cast(trait_object); //~ ERROR not satisfied
4545
}
46-
47-
struct Wrapper<T: ?Sized> {
48-
_tail: T
49-
}
50-
51-
// This requires normalization from `<Wrapper<T> as Pointee>::Metadata`
52-
// to `<T as Pointee>::Metadata`.
53-
fn normalize_better<T: ?Sized>(ptr: *mut Wrapper<T>) -> *mut T {
54-
cast(ptr) //~ ERROR not satisfied
55-
}

tests/ui/traits/metadata-cast-fail-traits.stderr

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -226,28 +226,6 @@ LL | where
226226
LL | T: PointerCast<U>,
227227
| ^^^^^^^^^^^^^^ required by this bound in `cast`
228228

229-
error[E0277]: the trait bound `<Wrapper<T> as Pointee>::Metadata: MetadataCast<<T as Pointee>::Metadata>` is not satisfied
230-
--> $DIR/metadata-cast-fail-traits.rs:54:10
231-
|
232-
LL | cast(ptr)
233-
| ---- ^^^ the trait `MetadataCast<<T as Pointee>::Metadata>` is not implemented for `<Wrapper<T> as Pointee>::Metadata`
234-
| |
235-
| required by a bound introduced by this call
236-
|
237-
= note: required for `Wrapper<T>` to implement `PointerCast<T>`
238-
note: required by a bound in `cast`
239-
--> $DIR/metadata-cast-fail-traits.rs:7:8
240-
|
241-
LL | fn cast<T: ?Sized, U: ?Sized>(_: *mut T) -> *mut U
242-
| ---- required by a bound in this function
243-
LL | where
244-
LL | T: PointerCast<U>,
245-
| ^^^^^^^^^^^^^^ required by this bound in `cast`
246-
help: consider further restricting the associated type
247-
|
248-
LL | fn normalize_better<T: ?Sized>(ptr: *mut Wrapper<T>) -> *mut T where <Wrapper<T> as Pointee>::Metadata: MetadataCast<<T as Pointee>::Metadata> {
249-
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
250-
251-
error: aborting due to 15 previous errors
229+
error: aborting due to 14 previous errors
252230

253231
For more information about this error, try `rustc --explain E0277`.

tests/ui/traits/metadata-cast-pass.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,13 @@ where
7777
fn to_thin<T: ?Sized, U: ?Sized + Thin>(ptr: *mut T) -> *mut U {
7878
cast(ptr)
7979
}
80+
81+
struct Wrapper<T: ?Sized> {
82+
_tail: T
83+
}
84+
85+
// This requires normalization from `<Wrapper<T> as Pointee>::Metadata`
86+
// to `<T as Pointee>::Metadata`.
87+
fn normalize_better<T: ?Sized>(ptr: *mut Wrapper<T>) -> *mut T {
88+
cast(ptr)
89+
}

0 commit comments

Comments
 (0)