-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Taint the type of ill-formed (unsized) statics #144226
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
Changes from all commits
e70d213
6b4181f
8322078
ec81464
7c64961
8817572
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -14,6 +14,7 @@ use rustc_middle::{bug, span_bug}; | |||||||||||||
use rustc_span::{DUMMY_SP, Ident, Span}; | ||||||||||||||
|
||||||||||||||
use super::{HirPlaceholderCollector, ItemCtxt, bad_placeholder}; | ||||||||||||||
use crate::check::wfcheck::check_static_item; | ||||||||||||||
use crate::errors::TypeofReservedKeywordUsed; | ||||||||||||||
use crate::hir_ty_lowering::HirTyLowerer; | ||||||||||||||
|
||||||||||||||
|
@@ -217,7 +218,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ | |||||||||||||
"static variable", | ||||||||||||||
) | ||||||||||||||
} else { | ||||||||||||||
icx.lower_ty(ty) | ||||||||||||||
let ty = icx.lower_ty(ty); | ||||||||||||||
// MIR relies on references to statics being scalars. | ||||||||||||||
// Verify that here to avoid ill-formed MIR. | ||||||||||||||
match check_static_item(tcx, def_id, ty, false) { | ||||||||||||||
Comment on lines
+223
to
+224
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
Ok(()) => ty, | ||||||||||||||
Err(guar) => Ty::new_error(tcx, guar), | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
ItemKind::Const(ident, _, ty, body_id) => { | ||||||||||||||
|
@@ -275,7 +282,15 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ | |||||||||||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id); | ||||||||||||||
Ty::new_fn_def(tcx, def_id.to_def_id(), args) | ||||||||||||||
} | ||||||||||||||
ForeignItemKind::Static(t, _, _) => icx.lower_ty(t), | ||||||||||||||
ForeignItemKind::Static(ty, _, _) => { | ||||||||||||||
let ty = icx.lower_ty(ty); | ||||||||||||||
// MIR relies on references to statics being scalars. | ||||||||||||||
// Verify that here to avoid ill-formed MIR. | ||||||||||||||
match check_static_item(tcx, def_id, ty, false) { | ||||||||||||||
Comment on lines
+288
to
+289
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
Ok(()) => ty, | ||||||||||||||
Err(guar) => Ty::new_error(tcx, guar), | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
ForeignItemKind::Type => Ty::new_foreign(tcx, def_id.to_def_id()), | ||||||||||||||
}, | ||||||||||||||
|
||||||||||||||
|
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @oli-obk is it okay for this to cycle-error? Having the type of a static depend on its value does seem quite cursed.^^ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is a static's type meaningfully different from a function's return type? Because it's not about its evaluated value, but just how opaque types work. I don't think this use case is particularly unusual and expect people will want to be using TAITs like this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Hm... not really, the problem is just that the constraint on the type cannot be so easily expressed as a trait query. For return types it's |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -17,6 +17,7 @@ impl<F: Future> Task<F> { | |||||
} | ||||||
|
||||||
pub type F = impl Future; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Needing an extra annotation for an opaque type in a static item seems fine to me |
||||||
|
||||||
#[define_opaque(F)] | ||||||
fn foo() | ||||||
where | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
//! Regression test for #121176 | ||
//! KnownPanicsLint used to assert ABI compatibility in the interpreter, | ||
//! which ICEs with unsized statics. | ||
//@ needs-rustc-debug-assertions | ||
|
||
use std::fmt::Debug; | ||
|
||
static STATIC_1: dyn Debug + Sync = *(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For instance, this is a clearly ill-formed static. Nothing should ever look at its MIR. Trying to make the MIR interpreter APIs resistant against bogus MIR is a pointless game of whack-a-mole. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yea those cases are straight forward to prevent within There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That doesn't quite work since we allow extern statics that have extern types, which are unsized. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, we can check the tail manually for slices and dyn trait There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But that requires unfolding the type which will trigger the same cycle error, won't it? |
||
//~^ ERROR the size for values of type `(dyn Debug + Sync + 'static)` cannot be known | ||
//~| ERROR type `()` cannot be dereferenced | ||
|
||
fn main() { | ||
println!("{:?}", &STATIC_1); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time | ||
--> $DIR/static-by-value-dyn.rs:8:1 | ||
| | ||
LL | static STATIC_1: 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[E0614]: type `()` cannot be dereferenced | ||
--> $DIR/static-by-value-dyn.rs:8:37 | ||
| | ||
LL | static STATIC_1: dyn Debug + Sync = *(); | ||
| ^^^ can't be dereferenced | ||
|
||
error: aborting due to 2 previous errors | ||
|
||
Some errors have detailed explanations: E0277, E0614. | ||
For more information about an error, try `rustc --explain E0277`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
//! Regression test for #140332 | ||
//! KnownPanicsLint used to assert ABI compatibility in the interpreter, | ||
//! which ICEs with unsized statics. | ||
static mut S: [i8] = ["Some thing"; 1]; | ||
//~^ ERROR the size for values of type `[i8]` cannot be known | ||
|
||
fn main() { | ||
assert_eq!(S, [0; 1]); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
error[E0277]: the size for values of type `[i8]` cannot be known at compilation time | ||
--> $DIR/static-by-value-slice.rs:5:1 | ||
| | ||
LL | static mut S: [i8] = ["Some thing"; 1]; | ||
| ^^^^^^^^^^^^^^^^^^ 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 | ||
|
||
For more information about this error, try `rustc --explain E0277`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
//! Regression test for #139872 | ||
//! KnownPanicsLint used to assert ABI compatibility in the interpreter, | ||
//! which ICEs with unsized statics. | ||
enum E { | ||
V16(u16), | ||
V32(u32), | ||
} | ||
|
||
static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD); | ||
//~^ ERROR the size for values of type `str` cannot be known | ||
|
||
pub fn main() { | ||
let (_, n, _) = C; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
error[E0277]: the size for values of type `str` cannot be known at compilation time | ||
--> $DIR/static-by-value-str.rs:10:1 | ||
| | ||
LL | static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | ||
| | ||
= help: within `(E, u16, str)`, the trait `Sized` is not implemented for `str` | ||
= note: required because it appears within the type `(E, u16, str)` | ||
= note: statics and constants must have a statically known size | ||
|
||
error: aborting due to 1 previous error | ||
|
||
For more information about this error, try `rustc --explain E0277`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
//! Regression test for #129109 | ||
//! MIR building used to produce erroneous constants when referring to statics of unsized type. | ||
//@ compile-flags: -Zmir-enable-passes=+GVN -Zvalidate-mir | ||
|
||
extern "C" { | ||
pub static mut symbol: [i8]; | ||
//~^ ERROR the size for values of type `[i8]` | ||
} | ||
|
||
fn main() { | ||
println!("C", unsafe { &symbol }); | ||
//~^ ERROR argument never used | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.