Skip to content

Commit 882a5d2

Browse files
committed
Allow coercing sized metadata to unsized metadata
1 parent f387c93 commit 882a5d2

File tree

16 files changed

+213
-47
lines changed

16 files changed

+213
-47
lines changed

compiler/rustc_hir/src/lang_items.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ language_item_table! {
182182
PointeeTrait, sym::pointee_trait, pointee_trait, Target::Trait, GenericRequirement::None;
183183
Metadata, sym::metadata_type, metadata_type, Target::AssocTy, GenericRequirement::None;
184184
DynMetadata, sym::dyn_metadata, dyn_metadata, Target::Struct, GenericRequirement::None;
185+
SizedMetadata, sym::sized_metadata, sized_metadata, Target::Struct, GenericRequirement::None;
186+
MetadataCoerceImpl, sym::metadata_coerce_impl,metadata_coerce_impl, Target::Impl, GenericRequirement::None;
185187

186188
Freeze, sym::freeze, freeze_trait, Target::Trait, GenericRequirement::Exact(0);
187189

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
147147
impl_polarity => { table }
148148
impl_defaultness => { table }
149149
impl_constness => { table }
150-
coerce_unsized_info => { table }
150+
coerce_unsized_kind => { table }
151151
mir_const_qualif => { table }
152152
rendered_const => { table }
153153
asyncness => { table }

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,9 +1463,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14631463
// if this is an impl of `CoerceUnsized`, create its
14641464
// "unsized info", else just store None
14651465
if Some(trait_ref.def_id) == self.tcx.lang_items().coerce_unsized_trait() {
1466-
let coerce_unsized_info =
1467-
self.tcx.at(item.span).coerce_unsized_info(def_id);
1468-
record!(self.tables.coerce_unsized_info[def_id] <- coerce_unsized_info);
1466+
let coerce_unsized_kind =
1467+
self.tcx.at(item.span).coerce_unsized_kind(def_id);
1468+
record!(self.tables.coerce_unsized_kind[def_id] <- coerce_unsized_kind);
14691469
}
14701470
}
14711471

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ define_tables! {
338338
impl_constness: Table<DefIndex, hir::Constness>,
339339
impl_defaultness: Table<DefIndex, hir::Defaultness>,
340340
// FIXME(eddyb) perhaps compute this on the fly if cheap enough?
341-
coerce_unsized_info: Table<DefIndex, Lazy!(ty::adjustment::CoerceUnsizedInfo)>,
341+
coerce_unsized_kind: Table<DefIndex, Lazy!(ty::adjustment::CoerceUnsizedKind)>,
342342
mir_const_qualif: Table<DefIndex, Lazy!(mir::ConstQualifs)>,
343343
rendered_const: Table<DefIndex, Lazy!(String)>,
344344
asyncness: Table<DefIndex, hir::IsAsync>,

compiler/rustc_middle/src/query/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -792,8 +792,8 @@ rustc_queries! {
792792
}
793793

794794
/// Caches `CoerceUnsized` kinds for impls on custom types.
795-
query coerce_unsized_info(key: DefId) -> ty::adjustment::CoerceUnsizedInfo {
796-
desc { |tcx| "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) }
795+
query coerce_unsized_kind(key: DefId) -> ty::adjustment::CoerceUnsizedKind {
796+
desc { |tcx| "computing CoerceUnsized kind for `{}`", tcx.def_path_str(key) }
797797
separate_provide_extern
798798
}
799799

compiler/rustc_middle/src/ty/adjustment.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,11 @@ pub enum AutoBorrow<'tcx> {
181181
/// Demanding this struct also has the side-effect of reporting errors
182182
/// for inappropriate impls.
183183
#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, HashStable)]
184-
pub struct CoerceUnsizedInfo {
185-
/// If this is a "custom coerce" impl, then what kind of custom
186-
/// coercion is it? This applies to impls of `CoerceUnsized` for
187-
/// structs, primarily, where we store a bit of info about which
188-
/// fields need to be coerced.
189-
pub custom_kind: Option<CustomCoerceUnsized>,
190-
}
191-
192-
#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, HashStable)]
193-
pub enum CustomCoerceUnsized {
194-
/// Records the index of the field being coerced.
184+
pub enum CoerceUnsizedKind {
185+
/// Coercion of a raw pointer or ref.
186+
Ptr,
187+
/// Coercion of a struct. Records the index of the field being coerced.
195188
Struct(usize),
189+
/// Coercion of the pointee metadata directly.
190+
JustMetadata,
196191
}

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2292,14 +2292,18 @@ impl<'tcx> Ty<'tcx> {
22922292
| ty::Closure(..)
22932293
| ty::Never
22942294
| ty::Error(_)
2295-
// Extern types have metadata = ().
2296-
| ty::Foreign(..)
22972295
// If returned by `struct_tail_without_normalization` this is a unit struct
22982296
// without any fields, or not a struct, and therefore is Sized.
22992297
| ty::Adt(..)
23002298
// If returned by `struct_tail_without_normalization` this is the empty tuple,
23012299
// a.k.a. unit type, which is Sized
2302-
| ty::Tuple(..) => (tcx.types.unit, false),
2300+
| ty::Tuple(..) => {
2301+
let sized_metadata = tcx.lang_items().sized_metadata().unwrap();
2302+
(tcx.type_of(sized_metadata).subst(tcx, &[tail.into()]), false)
2303+
},
2304+
2305+
// Extern types have metadata = ().
2306+
ty::Foreign(..) => (tcx.types.unit, false),
23032307

23042308
ty::Str | ty::Slice(_) => (tcx.types.usize, false),
23052309
ty::Dynamic(..) => {
@@ -2309,7 +2313,10 @@ impl<'tcx> Ty<'tcx> {
23092313

23102314
// type parameters only have unit metadata if they're sized, so return true
23112315
// to make sure we double check this during confirmation
2312-
ty::Param(_) | ty::Projection(_) | ty::Opaque(..) => (tcx.types.unit, true),
2316+
ty::Param(_) | ty::Projection(_) | ty::Opaque(..) => {
2317+
let sized_metadata = tcx.lang_items().sized_metadata().unwrap();
2318+
(tcx.type_of(sized_metadata).subst(tcx, &[tail.into()]), true)
2319+
},
23132320

23142321
ty::Infer(ty::TyVar(_))
23152322
| ty::Bound(..)

compiler/rustc_monomorphize/src/collector.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ use rustc_middle::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar};
190190
use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
191191
use rustc_middle::mir::visit::Visitor as MirVisitor;
192192
use rustc_middle::mir::{self, Local, Location};
193-
use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast};
193+
use rustc_middle::ty::adjustment::{CoerceUnsizedKind, PointerCast};
194194
use rustc_middle::ty::print::with_no_trimmed_paths;
195195
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
196196
use rustc_middle::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable, VtblEntry};
@@ -1046,8 +1046,11 @@ fn find_vtable_types_for_unsizing<'tcx>(
10461046
(&ty::Adt(source_adt_def, source_substs), &ty::Adt(target_adt_def, target_substs)) => {
10471047
assert_eq!(source_adt_def, target_adt_def);
10481048

1049-
let CustomCoerceUnsized::Struct(coerce_index) =
1050-
crate::custom_coerce_unsize_info(tcx, source_ty, target_ty);
1049+
let CoerceUnsizedKind::Struct(coerce_index) =
1050+
crate::custom_coerce_unsize_info(tcx, source_ty, target_ty)
1051+
else {
1052+
bug!("ty::Adt should have a struct `CoerceUnsized` kind");
1053+
};
10511054

10521055
let source_fields = &source_adt_def.non_enum_variant().fields;
10531056
let target_fields = &target_adt_def.non_enum_variant().fields;

compiler/rustc_monomorphize/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ extern crate rustc_middle;
1313

1414
use rustc_hir::lang_items::LangItem;
1515
use rustc_middle::traits;
16-
use rustc_middle::ty::adjustment::CustomCoerceUnsized;
16+
use rustc_middle::ty::adjustment::CoerceUnsizedKind;
1717
use rustc_middle::ty::query::Providers;
1818
use rustc_middle::ty::{self, Ty, TyCtxt};
1919

@@ -26,7 +26,7 @@ fn custom_coerce_unsize_info<'tcx>(
2626
tcx: TyCtxt<'tcx>,
2727
source_ty: Ty<'tcx>,
2828
target_ty: Ty<'tcx>,
29-
) -> CustomCoerceUnsized {
29+
) -> CoerceUnsizedKind {
3030
let def_id = tcx.require_lang_item(LangItem::CoerceUnsized, None);
3131

3232
let trait_ref = ty::Binder::dummy(ty::TraitRef {
@@ -38,7 +38,7 @@ fn custom_coerce_unsize_info<'tcx>(
3838
Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData {
3939
impl_def_id,
4040
..
41-
})) => tcx.coerce_unsized_info(impl_def_id).custom_kind.unwrap(),
41+
})) => tcx.coerce_unsized_kind(impl_def_id),
4242
impl_source => {
4343
bug!("invalid `CoerceUnsized` impl_source: {:?}", impl_source);
4444
}

compiler/rustc_span/src/symbol.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,7 @@ symbols! {
887887
memtag,
888888
message,
889889
meta,
890+
metadata_coerce_impl,
890891
metadata_type,
891892
min_align_of,
892893
min_align_of_val,
@@ -1311,6 +1312,7 @@ symbols! {
13111312
size_of,
13121313
size_of_val,
13131314
sized,
1315+
sized_metadata,
13141316
skip,
13151317
slice,
13161318
slice_len_fn,

0 commit comments

Comments
 (0)