Skip to content

Commit

Permalink
Auto merge of rust-lang#137233 - compiler-errors:sized, r=<try>
Browse files Browse the repository at this point in the history
Unconditionally check sizedness of body in typeck to taint typeck results

Puts the sized check back into typeck (duplicated -- we still have it in wfcheck) so that we properly taint bodies. These duplicated diagnostics will all be deduplicated with `-Zdeduplicate-diagnostics`, so it's just UI test fallout and not an actual regression in user-facing diagnostics.

We could perhaps do this without duplicating all the diagnostics if we put this check into something like mir build 🤔 Ideally CTFE would just be more fallible to non-WF code but 🤷

Fixes rust-lang#137186
  • Loading branch information
bors committed Feb 19, 2025
2 parents 5986ff0 + a0dbaf2 commit 9183270
Show file tree
Hide file tree
Showing 56 changed files with 799 additions and 160 deletions.
14 changes: 11 additions & 3 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1110,7 +1110,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 @@ -1356,7 +1362,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 @@ -1700,6 +1706,7 @@ fn check_fn_or_method<'tcx>(
hir::FnRetTy::Return(ty) => Some(ty.span),
hir::FnRetTy::DefaultReturn(_) => None,
},
ObligationCauseCode::SizedReturnType,
);
}

Expand All @@ -1708,13 +1715,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
23 changes: 10 additions & 13 deletions compiler/rustc_hir_typeck/src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,19 +113,16 @@ pub(super) fn check_fn<'a, 'tcx>(

fcx.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);

// We checked the root's ret ty during wfcheck, but not the child.
if fcx.tcx.is_typeck_child(fn_def_id.to_def_id()) {
let return_or_body_span = match decl.output {
hir::FnRetTy::DefaultReturn(_) => body.value.span,
hir::FnRetTy::Return(ty) => ty.span,
};

fcx.require_type_is_sized(
declared_ret_ty,
return_or_body_span,
ObligationCauseCode::SizedReturnType,
);
}
let return_or_body_span = match decl.output {
hir::FnRetTy::DefaultReturn(_) => body.value.span,
hir::FnRetTy::Return(ty) => ty.span,
};

fcx.require_type_is_sized(
declared_ret_ty,
return_or_body_span,
ObligationCauseCode::SizedReturnType,
);

fcx.is_whole_body.set(true);
fcx.check_return_or_body_tail(body.value, false);
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
5 changes: 5 additions & 0 deletions compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@ fn typeck_with_inspect<'tcx>(

let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id)));
fcx.register_wf_obligation(expected_type.into(), body.value.span, wf_code);
fcx.require_type_is_sized(
expected_type,
node.ty().map_or(body.value.span, |ty| ty.span),
ObligationCauseCode::SizedConstOrStatic,
);

// Gather locals in statics (because of block expressions).
GatherLocalsVisitor::new(&fcx).visit_body(body);
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 @@ -273,7 +273,7 @@ pub enum ObligationCauseCode<'tcx> {
},

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

/// `static` items must have `Sync` type.
SharedStatic,
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
1 change: 1 addition & 0 deletions tests/ui/associated-consts/issue-58022.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ impl Bar<[u8]> {

fn new(slice: &[u8; Self::SIZE]) -> Self {
//~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time
//~| ERROR: the size for values of type `[u8]` cannot be known at compilation time
Foo(Box::new(*slice))
//~^ ERROR: expected function, tuple struct or tuple variant, found trait `Foo`
}
Expand Down
19 changes: 17 additions & 2 deletions tests/ui/associated-consts/issue-58022.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,28 @@ LL |
LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
| ^^^^^^^^^ cannot refer to the associated constant of trait

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/issue-58022.rs:13:41
|
LL | fn new(slice: &[u8; Self::SIZE]) -> Self {
| ^^^^ doesn't have a size known at compile-time
|
= help: within `Bar<[u8]>`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `Bar<[u8]>`
--> $DIR/issue-58022.rs:8:12
|
LL | pub struct Bar<T: ?Sized>(T);
| ^^^
= note: the return type of a function must have a statically known size
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0423]: expected function, tuple struct or tuple variant, found trait `Foo`
--> $DIR/issue-58022.rs:15:9
--> $DIR/issue-58022.rs:16:9
|
LL | Foo(Box::new(*slice))
| ^^^ not a function, tuple struct or tuple variant

error: aborting due to 3 previous errors
error: aborting due to 4 previous errors

Some errors have detailed explanations: E0277, E0423, E0790.
For more information about an error, try `rustc --explain E0277`.
1 change: 1 addition & 0 deletions tests/ui/consts/const-slice-array-deref.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const ONE: [u16] = [1];
//~^ ERROR the size for values of type `[u16]` cannot be known at compilation time
//~| ERROR the size for values of type `[u16]` cannot be known at compilation time
//~| ERROR mismatched types

const TWO: &'static u16 = &ONE[0];
Expand Down
15 changes: 13 additions & 2 deletions tests/ui/consts/const-slice-array-deref.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,31 @@ 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
|
LL | const ONE: [u16] = [1];
| ^^^ expected `[u16]`, found `[u16; 1]`

error[E0277]: the size for values of type `[u16]` cannot be known at compilation time
--> $DIR/const-slice-array-deref.rs:1:12
|
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
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0161]: cannot move a value of type `[u16]`
--> $DIR/const-slice-array-deref.rs:5:28
--> $DIR/const-slice-array-deref.rs:6:28
|
LL | const TWO: &'static u16 = &ONE[0];
| ^^^ the size of `[u16]` cannot be statically determined

error: aborting due to 3 previous errors
error: aborting due to 4 previous errors

Some errors have detailed explanations: E0161, E0277, E0308.
For more information about an error, try `rustc --explain E0161`.
8 changes: 4 additions & 4 deletions tests/ui/consts/const-unsized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ use std::fmt::Debug;

const CONST_0: dyn Debug + Sync = *(&0 as &(dyn Debug + Sync));
//~^ ERROR the size for values of type
//~| ERROR cannot move out of a shared reference
//~| ERROR the size for values of type

const CONST_FOO: str = *"foo";
//~^ ERROR the size for values of type
//~| ERROR cannot move out of a shared reference
//~| ERROR the size for values of type

static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
//~^ ERROR the size for values of type
//~| ERROR cannot move out of a shared reference
//~| ERROR the size for values of type

static STATIC_BAR: str = *"bar";
//~^ ERROR the size for values of type
//~| ERROR cannot move out of a shared reference
//~| ERROR the size for values of type

fn main() {
println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR);
Expand Down
64 changes: 42 additions & 22 deletions tests/ui/consts/const-unsized.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ 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 `(dyn Debug + Sync + 'static)` cannot be known at compilation time
--> $DIR/const-unsized.rs:3:16
|
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
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

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 +24,26 @@ 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 `str` cannot be known at compilation time
--> $DIR/const-unsized.rs:7:18
|
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
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time
--> $DIR/const-unsized.rs:11:18
|
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 `(dyn Debug + Sync + 'static)` cannot be known at compilation time
--> $DIR/const-unsized.rs:11:18
Expand All @@ -21,6 +52,8 @@ 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
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/const-unsized.rs:15:20
Expand All @@ -29,30 +62,17 @@ 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
|
LL | const CONST_0: dyn Debug + Sync = *(&0 as &(dyn Debug + Sync));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `dyn Debug + Sync`, which does not implement the `Copy` trait

error[E0507]: cannot move out of a shared reference
--> $DIR/const-unsized.rs:7:24
|
LL | const CONST_FOO: str = *"foo";
| ^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait

error[E0507]: cannot move out of a shared reference
--> $DIR/const-unsized.rs:11:37
|
LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `dyn Debug + Sync`, which does not implement the `Copy` trait

error[E0507]: cannot move out of a shared reference
--> $DIR/const-unsized.rs:15:26
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/const-unsized.rs:15:20
|
LL | static STATIC_BAR: str = *"bar";
| ^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait
| ^^^ 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
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0161]: cannot move a value of type `str`
--> $DIR/const-unsized.rs:20:48
Expand All @@ -68,5 +88,5 @@ LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATI

error: aborting due to 10 previous errors

Some errors have detailed explanations: E0161, E0277, E0507.
Some errors have detailed explanations: E0161, E0277.
For more information about an error, try `rustc --explain E0161`.
2 changes: 2 additions & 0 deletions tests/ui/consts/const_refs_to_static-ice-121413.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ const REF_INTERIOR_MUT: &usize = {
//~^ ERROR failed to resolve: use of undeclared type `AtomicUsize`
//~| WARN trait objects without an explicit `dyn` are deprecated
//~| ERROR the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time
//~| ERROR the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time
//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
//~| HELP if this is a dyn-compatible trait, use `dyn`
//~| HELP the trait `Sized` is not implemented for `(dyn Sync + 'static)`
//~| HELP the trait `Sized` is not implemented for `(dyn Sync + 'static)`
unsafe { &*(&FOO as *const _ as *const usize) }
};
pub fn main() {}
13 changes: 12 additions & 1 deletion tests/ui/consts/const_refs_to_static-ice-121413.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,19 @@ 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
error[E0277]: the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time
--> $DIR/const_refs_to_static-ice-121413.rs:8:17
|
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
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

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

Some errors have detailed explanations: E0277, E0433.
For more information about an error, try `rustc --explain E0277`.
9 changes: 9 additions & 0 deletions tests/ui/consts/unsized.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
static S: str = todo!();
//~^ ERROR the size for values of type `str` cannot be known at compilation time
//~| ERROR the size for values of type `str` cannot be known at compilation time

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

fn main() {}
Loading

0 comments on commit 9183270

Please sign in to comment.