8000 Rollup of 5 pull requests by Manishearth · Pull Request #94328 · rust-lang/rust · GitHub
[go: up one dir, main page]

Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
properly handle fat pointers to uninhabitable types
  • Loading branch information
compiler-errors committed Feb 23, 2022
commit c73a2f8a652134bd7bf00ca61ca65bd7adb8aec7
5 changes: 4 additions & 1 deletion compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,10 @@ fn pointer_or_reference_metadata<'ll, 'tcx>(
// This is a thin pointer. Create a regular pointer type and give it the correct name.
debug_assert_eq!(
(thin_pointer_size, thin_pointer_align),
cx.size_and_align_of(ptr_type)
cx.size_and_align_of(ptr_type),
"ptr_type={}, pointee_type={}",
ptr_type,
pointee_type,
);

unsafe {
Expand Down
33 changes: 16 additions & 17 deletions compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use super::namespace::item_namespace;
use super::CrateDebugContext;

use rustc_hir::def_id::DefId;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::layout::{HasParamEnv, LayoutOf};
use rustc_middle::ty::{self, DefIdTree, Ty};
use rustc_target::abi::Variants;
use tracing::trace;

use crate::common::CodegenCx;
use crate::llvm;
Expand Down Expand Up @@ -63,38 +63,37 @@ pub(crate) fn fat_pointer_kind<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
pointee_ty: Ty<'tcx>,
) -> Option<FatPtrKind> {
let layout = cx.layout_of(pointee_ty);
let pointee_tail_ty = cx.tcx.struct_tail_erasing_lifetimes(pointee_ty, cx.param_env());
let layout = cx.layout_of(pointee_tail_ty);
trace!(
"fat_pointer_kind: {:?} has layout {:?} (is_unsized? {})",
pointee_tail_ty,
layout,
layout.is_unsized()
);

if !layout.is_unsized() {
return None;
}

match *pointee_ty.kind() {
match *pointee_tail_ty.kind() {
ty::Str | ty::Slice(_) => Some(FatPtrKind::Slice),
ty::Dynamic(..) => Some(FatPtrKind::Dyn),
ty::Adt(..) | ty::Tuple(..) if matches!(layout.variants, Variants::Single { .. }) => {
let last_field_index = layout.fields.count() - 1;
debug_assert!(
(0..last_field_index)
.all(|field_index| { !layout.field(cx, field_index).is_unsized() })
);

let unsized_field = layout.field(cx, last_field_index);
debug_assert!(unsized_field.is_unsized());
fat_pointer_kind(cx, unsized_field.ty)
}
ty::Foreign(_) => {
// Assert that pointers to foreign types really are thin:
debug_assert_eq!(
cx.size_of(cx.tcx.mk_imm_ptr(pointee_ty)),
cx.size_of(cx.tcx.mk_imm_ptr(pointee_tail_ty)),
cx.size_of(cx.tcx.mk_imm_ptr(cx.tcx.types.u8))
);
None
}
_ => {
// For all other pointee types we should already have returned None
// at the beginning of the function.
panic!("fat_pointer_kind() - Encountered unexpected `pointee_ty`: {:?}", pointee_ty)
panic!(
"fat_pointer_kind() - Encountered unexpected `pointee_tail_ty`: {:?}",
pointee_tail_ty
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// check-pass
// compile-flags: -Cdebuginfo=2
// fixes issue #94149

#![allow(dead_code)]

pub fn main() {
let _ = Foo::<dyn FooTrait>::new();
}

pub struct Foo<T: FooTrait + ?Sized> {
base: FooBase,
value: T,
}

impl<T: FooTrait + ?Sized> Foo<T> {
pub fn new() -> Box<Foo<T>> {
todo!()
}
}

pub trait FooTrait {}

pub struct FooBase {
cls: Bar,
}

// Bar *must* be a fieldless enum
pub enum Bar {}
0