Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check signature WF when lowering MIR body #137298

Merged
merged 3 commits into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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
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);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are body owners, so they'll be typeck'd like all other body owners later on.

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 @@ -1806,7 +1806,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 @@ -266,7 +266,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 @@ -3126,8 +3126,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
2 changes: 1 addition & 1 deletion tests/rustdoc-ui/issues/issue-79494.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

#![feature(const_transmute)]

const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; //~ ERROR cannot transmute between types of different sizes, or dependently-sized types
pub const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; //~ ERROR cannot transmute between types of different sizes, or dependently-sized types
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this pub?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so we can keep the error

6 changes: 3 additions & 3 deletions tests/rustdoc-ui/issues/issue-79494.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/issue-79494.rs:5:29
--> $DIR/issue-79494.rs:5:33
|
LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) };
| ^^^^^^^^^^^^^^^^^^^
LL | pub const ZST: &[u8] = unsafe { std::mem::transmute(1usize) };
| ^^^^^^^^^^^^^^^^^^^
|
= note: source type: `usize` (64 bits)
= note: target type: `&[u8]` (128 bits)
Expand Down
3 changes: 2 additions & 1 deletion tests/rustdoc-ui/track-diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@

struct A;
struct B;
const S: A = B;

pub const S: A = B;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A side-effect of this is that consts are only required to typeck if they're being documented.

Copy link
Contributor

@lcnr lcnr Mar 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in rustdoc

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh 💀 yes in roblox

4 changes: 2 additions & 2 deletions tests/rustdoc-ui/track-diagnostics.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0308]: mismatched types
--> $DIR/track-diagnostics.rs:LL:CC
|
LL | const S: A = B;
| ^ expected `A`, found `B`
LL | pub const S: A = B;
| ^ expected `A`, found `B`
-Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC

error: aborting due to 1 previous error
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
Loading
Loading