diff options
| author | Lukas Markeffsky <@> | 2024-02-05 14:54:24 +0100 |
|---|---|---|
| committer | Lukas Markeffsky <@> | 2024-02-05 15:37:21 +0100 |
| commit | 0c1f401d98c17372d4f305602a43e53cd2ef78a6 (patch) | |
| tree | 46bcda5b2bbb282dbc4783b38b27d45812224738 /compiler/rustc_middle/src/ty | |
| parent | 77fb5406842d6e349b4d67289eba5a9a4a571a9a (diff) | |
| download | rust-0c1f401d98c17372d4f305602a43e53cd2ef78a6.tar.gz rust-0c1f401d98c17372d4f305602a43e53cd2ef78a6.zip | |
old solver: improve normalization of `Pointee::Metadata`
Diffstat (limited to 'compiler/rustc_middle/src/ty')
| -rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index f5fdf210592..6e944d44a8b 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1957,12 +1957,12 @@ impl<'tcx> Ty<'tcx> { } /// Returns the type of metadata for (potentially fat) pointers to this type, - /// and a boolean signifying if this is conditional on this type being `Sized`. - pub fn ptr_metadata_ty( + /// or the struct tail if the metadata type cannot be determined. + pub fn ptr_metadata_ty_or_tail( self, tcx: TyCtxt<'tcx>, normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>, - ) -> (Ty<'tcx>, bool) { + ) -> Result<Ty<'tcx>, Ty<'tcx>> { let tail = tcx.struct_tail_with_normalize(self, normalize, || {}); match tail.kind() { // Sized types @@ -1984,31 +1984,47 @@ impl<'tcx> Ty<'tcx> { | ty::Error(_) // Extern types have metadata = (). | ty::Foreign(..) - // `dyn*` has no metadata + // `dyn*` has metadata = (). | ty::Dynamic(_, _, ty::DynStar) - // If returned by `struct_tail_without_normalization` this is a unit struct + // If returned by `struct_tail_with_normalize` this is a unit struct // without any fields, or not a struct, and therefore is Sized. | ty::Adt(..) - // If returned by `struct_tail_without_normalization` this is the empty tuple, + // If returned by `struct_tail_with_normalize` this is the empty tuple, // a.k.a. unit type, which is Sized - | ty::Tuple(..) => (tcx.types.unit, false), + | ty::Tuple(..) => Ok(tcx.types.unit), + + ty::Str | ty::Slice(_) => Ok(tcx.types.usize), - ty::Str | ty::Slice(_) => (tcx.types.usize, false), ty::Dynamic(_, _, ty::Dyn) => { let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None); - (tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()]), false) - }, + Ok(tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()])) + } - // type parameters only have unit metadata if they're sized, so return true - // to make sure we double check this during confirmation - ty::Param(_) | ty::Alias(..) => (tcx.types.unit, true), + // We don't know the metadata of `self`, but it must be equal to the + // metadata of `tail`. + ty::Param(_) | ty::Alias(..) => Err(tail), ty::Infer(ty::TyVar(_)) | ty::Bound(..) | ty::Placeholder(..) - | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { - bug!("`ptr_metadata_ty` applied to unexpected type: {:?} (tail = {:?})", self, tail) - } + | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => bug!( + "`ptr_metadata_ty_or_tail` applied to unexpected type: {self:?} (tail = {tail:?})" + ), + } + } + + /// Returns the type of metadata for (potentially fat) pointers to this type. + /// Causes an ICE if the metadata type cannot be determined. + pub fn ptr_metadata_ty( + self, + tcx: TyCtxt<'tcx>, + normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>, + ) -> Ty<'tcx> { + match self.ptr_metadata_ty_or_tail(tcx, normalize) { + Ok(metadata) => metadata, + Err(tail) => bug!( + "`ptr_metadata_ty` failed to get metadata for type: {self:?} (tail = {tail:?})" + ), } } |
