Skip to content

Commit ef53028

Browse files
author
Lukas Markeffsky
committed
[needs comments] normalize better
1 parent ec940ca commit ef53028

File tree

3 files changed

+22
-4
lines changed

3 files changed

+22
-4
lines changed

compiler/rustc_middle/src/ty/sty.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -2759,9 +2759,17 @@ 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+
let metadata = tcx.require_lang_item(LangItem::Metadata, None);
2769+
let project = Ty::new_projection(tcx, metadata, [tail]);
2770+
(project, false)
2771+
}
2772+
},
27652773

27662774
ty::Infer(ty::TyVar(_))
27672775
| ty::Bound(..)

compiler/rustc_trait_selection/src/traits/project.rs

+1-1
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.rs

+10
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,13 @@ fn do_casts<'a>(thin: &mut i32, slice: &mut [i32], trait_object: &mut dyn Trait)
9393
let _: *mut dyn Send = cast(trait_object); //[traits]~ ERROR not satisfied
9494
}
9595
}
96+
97+
struct Wrapper<T: ?Sized> {
98+
_tail: T
99+
}
100+
101+
// This requires normalization from `<Wrapper<T> as Pointee>::Metadata`
102+
// to `<T as Pointee>::Metadata`.
103+
pub fn normalize_better<T: ?Sized>(ptr: *mut Wrapper<T>) -> *mut T {
104+
cast(ptr)
105+
}

0 commit comments

Comments
 (0)