diff options
| author | Ralf Jung <post@ralfj.de> | 2023-09-09 16:52:20 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2023-09-09 17:32:12 +0200 |
| commit | a5b031136702068e4a82d384fec1e66503974064 (patch) | |
| tree | a524f92d747af051578753462cebf9252f06c734 | |
| parent | 38bbc2ce03a2369d96898d58cc0aa06f1a4b5dcf (diff) | |
| download | rust-a5b031136702068e4a82d384fec1e66503974064.tar.gz rust-a5b031136702068e4a82d384fec1e66503974064.zip | |
rustc_layout, rustc_abi: make sure the types are well-formed
| -rw-r--r-- | compiler/rustc_passes/src/abi_test.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/layout_test.rs | 61 | ||||
| -rw-r--r-- | tests/ui/abi/compatibility.rs | 9 | ||||
| -rw-r--r-- | tests/ui/abi/debug.rs | 3 | ||||
| -rw-r--r-- | tests/ui/abi/debug.stderr | 12 | ||||
| -rw-r--r-- | tests/ui/associated-types/issue-85103.rs | 2 | ||||
| -rw-r--r-- | tests/ui/associated-types/issue-85103.stderr | 8 | ||||
| -rw-r--r-- | tests/ui/layout/debug.rs | 3 | ||||
| -rw-r--r-- | tests/ui/layout/debug.stderr | 12 |
9 files changed, 87 insertions, 36 deletions
diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs index 7e781bdd6f4..689f083217b 100644 --- a/compiler/rustc_passes/src/abi_test.rs +++ b/compiler/rustc_passes/src/abi_test.rs @@ -7,6 +7,7 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; use rustc_target::abi::call::FnAbi; +use super::layout_test::ensure_wf; use crate::errors::{AbiInvalidAttribute, AbiNe, AbiOf, UnrecognizedField}; pub fn test_abi(tcx: TyCtxt<'_>) { @@ -131,6 +132,10 @@ fn test_abi_eq<'tcx>(abi1: &'tcx FnAbi<'tcx, Ty<'tcx>>, abi2: &'tcx FnAbi<'tcx, fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: DefId, attr: &Attribute) { let param_env = tcx.param_env(item_def_id); let ty = tcx.type_of(item_def_id).instantiate_identity(); + let span = tcx.def_span(item_def_id); + if !ensure_wf(tcx, param_env, ty, span) { + return; + } let meta_items = attr.meta_item_list().unwrap_or_default(); for meta_item in meta_items { match meta_item.name_or_empty() { @@ -148,11 +153,7 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: DefId, attr: &Attribute) { ); let fn_name = tcx.item_name(item_def_id); - tcx.sess.emit_err(AbiOf { - span: tcx.def_span(item_def_id), - fn_name, - fn_abi: format!("{:#?}", abi), - }); + tcx.sess.emit_err(AbiOf { span, fn_name, fn_abi: format!("{:#?}", abi) }); } sym::assert_eq => { let ty::Tuple(fields) = ty.kind() else { @@ -196,7 +197,7 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: DefId, attr: &Attribute) { if !test_abi_eq(abi1, abi2) { tcx.sess.emit_err(AbiNe { - span: tcx.def_span(item_def_id), + span, left: format!("{:#?}", abi1), right: format!("{:#?}", abi2), }); diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index f3c12e0746d..6dacac150d3 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -2,11 +2,13 @@ use rustc_ast::Attribute; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers, TyAndLayout}; -use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt}; use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_target::abi::{HasDataLayout, TargetDataLayout}; +use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; +use rustc_trait_selection::{infer::TyCtxtInferExt, traits}; use crate::errors::{ LayoutAbi, LayoutAlign, LayoutHomogeneousAggregate, LayoutInvalidAttribute, LayoutOf, @@ -40,9 +42,39 @@ pub fn test_layout(tcx: TyCtxt<'_>) { } } +pub fn ensure_wf<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, + ty: Ty<'tcx>, + span: Span, +) -> bool { + let pred = ty::ClauseKind::WellFormed(ty.into()); + let obligation = traits::Obligation::new( + tcx, + traits::ObligationCause::dummy_with_span(span), + param_env, + pred, + ); + let infcx = tcx.infer_ctxt().build(); + let ocx = traits::ObligationCtxt::new(&infcx); + ocx.register_obligation(obligation); + let errors = ocx.select_all_or_error(); + if !errors.is_empty() { + infcx.err_ctxt().report_fulfillment_errors(&errors); + false + } else { + // looks WF! + true + } +} + fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { let param_env = tcx.param_env(item_def_id); let ty = tcx.type_of(item_def_id).instantiate_identity(); + let span = tcx.def_span(item_def_id.to_def_id()); + if !ensure_wf(tcx, param_env, ty, span) { + return; + } match tcx.layout_of(param_env.and(ty)) { Ok(ty_layout) => { // Check out the `#[rustc_layout(..)]` attribute to tell what to dump. @@ -51,29 +83,24 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { for meta_item in meta_items { match meta_item.name_or_empty() { sym::abi => { - tcx.sess.emit_err(LayoutAbi { - span: tcx.def_span(item_def_id.to_def_id()), - abi: format!("{:?}", ty_layout.abi), - }); + tcx.sess.emit_err(LayoutAbi { span, abi: format!("{:?}", ty_layout.abi) }); } sym::align => { tcx.sess.emit_err(LayoutAlign { - span: tcx.def_span(item_def_id.to_def_id()), + span, align: format!("{:?}", ty_layout.align), }); } sym::size => { - tcx.sess.emit_err(LayoutSize { - span: tcx.def_span(item_def_id.to_def_id()), - size: format!("{:?}", ty_layout.size), - }); + tcx.sess + .emit_err(LayoutSize { span, size: format!("{:?}", ty_layout.size) }); } sym::homogeneous_aggregate => { tcx.sess.emit_err(LayoutHomogeneousAggregate { - span: tcx.def_span(item_def_id.to_def_id()), + span, homogeneous_aggregate: format!( "{:?}", ty_layout.homogeneous_aggregate(&UnwrapLayoutCx { tcx, param_env }) @@ -90,11 +117,7 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { ) ); let ty_layout = format!("{:#?}", *ty_layout); - tcx.sess.emit_err(LayoutOf { - span: tcx.def_span(item_def_id.to_def_id()), - normalized_ty, - ty_layout, - }); + tcx.sess.emit_err(LayoutOf { span, normalized_ty, ty_layout }); } name => { @@ -105,11 +128,7 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { } Err(layout_error) => { - tcx.sess.emit_fatal(Spanned { - node: layout_error.into_diagnostic(), - - span: tcx.def_span(item_def_id.to_def_id()), - }); + tcx.sess.emit_fatal(Spanned { node: layout_error.into_diagnostic(), span }); } } } diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index 0bbcba200c7..86fb365507a 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -2,6 +2,7 @@ #![feature(rustc_attrs, transparent_unions)] #![allow(unused, improper_ctypes_definitions)] use std::marker::PhantomData; +use std::mem::ManuallyDrop; use std::num::NonZeroI32; use std::ptr::NonNull; @@ -37,9 +38,9 @@ enum ReprCEnum<T> { Variant2(T), } #[repr(C)] -union ReprCUnion<T: Copy> { +union ReprCUnion<T> { nothing: (), - something: T, + something: ManuallyDrop<T>, } macro_rules! test_abi_compatible { @@ -82,9 +83,9 @@ struct Wrapper2<T>((), Zst, T); #[repr(transparent)] struct Wrapper3<T>(T, [u8; 0], PhantomData<u64>); #[repr(transparent)] -union WrapperUnion<T: Copy> { +union WrapperUnion<T> { nothing: (), - something: T, + something: ManuallyDrop<T>, } macro_rules! test_transparent { diff --git a/tests/ui/abi/debug.rs b/tests/ui/abi/debug.rs index 9decb41d565..77715ee4023 100644 --- a/tests/ui/abi/debug.rs +++ b/tests/ui/abi/debug.rs @@ -48,3 +48,6 @@ type TestAbiNeFloat = (fn(f32), fn(u32)); //~ ERROR: ABIs are not compatible // Sign matters on some targets (such as s390x), so let's make sure we never accept this. #[rustc_abi(assert_eq)] type TestAbiNeSign = (fn(i32), fn(u32)); //~ ERROR: ABIs are not compatible + +#[rustc_abi(assert_eq)] +type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); //~ ERROR: cannot be known at compilation time diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr index 0feaf0971d8..0ca74fdda35 100644 --- a/tests/ui/abi/debug.stderr +++ b/tests/ui/abi/debug.stderr @@ -945,5 +945,15 @@ error: ABIs are not compatible LL | type TestAbiNeSign = (fn(i32), fn(u32)); | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 10 previous errors +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/debug.rs:53:1 + | +LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); + | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + = note: only the last element of a tuple may have a dynamically sized type + +error: aborting due to 11 previous errors +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/issue-85103.rs b/tests/ui/associated-types/issue-85103.rs index 9c6a419e9f7..77c9876ffa5 100644 --- a/tests/ui/associated-types/issue-85103.rs +++ b/tests/ui/associated-types/issue-85103.rs @@ -4,6 +4,6 @@ use std::borrow::Cow; #[rustc_layout(debug)] type Edges<'a, E> = Cow<'a, [E]>; -//~^ 6:1: 6:18: unable to determine layout for `<[E] as ToOwned>::Owned` because `<[E] as ToOwned>::Owned` cannot be normalized +//~^ the trait bound `[E]: ToOwned` is not satisfied fn main() {} diff --git a/tests/ui/associated-types/issue-85103.stderr b/tests/ui/associated-types/issue-85103.stderr index 17f7148074c..302dec8dad1 100644 --- a/tests/ui/associated-types/issue-85103.stderr +++ b/tests/ui/associated-types/issue-85103.stderr @@ -1,8 +1,12 @@ -error: unable to determine layout for `<[E] as ToOwned>::Owned` because `<[E] as ToOwned>::Owned` cannot be normalized +error[E0277]: the trait bound `[E]: ToOwned` is not satisfied --> $DIR/issue-85103.rs:6:1 | LL | type Edges<'a, E> = Cow<'a, [E]>; - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ the trait `ToOwned` is not implemented for `[E]` + | +note: required by a bound in `Cow` + --> $SRC_DIR/alloc/src/borrow.rs:LL:COL error: aborting due to previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/layout/debug.rs b/tests/ui/layout/debug.rs index 97dc73d3aa7..65f2f3b89af 100644 --- a/tests/ui/layout/debug.rs +++ b/tests/ui/layout/debug.rs @@ -73,3 +73,6 @@ impl S { #[rustc_layout(debug)] const C: () = (); //~ ERROR: can only be applied to } + +#[rustc_layout(debug)] +type Impossible = (str, str); //~ ERROR: cannot be known at compilation time diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index 0973043c678..0910db69129 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -563,5 +563,15 @@ error: `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarat LL | const C: () = (); | ^^^^^^^^^^^ -error: aborting due to 16 previous errors +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/debug.rs:78:1 + | +LL | type Impossible = (str, str); + | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + = note: only the last element of a tuple may have a dynamically sized type + +error: aborting due to 17 previous errors +For more information about this error, try `rustc --explain E0277`. |
