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

Perform Sync check on static items in wf-check instead of during const checks #91251

Merged
merged 1 commit into from
Nov 28, 2021
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
29 changes: 2 additions & 27 deletions compiler/rustc_const_eval/src/transform/check_consts/check.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.

use rustc_errors::{Applicability, Diagnostic, ErrorReported};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, HirId, LangItem};
use rustc_index::bit_set::BitSet;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
Expand All @@ -14,8 +14,7 @@ use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty,
use rustc_middle::ty::{Binder, TraitPredicate, TraitRef};
use rustc_mir_dataflow::{self, Analysis};
use rustc_span::{sym, Span, Symbol};
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
use rustc_trait_selection::traits::{self, SelectionContext, TraitEngine};
use rustc_trait_selection::traits::SelectionContext;

use std::mem;
use std::ops::Deref;
Expand Down Expand Up @@ -255,16 +254,6 @@ impl Checker<'mir, 'tcx> {
self.visit_body(&body);
}

// Ensure that the end result is `Sync` in a non-thread local `static`.
let should_check_for_sync = self.const_kind()
== hir::ConstContext::Static(hir::Mutability::Not)
&& !tcx.is_thread_local_static(def_id.to_def_id());

if should_check_for_sync {
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
check_return_ty_is_sync(tcx, &body, hir_id);
}

// If we got through const-checking without emitting any "primary" errors, emit any
// "secondary" errors if they occurred.
let secondary_errors = mem::take(&mut self.secondary_errors);
Expand Down Expand Up @@ -1054,20 +1043,6 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
}
}

fn check_return_ty_is_sync(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, hir_id: HirId) {
let ty = body.return_ty();
tcx.infer_ctxt().enter(|infcx| {
let cause = traits::ObligationCause::new(body.span, hir_id, traits::SharedStatic);
let mut fulfillment_cx = traits::FulfillmentContext::new();
let sync_def_id = tcx.require_lang_item(LangItem::Sync, Some(body.span));
fulfillment_cx.register_bound(&infcx, ty::ParamEnv::empty(), ty, sync_def_id, cause);
let errors = fulfillment_cx.select_all_or_error(&infcx);
if !errors.is_empty() {
infcx.report_fulfillment_errors(&errors, None, false);
}
});
}

fn place_as_reborrow(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,20 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: LocalDefId, ty_span: Span, allow_fo
);
}

// Ensure that the end result is `Sync` in a non-thread local `static`.
let should_check_for_sync = tcx.static_mutability(item_id.to_def_id())
== Some(hir::Mutability::Not)
&& !tcx.is_foreign_item(item_id.to_def_id())
&& !tcx.is_thread_local_static(item_id.to_def_id());

if should_check_for_sync {
fcx.register_bound(
item_ty,
tcx.require_lang_item(LangItem::Sync, Some(ty_span)),
traits::ObligationCause::new(ty_span, fcx.body_id, traits::SharedStatic),
);
}

// No implied bounds in a const, etc.
FxHashSet::default()
});
Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/consts/const-cast-different-types.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
static a: &'static str = "foo";
static b: *const u8 = a as *const u8; //~ ERROR casting
static c: *const u8 = &a as *const u8; //~ ERROR casting
const a: &str = "foo";
const b: *const u8 = a as *const u8; //~ ERROR casting
const c: *const u8 = &a as *const u8; //~ ERROR casting

fn main() {
}
12 changes: 6 additions & 6 deletions src/test/ui/consts/const-cast-different-types.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
error[E0606]: casting `&'static str` as `*const u8` is invalid
--> $DIR/const-cast-different-types.rs:2:23
--> $DIR/const-cast-different-types.rs:2:22
|
LL | static b: *const u8 = a as *const u8;
| ^^^^^^^^^^^^^^
LL | const b: *const u8 = a as *const u8;
| ^^^^^^^^^^^^^^

error[E0606]: casting `&&'static str` as `*const u8` is invalid
--> $DIR/const-cast-different-types.rs:3:23
--> $DIR/const-cast-different-types.rs:3:22
|
LL | static c: *const u8 = &a as *const u8;
| ^^^^^^^^^^^^^^^
LL | const c: *const u8 = &a as *const u8;
| ^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/consts/const-cast-wrong-type.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
static a: [u8; 3] = ['h' as u8, 'i' as u8, 0 as u8];
static b: *const i8 = &a as *const i8; //~ ERROR mismatched types
const a: [u8; 3] = ['h' as u8, 'i' as u8, 0 as u8];
const b: *const i8 = &a as *const i8; //~ ERROR mismatched types

fn main() {
}
6 changes: 3 additions & 3 deletions src/test/ui/consts/const-cast-wrong-type.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0308]: mismatched types
--> $DIR/const-cast-wrong-type.rs:2:23
--> $DIR/const-cast-wrong-type.rs:2:22
|
LL | static b: *const i8 = &a as *const i8;
| ^^^^^^^^^^^^^^^ expected `u8`, found `i8`
LL | const b: *const i8 = &a as *const i8;
| ^^^^^^^^^^^^^^^ expected `u8`, found `i8`

error: aborting due to previous error

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/impl-trait/issues/issue-86201.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
#![feature(type_alias_impl_trait)]

type FunType = impl Fn<()>;
//~^ could not find defining uses
//~^ ERROR could not find defining uses
static STATIC_FN: FunType = some_fn;
//~^ mismatched types
//~^ ERROR mismatched types

fn some_fn() {}

Expand Down
29 changes: 14 additions & 15 deletions src/test/ui/issues/issue-16538.mir.stderr
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
--> $DIR/issue-16538.rs:14:27
--> $DIR/issue-16538.rs:15:23
|
LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: `*const usize` cannot be shared between threads safely
--> $DIR/issue-16538.rs:14:1
error[E0133]: use of extern static is unsafe and requires unsafe function or block
--> $DIR/issue-16538.rs:15:30
|
LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const usize` cannot be shared between threads safely
LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
| ^^^^ use of extern static
|
= help: the trait `Sync` is not implemented for `*const usize`
= note: shared static variables must have a type that implements `Sync`
= note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior

error[E0133]: use of extern static is unsafe and requires unsafe function or block
--> $DIR/issue-16538.rs:14:34
error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
--> $DIR/issue-16538.rs:15:21
|
LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
| ^^^^ use of extern static
LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereference of raw pointer
|
= note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
= note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0015, E0133, E0277.
Some errors have detailed explanations: E0015, E0133.
For more information about an error, try `rustc --explain E0015`.
5 changes: 3 additions & 2 deletions src/test/ui/issues/issue-16538.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// revisions: mir thir
// [thir]compile-flags: -Z thir-unsafeck

#![feature(const_raw_ptr_deref)]
mod Y {
pub type X = usize;
extern "C" {
Expand All @@ -11,8 +12,8 @@ mod Y {
}
}

static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
//~^ ERROR `*const usize` cannot be shared between threads safely [E0277]
static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
//~^ ERROR dereference of raw pointer
//~| ERROR E0015
//~| ERROR use of extern static is unsafe and requires

Expand Down
31 changes: 15 additions & 16 deletions src/test/ui/issues/issue-16538.thir.stderr
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
--> $DIR/issue-16538.rs:15:22
|
LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereference of raw pointer
|
= note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior

error[E0133]: use of extern static is unsafe and requires unsafe function or block
--> $DIR/issue-16538.rs:14:34
--> $DIR/issue-16538.rs:15:30
|
LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
| ^^^^ use of extern static
LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
| ^^^^ use of extern static
|
= note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior

error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
--> $DIR/issue-16538.rs:14:27
|
LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: `*const usize` cannot be shared between threads safely
--> $DIR/issue-16538.rs:14:1
|
LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const usize` cannot be shared between threads safely
--> $DIR/issue-16538.rs:15:23
|
= help: the trait `Sync` is not implemented for `*const usize`
= note: shared static variables must have a type that implements `Sync`
LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0015, E0133, E0277.
Some errors have detailed explanations: E0015, E0133.
For more information about an error, try `rustc --explain E0015`.
4 changes: 2 additions & 2 deletions src/test/ui/issues/issue-17718-static-sync.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: `Foo` cannot be shared between threads safely
--> $DIR/issue-17718-static-sync.rs:9:1
--> $DIR/issue-17718-static-sync.rs:9:13
|
LL | static BAR: Foo = Foo;
| ^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be shared between threads safely
| ^^^ `Foo` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `Foo`
= note: shared static variables must have a type that implements `Sync`
Expand Down
1 change: 1 addition & 0 deletions src/test/ui/issues/issue-24446.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
fn main() {
static foo: dyn Fn() -> u32 = || -> u32 {
//~^ ERROR the size for values of type
//~| ERROR cannot be shared between threads safely
0
};
}
11 changes: 10 additions & 1 deletion src/test/ui/issues/issue-24446.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ LL | static foo: dyn Fn() -> u32 = || -> u32 {
|
= help: the trait `Sized` is not implemented for `(dyn Fn() -> u32 + 'static)`

error: aborting due to previous error
error[E0277]: `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely
--> $DIR/issue-24446.rs:2:17
|
LL | static foo: dyn Fn() -> u32 = || -> u32 {
| ^^^^^^^^^^^^^^^ `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `(dyn Fn() -> u32 + 'static)`
= note: shared static variables must have a type that implements `Sync`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
4 changes: 2 additions & 2 deletions src/test/ui/issues/issue-5216.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
fn f() { }
struct S(Box<dyn FnMut()>);
struct S(Box<dyn FnMut() + Sync>);
pub static C: S = S(f); //~ ERROR mismatched types


fn g() { }
type T = Box<dyn FnMut()>;
type T = Box<dyn FnMut() + Sync>;
pub static D: T = g; //~ ERROR mismatched types

fn main() {}
4 changes: 2 additions & 2 deletions src/test/ui/issues/issue-5216.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error[E0308]: mismatched types
LL | pub static C: S = S(f);
| ^ expected struct `Box`, found fn item
|
= note: expected struct `Box<(dyn FnMut() + 'static)>`
= note: expected struct `Box<(dyn FnMut() + Sync + 'static)>`
found fn item `fn() {f}`

error[E0308]: mismatched types
Expand All @@ -13,7 +13,7 @@ error[E0308]: mismatched types
LL | pub static D: T = g;
| ^ expected struct `Box`, found fn item
|
= note: expected struct `Box<(dyn FnMut() + 'static)>`
= note: expected struct `Box<(dyn FnMut() + Sync + 'static)>`
found fn item `fn() {g}`

error: aborting due to 2 previous errors
Expand Down
3 changes: 1 addition & 2 deletions src/test/ui/issues/issue-7364.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::cell::RefCell;

// Regression test for issue 7364
static boxed: Box<RefCell<isize>> = box RefCell::new(0);
//~^ ERROR allocations are not allowed in statics
//~| ERROR `RefCell<isize>` cannot be shared between threads safely [E0277]
//~^ ERROR `RefCell<isize>` cannot be shared between threads safely [E0277]

fn main() { }
15 changes: 4 additions & 11 deletions src/test/ui/issues/issue-7364.stderr
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
error[E0010]: allocations are not allowed in statics
--> $DIR/issue-7364.rs:6:37
|
LL | static boxed: Box<RefCell<isize>> = box RefCell::new(0);
| ^^^^^^^^^^^^^^^^^^^ allocation not allowed in statics

error[E0277]: `RefCell<isize>` cannot be shared between threads safely
--> $DIR/issue-7364.rs:6:1
--> $DIR/issue-7364.rs:6:15
|
LL | static boxed: Box<RefCell<isize>> = box RefCell::new(0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `RefCell<isize>` cannot be shared between threads safely
| ^^^^^^^^^^^^^^^^^^^ `RefCell<isize>` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `RefCell<isize>`
= note: required because of the requirements on the impl of `Sync` for `Unique<RefCell<isize>>`
= note: required because it appears within the type `Box<RefCell<isize>>`
= note: shared static variables must have a type that implements `Sync`

error: aborting due to 2 previous errors
error: aborting due to previous error

Some errors have detailed explanations: E0010, E0277.
For more information about an error, try `rustc --explain E0010`.
For more information about this error, try `rustc --explain E0277`.
Loading