Skip to content

Commit

Permalink
Auto merge of rust-lang#137298 - compiler-errors:mir-wf, r=<try>
Browse files Browse the repository at this point in the history
Check signature WF when lowering MIR body

Alternative to rust-lang#137233.

rust-lang#137233 (comment)

Fixes rust-lang#137186

We do this check in `mir_drops_elaborated_and_const_checked` and not during `mir_promoted` because that may result in borrowck cycles if WF requires looking into an opaque hidden type. This causes some TAIT tests to fail unnecessarily.

r? lcnr

try-job: test-various
  • Loading branch information
bors committed Feb 21, 2025
2 parents 71e06b9 + 0e9a6cc commit ba95435
Show file tree
Hide file tree
Showing 29 changed files with 166 additions and 67 deletions.
7 changes: 1 addition & 6 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,14 +745,10 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
match tcx.def_kind(def_id) {
DefKind::Static { .. } => {
tcx.ensure_ok().typeck(def_id);
maybe_check_static_with_link_section(tcx, def_id);
check_static_inhabited(tcx, def_id);
check_static_linkage(tcx, def_id);
}
DefKind::Const => {
tcx.ensure_ok().typeck(def_id);
}
DefKind::Const => {}
DefKind::Enum => {
check_enum(tcx, def_id);
}
Expand All @@ -766,7 +762,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
ExternAbi::Rust,
)
}
// Everything else is checked entirely within check_item_body
}
DefKind::Impl { of_trait } => {
if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ pub fn forbid_intrinsic_abi(tcx: TyCtxt<'_>, sp: Span, abi: ExternAbi) {
}
}

fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) {
pub(super) fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) {
// Only restricted on wasm target for now
if !tcx.sess.target.is_like_wasm {
return;
Expand Down
16 changes: 12 additions & 4 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua
hir::Node::ImplItem(item) => check_impl_item(tcx, item),
hir::Node::ForeignItem(item) => check_foreign_item(tcx, item),
hir::Node::OpaqueTy(_) => Ok(crate::check::check::check_item_type(tcx, def_id)),
_ => unreachable!(),
_ => unreachable!("{node:?}"),
};

if let Some(generics) = node.generics() {
Expand Down Expand Up @@ -1108,7 +1108,13 @@ fn check_associated_item(
let ty = tcx.type_of(item.def_id).instantiate_identity();
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
wfcx.register_wf_obligation(span, loc, ty.into());
check_sized_if_body(wfcx, item.def_id.expect_local(), ty, Some(span));
check_sized_if_body(
wfcx,
item.def_id.expect_local(),
ty,
Some(span),
ObligationCauseCode::SizedConstOrStatic,
);
Ok(())
}
ty::AssocKind::Fn => {
Expand Down Expand Up @@ -1354,7 +1360,7 @@ fn check_item_type(
traits::ObligationCause::new(
ty_span,
wfcx.body_def_id,
ObligationCauseCode::WellFormed(None),
ObligationCauseCode::SizedConstOrStatic,
),
wfcx.param_env,
item_ty,
Expand Down Expand Up @@ -1698,6 +1704,7 @@ fn check_fn_or_method<'tcx>(
hir::FnRetTy::Return(ty) => Some(ty.span),
hir::FnRetTy::DefaultReturn(_) => None,
},
ObligationCauseCode::SizedReturnType,
);
}

Expand All @@ -1706,13 +1713,14 @@ fn check_sized_if_body<'tcx>(
def_id: LocalDefId,
ty: Ty<'tcx>,
maybe_span: Option<Span>,
code: ObligationCauseCode<'tcx>,
) {
let tcx = wfcx.tcx();
if let Some(body) = tcx.hir_maybe_body_owned_by(def_id) {
let span = maybe_span.unwrap_or(body.value.span);

wfcx.register_bound(
ObligationCause::new(span, def_id, traits::ObligationCauseCode::SizedReturnType),
ObligationCause::new(span, def_id, code),
wfcx.param_env,
ty,
tcx.require_lang_item(LangItem::Sized, Some(span)),
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_hir_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
tcx.par_hir_body_owners(|item_def_id| {
let def_kind = tcx.def_kind(item_def_id);
match def_kind {
DefKind::Static { .. } => tcx.ensure_ok().eval_static_initializer(item_def_id),
DefKind::Static { .. } => {
tcx.ensure_ok().eval_static_initializer(item_def_id);
check::maybe_check_static_with_link_section(tcx, item_def_id);
}
DefKind::Const if tcx.generics_of(item_def_id).is_empty() => {
let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty());
let cid = GlobalId { instance, promoted: None };
Expand All @@ -223,12 +226,9 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
}
});

// FIXME: Remove this when we implement creating `DefId`s
// for anon constants during their parents' typeck.
// Typeck all body owners in parallel will produce queries
// cycle errors because it may typeck on anon constants directly.
tcx.par_hir_body_owners(|item_def_id| {
let def_kind = tcx.def_kind(item_def_id);
// Skip `AnonConst`s because we feed their `type_of`.
if !matches!(def_kind, DefKind::AnonConst) {
tcx.ensure_ok().typeck(item_def_id);
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1810,7 +1810,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
crate::GatherLocalsVisitor::new(&fcx).visit_body(body);

let ty = fcx.check_expr_with_expectation(body.value, expected);
fcx.require_type_is_sized(ty, body.value.span, ObligationCauseCode::ConstSized);
fcx.require_type_is_sized(ty, body.value.span, ObligationCauseCode::SizedConstOrStatic);
fcx.write_ty(block.hir_id, ty);
ty
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ pub enum ObligationCauseCode<'tcx> {
},

/// Constant expressions must be sized.
ConstSized,
SizedConstOrStatic,

/// `static` items must have `Sync` type.
SharedStatic,
Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,24 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
body.tainted_by_errors = Some(error_reported);
}

// Also taint the body if it's within a top-level item that is not well formed.
//
// We do this check here and not during `mir_promoted` because that may result
// in borrowck cycles if WF requires looking into an opaque hidden type.
let root = tcx.typeck_root_def_id(def.to_def_id());
match tcx.def_kind(root) {
DefKind::Fn
| DefKind::AssocFn
| DefKind::Static { .. }
| DefKind::Const
| DefKind::AssocConst => {
if let Err(guar) = tcx.check_well_formed(root.expect_local()) {
body.tainted_by_errors = Some(guar);
}
}
_ => {}
}

run_analysis_to_runtime_passes(tcx, &mut body);

tcx.alloc_steal_mir(body)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3125,8 +3125,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
Applicability::MachineApplicable,
);
}
ObligationCauseCode::ConstSized => {
err.note("constant expressions must have a statically known size");
ObligationCauseCode::SizedConstOrStatic => {
err.note("statics and constants must have a statically known size");
}
ObligationCauseCode::InlineAsmSized => {
err.note("all inline asm arguments must have a statically known size");
Expand Down
5 changes: 4 additions & 1 deletion tests/crashes/129095.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
//@ known-bug: rust-lang/rust#129095
//@ compile-flags: -Zmir-enable-passes=+GVN -Zmir-enable-passes=+Inline -Zvalidate-mir

#![feature(adt_const_params, unsized_const_params)]
#![allow(incomplete_features)]

pub fn function_with_bytes<const BYTES: &'static [u8; 4]>() -> &'static [u8] {
BYTES
}

pub fn main() {
assert_eq!(function_with_bytes::<b"AAAAb">(), &[0x41, 0x41, 0x41, 0x41]);
assert_eq!(function_with_bytes::<b"AAAAA">(), &[0x41, 0x41, 0x41, 0x41]);
}
2 changes: 1 addition & 1 deletion tests/crashes/132960.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//@ known-bug: #132960

#![feature(adt_const_params, const_ptr_read, generic_const_exprs)]
#![feature(adt_const_params, const_ptr_read, generic_const_exprs, unsized_const_params)]

const fn concat_strs<const A: &'static str, const B: &'static str>() -> &'static str
where
Expand Down
3 changes: 3 additions & 0 deletions tests/crashes/134654.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
//@ compile-flags: -Zmir-enable-passes=+GVN -Zmir-enable-passes=+Inline -Zvalidate-mir
//@ only-x86_64

#![feature(adt_const_params, unsized_const_params)]
#![allow(incomplete_features)]

fn function_with_bytes<const BYTES:
&'static [u8; 0xa9008fb6c9d81e42_0e25730562a601c8_u128]>() -> &'static [u8] {
BYTES
Expand Down
2 changes: 2 additions & 0 deletions tests/crashes/135128.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//@ known-bug: #135128
//@ compile-flags: -Copt-level=1 --edition=2021

#![feature(trivial_bounds)]

async fn return_str() -> str
where
str: Sized,
Expand Down
3 changes: 3 additions & 0 deletions tests/crashes/135570.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
//@compile-flags: -Zvalidate-mir -Zmir-enable-passes=+Inline -Copt-level=0 -Zmir-enable-passes=+GVN
//@ only-x86_64

#![feature(adt_const_params, unsized_const_params)]
#![allow(incomplete_features)]

fn function_with_bytes<const BYTES: &'static [u8; 0xc7b889180b67b07d_bc1a3c88783d35b5_u128]>(
) -> &'static [u8] {
BYTES
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,6 @@ warning: type `v17` should have an upper camel case name
LL | pub struct v17<const v10: usize, const v7: v11> {
| ^^^ help: convert the identifier to upper camel case (notice the capitalization): `V17`

error[E0425]: cannot find function `v6` in this scope
--> $DIR/unevaluated-const-ice-119731.rs:13:35
|
LL | const v0: [[usize; v4]; v4] = v6(v8);
| ^^ not found in this scope

error: `[[usize; v4]; v4]` is forbidden as the type of a const generic parameter
--> $DIR/unevaluated-const-ice-119731.rs:16:48
|
Expand All @@ -72,6 +66,12 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more
LL + #![feature(adt_const_params)]
|

error[E0425]: cannot find function `v6` in this scope
--> $DIR/unevaluated-const-ice-119731.rs:13:35
|
LL | const v0: [[usize; v4]; v4] = v6(v8);
| ^^ not found in this scope

error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
--> $DIR/unevaluated-const-ice-119731.rs:28:37
|
Expand Down
1 change: 1 addition & 0 deletions tests/ui/consts/const-slice-array-deref.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ LL | const ONE: [u16] = [1];
| ^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u16]`
= note: statics and constants must have a statically known size

error[E0308]: mismatched types
--> $DIR/const-slice-array-deref.rs:1:20
Expand Down
4 changes: 4 additions & 0 deletions tests/ui/consts/const-unsized.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ LL | const CONST_0: dyn Debug + Sync = *(&0 as &(dyn Debug + Sync));
| ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
= note: statics and constants must have a statically known size

error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/const-unsized.rs:7:18
Expand All @@ -13,6 +14,7 @@ LL | const CONST_FOO: str = *"foo";
| ^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
= note: statics and constants must have a statically known size

error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time
--> $DIR/const-unsized.rs:11:18
Expand All @@ -21,6 +23,7 @@ LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
| ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
= note: statics and constants must have a statically known size

error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/const-unsized.rs:15:20
Expand All @@ -29,6 +32,7 @@ LL | static STATIC_BAR: str = *"bar";
| ^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
= note: statics and constants must have a statically known size

error[E0507]: cannot move out of a shared reference
--> $DIR/const-unsized.rs:3:35
Expand Down
1 change: 1 addition & 0 deletions tests/ui/consts/const_refs_to_static-ice-121413.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ LL | static FOO: Sync = AtomicUsize::new(0);
| ^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn Sync + 'static)`
= note: statics and constants must have a statically known size

error: aborting due to 2 previous errors; 1 warning emitted

Expand Down
7 changes: 7 additions & 0 deletions tests/ui/consts/dont-ctfe-unsized-initializer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
static S: str = todo!();
//~^ ERROR the size for values of type `str` cannot be known at compilation time

const C: str = todo!();
//~^ ERROR the size for values of type `str` cannot be known at compilation time

fn main() {}
21 changes: 21 additions & 0 deletions tests/ui/consts/dont-ctfe-unsized-initializer.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/dont-ctfe-unsized-initializer.rs:1:11
|
LL | static S: str = todo!();
| ^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
= note: statics and constants must have a statically known size

error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/dont-ctfe-unsized-initializer.rs:4:10
|
LL | const C: str = todo!();
| ^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
= note: statics and constants must have a statically known size

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
12 changes: 6 additions & 6 deletions tests/ui/consts/issue-39974.stderr
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
error[E0308]: mismatched types
--> $DIR/issue-39974.rs:5:19
|
LL | f: [[f64; 2]; LENGTH],
| ^^^^^^ expected `usize`, found `f64`

error[E0308]: mismatched types
--> $DIR/issue-39974.rs:1:21
|
Expand All @@ -9,12 +15,6 @@ help: use a float literal
LL | const LENGTH: f64 = 2.0;
| ++

error[E0308]: mismatched types
--> $DIR/issue-39974.rs:5:19
|
LL | f: [[f64; 2]; LENGTH],
| ^^^^^^ expected `usize`, found `f64`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0308`.
1 change: 1 addition & 0 deletions tests/ui/extern/issue-36122-accessing-externed-dst.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ LL | static symbol: [usize];
| ^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[usize]`
= note: statics and constants must have a statically known size

error[E0133]: use of extern static is unsafe and requires unsafe function or block
--> $DIR/issue-36122-accessing-externed-dst.rs:5:20
Expand Down
1 change: 1 addition & 0 deletions tests/ui/issues/issue-54410.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ LL | pub static mut symbol: [i8];
| ^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[i8]`
= note: statics and constants must have a statically known size

error: aborting due to 1 previous error

Expand Down
18 changes: 9 additions & 9 deletions tests/ui/layout/issue-84108.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42);
= help: the trait `Sized` is not implemented for `[u8]`
= note: only the last element of a tuple may have a dynamically sized type

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/issue-84108.rs:15:13
|
LL | static BAZ: ([u8], usize) = ([], 0);
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
= note: only the last element of a tuple may have a dynamically sized type

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/issue-84108.rs:9:12
|
Expand All @@ -48,15 +57,6 @@ LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42);
= note: expected slice `[u8]`
found array `[_; 0]`

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/issue-84108.rs:15:13
|
LL | static BAZ: ([u8], usize) = ([], 0);
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
= note: only the last element of a tuple may have a dynamically sized type

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/issue-84108.rs:15:13
|
Expand Down
Loading

0 comments on commit ba95435

Please sign in to comment.