Auto merge of #115354 - matthiaskrgr:rollup-4cotcxz, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #111580 (Don't ICE on layout computation failure) - #114923 (doc: update lld-flavor ref) - #115174 (tests: add test for #67992) - #115187 (Add new interface to smir) - #115300 (Tweaks and improvements on SMIR around generics_of and predicates_of) - #115340 (some more is_zst that should be is_1zst) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
83995f320c
21 changed files with 205 additions and 119 deletions
|
@ -4335,8 +4335,11 @@ dependencies = [
|
|||
name = "rustc_smir"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustc_driver",
|
||||
"rustc_hir",
|
||||
"rustc_interface",
|
||||
"rustc_middle",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"scoped-tls",
|
||||
|
|
|
@ -480,7 +480,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
|
|||
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
|
||||
self.0.sess.span_fatal(span, err.to_string())
|
||||
} else {
|
||||
span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
|
||||
self.0.sess.span_fatal(span, format!("failed to get layout for `{}`: {}", ty, err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ use rustc_codegen_ssa::traits::{
|
|||
BaseTypeMethods,
|
||||
MiscMethods,
|
||||
};
|
||||
use rustc_codegen_ssa::errors as ssa_errors;
|
||||
use rustc_data_structures::base_n;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_middle::span_bug;
|
||||
|
@ -479,7 +480,7 @@ impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
|
|||
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
|
||||
self.sess().emit_fatal(respan(span, err.into_diagnostic()))
|
||||
} else {
|
||||
span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
|
||||
self.tcx.sess.emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::value::Value;
|
|||
|
||||
use cstr::cstr;
|
||||
use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh};
|
||||
use rustc_codegen_ssa::errors as ssa_errors;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_data_structures::base_n;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
@ -1000,7 +1001,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
|
|||
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
|
||||
self.sess().emit_fatal(Spanned { span, node: err.into_diagnostic() })
|
||||
} else {
|
||||
span_bug!(span, "failed to get layout for `{ty}`: {err:?}")
|
||||
self.tcx.sess.emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ codegen_ssa_extract_bundled_libs_parse_archive = failed to parse archive '{$rlib
|
|||
codegen_ssa_extract_bundled_libs_read_entry = failed to read entry '{$rlib}': {$error}
|
||||
codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$error}
|
||||
|
||||
codegen_ssa_failed_to_get_layout = failed to get layout for {$ty}: {$err}
|
||||
|
||||
codegen_ssa_failed_to_write = failed to write {$path}: {$error}
|
||||
|
||||
codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extension} files were produced
|
||||
|
|
|
@ -7,6 +7,7 @@ use rustc_errors::{
|
|||
IntoDiagnosticArg,
|
||||
};
|
||||
use rustc_macros::Diagnostic;
|
||||
use rustc_middle::ty::layout::LayoutError;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::{Span, Symbol};
|
||||
use rustc_type_ir::FloatTy;
|
||||
|
@ -1030,6 +1031,15 @@ pub struct TargetFeatureSafeTrait {
|
|||
pub def: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_failed_to_get_layout)]
|
||||
pub struct FailedToGetLayout<'tcx> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub ty: Ty<'tcx>,
|
||||
pub err: LayoutError<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_error_creating_remark_dir)]
|
||||
pub struct ErrorCreatingRemarkDir {
|
||||
|
|
|
@ -195,8 +195,8 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
|
|||
let ty_b = field.ty(tcx, args_b);
|
||||
|
||||
if let Ok(layout) = tcx.layout_of(param_env.and(ty_a)) {
|
||||
if layout.is_zst() && layout.align.abi.bytes() == 1 {
|
||||
// ignore ZST fields with alignment of 1 byte
|
||||
if layout.is_1zst() {
|
||||
// ignore 1-ZST fields
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -804,7 +804,7 @@ pub(crate) fn nonnull_optimization_guaranteed<'tcx>(
|
|||
tcx.has_attr(def.did(), sym::rustc_nonnull_optimization_guaranteed)
|
||||
}
|
||||
|
||||
/// `repr(transparent)` structs can have a single non-ZST field, this function returns that
|
||||
/// `repr(transparent)` structs can have a single non-1-ZST field, this function returns that
|
||||
/// field.
|
||||
pub fn transparent_newtype_field<'a, 'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
@ -813,8 +813,8 @@ pub fn transparent_newtype_field<'a, 'tcx>(
|
|||
let param_env = tcx.param_env(variant.def_id);
|
||||
variant.fields.iter().find(|field| {
|
||||
let field_ty = tcx.type_of(field.did).instantiate_identity();
|
||||
let is_zst = tcx.layout_of(param_env.and(field_ty)).is_ok_and(|layout| layout.is_zst());
|
||||
!is_zst
|
||||
let is_1zst = tcx.layout_of(param_env.and(field_ty)).is_ok_and(|layout| layout.is_1zst());
|
||||
!is_1zst
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,9 @@ use crate::query::TyCtxtAt;
|
|||
use crate::ty::normalize_erasing_regions::NormalizationError;
|
||||
use crate::ty::{self, ConstKind, ReprOptions, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_error_messages::DiagnosticMessage;
|
||||
use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic};
|
||||
use rustc_errors::{
|
||||
DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg,
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_index::IndexVec;
|
||||
|
@ -265,6 +267,12 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> IntoDiagnosticArg for LayoutError<'tcx> {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
self.to_string().into_diagnostic_arg()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct LayoutCx<'tcx, C> {
|
||||
pub tcx: C,
|
||||
|
|
|
@ -9,6 +9,9 @@ rustc_hir = { path = "../rustc_hir", optional = true }
|
|||
rustc_middle = { path = "../rustc_middle", optional = true }
|
||||
rustc_span = { path = "../rustc_span", optional = true }
|
||||
rustc_target = { path = "../rustc_target", optional = true }
|
||||
rustc_driver = { path = "../rustc_driver", optional = true }
|
||||
rustc_interface = { path = "../rustc_interface", optional = true}
|
||||
rustc_session = {path = "../rustc_session", optional = true}
|
||||
tracing = "0.1"
|
||||
scoped-tls = "1.0"
|
||||
|
||||
|
@ -18,4 +21,7 @@ default = [
|
|||
"rustc_middle",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"rustc_driver",
|
||||
"rustc_interface",
|
||||
"rustc_session",
|
||||
]
|
||||
|
|
|
@ -4,13 +4,18 @@
|
|||
//! until stable MIR is complete.
|
||||
|
||||
use std::fmt::Debug;
|
||||
use std::ops::Index;
|
||||
use std::string::ToString;
|
||||
|
||||
use crate::rustc_internal;
|
||||
use crate::{
|
||||
rustc_smir::Tables,
|
||||
stable_mir::{self, with},
|
||||
};
|
||||
use rustc_driver::{Callbacks, Compilation, RunCompiler};
|
||||
use rustc_interface::{interface, Queries};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::EarlyErrorHandler;
|
||||
pub use rustc_span::def_id::{CrateNum, DefId};
|
||||
|
||||
fn with_tables<R>(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R {
|
||||
|
@ -20,7 +25,7 @@ fn with_tables<R>(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R {
|
|||
}
|
||||
|
||||
pub fn item_def_id(item: &stable_mir::CrateItem) -> DefId {
|
||||
with_tables(|t| t.item_def_id(item))
|
||||
with_tables(|t| t[item.0])
|
||||
}
|
||||
|
||||
pub fn crate_item(did: DefId) -> stable_mir::CrateItem {
|
||||
|
@ -67,23 +72,16 @@ pub fn impl_def(did: DefId) -> stable_mir::ty::ImplDef {
|
|||
with_tables(|t| t.impl_def(did))
|
||||
}
|
||||
|
||||
impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
|
||||
type Output = DefId;
|
||||
|
||||
#[inline(always)]
|
||||
fn index(&self, index: stable_mir::DefId) -> &Self::Output {
|
||||
&self.def_ids[index.0]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Tables<'tcx> {
|
||||
pub fn item_def_id(&self, item: &stable_mir::CrateItem) -> DefId {
|
||||
self.def_ids[item.0]
|
||||
}
|
||||
|
||||
pub fn trait_def_id(&self, trait_def: &stable_mir::ty::TraitDef) -> DefId {
|
||||
self.def_ids[trait_def.0]
|
||||
}
|
||||
|
||||
pub fn impl_trait_def_id(&self, impl_def: &stable_mir::ty::ImplDef) -> DefId {
|
||||
self.def_ids[impl_def.0]
|
||||
}
|
||||
|
||||
pub fn generic_def_id(&self, generic_def: &stable_mir::ty::GenericDef) -> DefId {
|
||||
self.def_ids[generic_def.0]
|
||||
}
|
||||
|
||||
pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem {
|
||||
stable_mir::CrateItem(self.create_def_id(did))
|
||||
}
|
||||
|
@ -140,12 +138,12 @@ impl<'tcx> Tables<'tcx> {
|
|||
// FIXME: this becomes inefficient when we have too many ids
|
||||
for (i, &d) in self.def_ids.iter().enumerate() {
|
||||
if d == did {
|
||||
return i;
|
||||
return stable_mir::DefId(i);
|
||||
}
|
||||
}
|
||||
let id = self.def_ids.len();
|
||||
self.def_ids.push(did);
|
||||
id
|
||||
stable_mir::DefId(id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,3 +161,40 @@ pub type Opaque = impl Debug + ToString + Clone;
|
|||
pub(crate) fn opaque<T: Debug>(value: &T) -> Opaque {
|
||||
format!("{value:?}")
|
||||
}
|
||||
|
||||
pub struct StableMir {
|
||||
args: Vec<String>,
|
||||
callback: fn(TyCtxt<'_>),
|
||||
}
|
||||
|
||||
impl StableMir {
|
||||
/// Creates a new `StableMir` instance, with given test_function and arguments.
|
||||
pub fn new(args: Vec<String>, callback: fn(TyCtxt<'_>)) -> Self {
|
||||
StableMir { args, callback }
|
||||
}
|
||||
|
||||
/// Runs the compiler against given target and tests it with `test_function`
|
||||
pub fn run(&mut self) {
|
||||
rustc_driver::catch_fatal_errors(|| {
|
||||
RunCompiler::new(&self.args.clone(), self).run().unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl Callbacks for StableMir {
|
||||
/// Called after analysis. Return value instructs the compiler whether to
|
||||
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
|
||||
fn after_analysis<'tcx>(
|
||||
&mut self,
|
||||
_handler: &EarlyErrorHandler,
|
||||
_compiler: &interface::Compiler,
|
||||
queries: &'tcx Queries<'tcx>,
|
||||
) -> Compilation {
|
||||
queries.global_ctxt().unwrap().enter(|tcx| {
|
||||
rustc_internal::run(tcx, || (self.callback)(tcx));
|
||||
});
|
||||
// No need to keep going.
|
||||
Compilation::Stop
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
use crate::rustc_internal::{self, opaque};
|
||||
use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
|
||||
use crate::stable_mir::ty::{
|
||||
allocation_filter, new_allocation, Const, FloatTy, GenericDef, GenericParamDef, IntTy,
|
||||
Movability, RigidTy, TyKind, UintTy,
|
||||
allocation_filter, new_allocation, Const, FloatTy, GenericParamDef, IntTy, Movability, RigidTy,
|
||||
TyKind, UintTy,
|
||||
};
|
||||
use crate::stable_mir::{self, Context};
|
||||
use rustc_hir as hir;
|
||||
|
@ -54,7 +54,7 @@ impl<'tcx> Context for Tables<'tcx> {
|
|||
}
|
||||
|
||||
fn trait_decl(&mut self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl {
|
||||
let def_id = self.trait_def_id(trait_def);
|
||||
let def_id = self[trait_def.0];
|
||||
let trait_def = self.tcx.trait_def(def_id);
|
||||
trait_def.stable(self)
|
||||
}
|
||||
|
@ -68,13 +68,13 @@ impl<'tcx> Context for Tables<'tcx> {
|
|||
}
|
||||
|
||||
fn trait_impl(&mut self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait {
|
||||
let def_id = self.impl_trait_def_id(impl_def);
|
||||
let def_id = self[impl_def.0];
|
||||
let impl_trait = self.tcx.impl_trait_ref(def_id).unwrap();
|
||||
impl_trait.stable(self)
|
||||
}
|
||||
|
||||
fn mir_body(&mut self, item: &stable_mir::CrateItem) -> stable_mir::mir::Body {
|
||||
let def_id = self.item_def_id(item);
|
||||
let def_id = self[item.0];
|
||||
let mir = self.tcx.optimized_mir(def_id);
|
||||
stable_mir::mir::Body {
|
||||
blocks: mir
|
||||
|
@ -102,19 +102,16 @@ impl<'tcx> Context for Tables<'tcx> {
|
|||
ty.stable(self)
|
||||
}
|
||||
|
||||
fn generics_of(&mut self, generic_def: &GenericDef) -> stable_mir::ty::Generics {
|
||||
let def_id = self.generic_def_id(generic_def);
|
||||
let generic_def = self.tcx.generics_of(def_id);
|
||||
generic_def.stable(self)
|
||||
fn generics_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics {
|
||||
let def_id = self[def_id];
|
||||
let generics = self.tcx.generics_of(def_id);
|
||||
generics.stable(self)
|
||||
}
|
||||
|
||||
fn predicates_of(
|
||||
&mut self,
|
||||
trait_def: &stable_mir::ty::TraitDef,
|
||||
) -> stable_mir::GenericPredicates {
|
||||
let trait_def_id = self.trait_def_id(trait_def);
|
||||
let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(trait_def_id);
|
||||
stable_mir::GenericPredicates {
|
||||
fn predicates_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates {
|
||||
let def_id = self[def_id];
|
||||
let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(def_id);
|
||||
stable_mir::ty::GenericPredicates {
|
||||
parent: parent.map(|did| self.trait_def(did)),
|
||||
predicates: predicates
|
||||
.iter()
|
||||
|
|
|
@ -13,11 +13,10 @@
|
|||
|
||||
use std::cell::Cell;
|
||||
|
||||
use crate::rustc_smir::Tables;
|
||||
|
||||
use self::ty::{
|
||||
GenericDef, Generics, ImplDef, ImplTrait, PredicateKind, Span, TraitDecl, TraitDef, Ty, TyKind,
|
||||
GenericPredicates, Generics, ImplDef, ImplTrait, Span, TraitDecl, TraitDef, Ty, TyKind,
|
||||
};
|
||||
use crate::rustc_smir::Tables;
|
||||
|
||||
pub mod mir;
|
||||
pub mod ty;
|
||||
|
@ -29,7 +28,8 @@ pub type Symbol = String;
|
|||
pub type CrateNum = usize;
|
||||
|
||||
/// A unique identification number for each item accessible for the current compilation unit.
|
||||
pub type DefId = usize;
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct DefId(pub(crate) usize);
|
||||
|
||||
/// A list of crate items.
|
||||
pub type CrateItems = Vec<CrateItem>;
|
||||
|
@ -40,12 +40,6 @@ pub type TraitDecls = Vec<TraitDef>;
|
|||
/// A list of impl trait decls.
|
||||
pub type ImplTraitDecls = Vec<ImplDef>;
|
||||
|
||||
/// A list of predicates.
|
||||
pub struct GenericPredicates {
|
||||
pub parent: Option<TraitDef>,
|
||||
pub predicates: Vec<(PredicateKind, Span)>,
|
||||
}
|
||||
|
||||
/// Holds information about a crate.
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Crate {
|
||||
|
@ -109,14 +103,6 @@ pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait {
|
|||
with(|cx| cx.trait_impl(trait_impl))
|
||||
}
|
||||
|
||||
pub fn generics_of(generic_def: &GenericDef) -> Generics {
|
||||
with(|cx| cx.generics_of(generic_def))
|
||||
}
|
||||
|
||||
pub fn predicates_of(trait_def: &TraitDef) -> GenericPredicates {
|
||||
with(|cx| cx.predicates_of(trait_def))
|
||||
}
|
||||
|
||||
pub trait Context {
|
||||
fn entry_fn(&mut self) -> Option<CrateItem>;
|
||||
/// Retrieve all items of the local crate that have a MIR associated with them.
|
||||
|
@ -126,8 +112,8 @@ pub trait Context {
|
|||
fn trait_decl(&mut self, trait_def: &TraitDef) -> TraitDecl;
|
||||
fn all_trait_impls(&mut self) -> ImplTraitDecls;
|
||||
fn trait_impl(&mut self, trait_impl: &ImplDef) -> ImplTrait;
|
||||
fn generics_of(&mut self, generic_def: &GenericDef) -> Generics;
|
||||
fn predicates_of(&mut self, trait_def: &TraitDef) -> GenericPredicates;
|
||||
fn generics_of(&mut self, def_id: DefId) -> Generics;
|
||||
fn predicates_of(&mut self, def_id: DefId) -> GenericPredicates;
|
||||
/// Get information about the local crate.
|
||||
fn local_crate(&self) -> Crate;
|
||||
/// Retrieve a list of all external crates.
|
||||
|
|
|
@ -120,27 +120,9 @@ pub struct GenericDef(pub(crate) DefId);
|
|||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct ConstDef(pub(crate) DefId);
|
||||
|
||||
impl TraitDef {
|
||||
pub fn trait_decl(&self) -> TraitDecl {
|
||||
with(|cx| cx.trait_decl(self))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct ImplDef(pub(crate) DefId);
|
||||
|
||||
impl ImplDef {
|
||||
pub fn trait_impl(&self) -> ImplTrait {
|
||||
with(|cx| cx.trait_impl(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl GenericDef {
|
||||
pub fn generics_of(&self) -> Generics {
|
||||
with(|tcx| tcx.generics_of(self))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GenericArgs(pub Vec<GenericArgKind>);
|
||||
|
||||
|
@ -463,6 +445,16 @@ pub struct TraitDecl {
|
|||
pub deny_explicit_impl: bool,
|
||||
}
|
||||
|
||||
impl TraitDecl {
|
||||
pub fn generics_of(&self) -> Generics {
|
||||
with(|cx| cx.generics_of(self.def_id.0))
|
||||
}
|
||||
|
||||
pub fn predicates_of(&self) -> GenericPredicates {
|
||||
with(|cx| cx.predicates_of(self.def_id.0))
|
||||
}
|
||||
}
|
||||
|
||||
pub type ImplTrait = EarlyBinder<TraitRef>;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -499,8 +491,8 @@ pub struct GenericParamDef {
|
|||
}
|
||||
|
||||
pub struct GenericPredicates {
|
||||
pub parent: Option<DefId>,
|
||||
pub predicates: Vec<PredicateKind>,
|
||||
pub parent: Option<TraitDef>,
|
||||
pub predicates: Vec<(PredicateKind, Span)>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
@ -592,13 +592,13 @@ fn make_thin_self_ptr<'tcx>(
|
|||
for i in 0..fat_pointer_layout.fields.count() {
|
||||
let field_layout = fat_pointer_layout.field(cx, i);
|
||||
|
||||
if !field_layout.is_zst() {
|
||||
if !field_layout.is_1zst() {
|
||||
fat_pointer_layout = field_layout;
|
||||
continue 'descend_newtypes;
|
||||
}
|
||||
}
|
||||
|
||||
bug!("receiver has no non-zero-sized fields {:?}", fat_pointer_layout);
|
||||
bug!("receiver has no non-1-ZST fields {:?}", fat_pointer_layout);
|
||||
}
|
||||
|
||||
fat_pointer_layout.ty
|
||||
|
|
|
@ -192,7 +192,7 @@ fn layout_of_uncached<'tcx>(
|
|||
|
||||
let metadata_layout = cx.layout_of(metadata_ty)?;
|
||||
// If the metadata is a 1-zst, then the pointer is thin.
|
||||
if metadata_layout.is_zst() && metadata_layout.align.abi.bytes() == 1 {
|
||||
if metadata_layout.is_1zst() {
|
||||
return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr)));
|
||||
}
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ flavor. Valid options are:
|
|||
* `lld-link`: use the LLVM `lld` executable with the [`-flavor link`
|
||||
flag][lld-flavor] for Microsoft's `link.exe`.
|
||||
|
||||
[lld-flavor]: https://lld.llvm.org/Driver.html
|
||||
[lld-flavor]: https://releases.llvm.org/12.0.0/tools/lld/docs/Driver.html
|
||||
|
||||
## linker-plugin-lto
|
||||
|
||||
|
|
31
tests/debuginfo/regression-bad-location-list-67992.rs
Normal file
31
tests/debuginfo/regression-bad-location-list-67992.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
// compile-flags:-g
|
||||
|
||||
// === GDB TESTS ===================================================================================
|
||||
|
||||
// gdb-command:run
|
||||
|
||||
// gdb-command:print a
|
||||
// gdb-check:$1 = regression_bad_location_list_67992::Foo {x: [0 <repeats 1024 times>]}
|
||||
|
||||
// === LLDB TESTS ==================================================================================
|
||||
|
||||
// lldb-command:run
|
||||
// lldb-command:print a
|
||||
// lldbg-check:(regression_bad_location_list_67992::Foo) $0 = [...]
|
||||
// lldbr-check:(regression_bad_location_list_67992::Foo) a = [...]
|
||||
|
||||
const ARRAY_SIZE: usize = 1024;
|
||||
|
||||
struct Foo {
|
||||
x: [u64; ARRAY_SIZE],
|
||||
}
|
||||
|
||||
fn foo(a: Foo, i: usize) -> u64 {
|
||||
a.x[i] // #break
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
|
||||
println!("{}", foo(Foo { x: [0; ARRAY_SIZE] }, 42));
|
||||
}
|
|
@ -9,18 +9,12 @@
|
|||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
|
||||
extern crate rustc_driver;
|
||||
extern crate rustc_hir;
|
||||
extern crate rustc_interface;
|
||||
extern crate rustc_middle;
|
||||
extern crate rustc_session;
|
||||
extern crate rustc_smir;
|
||||
|
||||
use rustc_driver::{Callbacks, Compilation, RunCompiler};
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_interface::{interface, Queries};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::EarlyErrorHandler;
|
||||
use rustc_smir::{rustc_internal, stable_mir};
|
||||
use std::assert_matches::assert_matches;
|
||||
use std::io::Write;
|
||||
|
@ -130,8 +124,8 @@ fn get_item<'a>(
|
|||
|
||||
/// This test will generate and analyze a dummy crate using the stable mir.
|
||||
/// For that, it will first write the dummy crate into a file.
|
||||
/// It will invoke the compiler using a custom Callback implementation, which will
|
||||
/// invoke Stable MIR APIs after the compiler has finished its analysis.
|
||||
/// Then it will create a `StableMir` using custom arguments and then
|
||||
/// it will run the compiler.
|
||||
fn main() {
|
||||
let path = "input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
|
@ -142,29 +136,7 @@ fn main() {
|
|||
CRATE_NAME.to_string(),
|
||||
path.to_string(),
|
||||
];
|
||||
rustc_driver::catch_fatal_errors(|| {
|
||||
RunCompiler::new(&args, &mut SMirCalls {}).run().unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
struct SMirCalls {}
|
||||
|
||||
impl Callbacks for SMirCalls {
|
||||
/// Called after analysis. Return value instructs the compiler whether to
|
||||
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
|
||||
fn after_analysis<'tcx>(
|
||||
&mut self,
|
||||
_handler: &EarlyErrorHandler,
|
||||
_compiler: &interface::Compiler,
|
||||
queries: &'tcx Queries<'tcx>,
|
||||
) -> Compilation {
|
||||
queries.global_ctxt().unwrap().enter(|tcx| {
|
||||
rustc_smir::rustc_internal::run(tcx, || test_stable_mir(tcx));
|
||||
});
|
||||
// No need to keep going.
|
||||
Compilation::Stop
|
||||
}
|
||||
rustc_internal::StableMir::new(args, test_stable_mir).run();
|
||||
}
|
||||
|
||||
fn generate_input(path: &str) -> std::io::Result<()> {
|
||||
|
|
31
tests/ui/layout/layout-cycle.rs
Normal file
31
tests/ui/layout/layout-cycle.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
// build-fail
|
||||
//~^ ERROR: a cycle occurred during layout computation
|
||||
//~| ERROR: cycle detected when computing layout of
|
||||
|
||||
// Issue #111176 -- ensure that we do not emit ICE on layout cycles
|
||||
|
||||
use std::mem;
|
||||
|
||||
pub struct S<T: Tr> {
|
||||
pub f: <T as Tr>::I,
|
||||
}
|
||||
|
||||
pub trait Tr {
|
||||
type I: Tr;
|
||||
}
|
||||
|
||||
impl<T: Tr> Tr for S<T> {
|
||||
type I = S<S<T>>;
|
||||
}
|
||||
|
||||
impl Tr for () {
|
||||
type I = ();
|
||||
}
|
||||
|
||||
fn foo<T: Tr>() -> usize {
|
||||
mem::size_of::<S<T>>()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("{}", foo::<S<()>>());
|
||||
}
|
11
tests/ui/layout/layout-cycle.stderr
Normal file
11
tests/ui/layout/layout-cycle.stderr
Normal file
|
@ -0,0 +1,11 @@
|
|||
error[E0391]: cycle detected when computing layout of `S<S<()>>`
|
||||
|
|
||||
= note: ...which requires computing layout of `<S<()> as Tr>::I`...
|
||||
= note: ...which again requires computing layout of `S<S<()>>`, completing the cycle
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error: failed to get layout for S<S<()>>: a cycle occurred during layout computation
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0391`.
|
Loading…
Add table
Reference in a new issue