Skip to content

Commit 1869412

Browse files
committed
Perform Sync check on static items in wf-check instead of during const checks
1 parent 1e79d79 commit 1869412

22 files changed

+103
-134
lines changed

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+2-27
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.
22
33
use rustc_errors::{Applicability, Diagnostic, ErrorReported};
4+
use rustc_hir as hir;
45
use rustc_hir::def_id::DefId;
5-
use rustc_hir::{self as hir, HirId, LangItem};
66
use rustc_index::bit_set::BitSet;
77
use rustc_infer::infer::TyCtxtInferExt;
88
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
@@ -14,8 +14,7 @@ use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty,
1414
use rustc_middle::ty::{Binder, TraitPredicate, TraitRef};
1515
use rustc_mir_dataflow::{self, Analysis};
1616
use rustc_span::{sym, Span, Symbol};
17-
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
18-
use rustc_trait_selection::traits::{self, SelectionContext, TraitEngine};
17+
use rustc_trait_selection::traits::SelectionContext;
1918

2019
use std::mem;
2120
use std::ops::Deref;
@@ -255,16 +254,6 @@ impl Checker<'mir, 'tcx> {
255254
self.visit_body(&body);
256255
}
257256

258-
// Ensure that the end result is `Sync` in a non-thread local `static`.
259-
let should_check_for_sync = self.const_kind()
260-
== hir::ConstContext::Static(hir::Mutability::Not)
261-
&& !tcx.is_thread_local_static(def_id.to_def_id());
262-
263-
if should_check_for_sync {
264-
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
265-
check_return_ty_is_sync(tcx, &body, hir_id);
266-
}
267-
268257
// If we got through const-checking without emitting any "primary" errors, emit any
269258
// "secondary" errors if they occurred.
270259
let secondary_errors = mem::take(&mut self.secondary_errors);
@@ -1054,20 +1043,6 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
10541043
}
10551044
}
10561045

1057-
fn check_return_ty_is_sync(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, hir_id: HirId) {
1058-
let ty = body.return_ty();
1059-
tcx.infer_ctxt().enter(|infcx| {
1060-
let cause = traits::ObligationCause::new(body.span, hir_id, traits::SharedStatic);
1061-
let mut fulfillment_cx = traits::FulfillmentContext::new();
1062-
let sync_def_id = tcx.require_lang_item(LangItem::Sync, Some(body.span));
1063-
fulfillment_cx.register_bound(&infcx, ty::ParamEnv::empty(), ty, sync_def_id, cause);
1064-
let errors = fulfillment_cx.select_all_or_error(&infcx);
1065-
if !errors.is_empty() {
1066-
infcx.report_fulfillment_errors(&errors, None, false);
1067-
}
1068-
});
1069-
}
1070-
10711046
fn place_as_reborrow(
10721047
tcx: TyCtxt<'tcx>,
10731048
body: &Body<'tcx>,

compiler/rustc_typeck/src/check/wfcheck.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,20 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: LocalDefId, ty_span: Span, allow_fo
10601060
);
10611061
}
10621062

1063+
// Ensure that the end result is `Sync` in a non-thread local `static`.
1064+
let should_check_for_sync = tcx.static_mutability(item_id.to_def_id())
1065+
== Some(hir::Mutability::Not)
1066+
&& !tcx.is_foreign_item(item_id.to_def_id())
1067+
&& !tcx.is_thread_local_static(item_id.to_def_id());
1068+
1069+
if should_check_for_sync {
1070+
fcx.register_bound(
1071+
item_ty,
1072+
tcx.require_lang_item(LangItem::Sync, Some(ty_span)),
1073+
traits::ObligationCause::new(ty_span, fcx.body_id, traits::SharedStatic),
1074+
);
1075+
}
1076+
10631077
// No implied bounds in a const, etc.
10641078
FxHashSet::default()
10651079
});
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
static a: &'static str = "foo";
2-
static b: *const u8 = a as *const u8; //~ ERROR casting
3-
static c: *const u8 = &a as *const u8; //~ ERROR casting
1+
const a: &str = "foo";
2+
const b: *const u8 = a as *const u8; //~ ERROR casting
3+
const c: *const u8 = &a as *const u8; //~ ERROR casting
44

55
fn main() {
66
}

src/test/ui/consts/const-cast-different-types.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
error[E0606]: casting `&'static str` as `*const u8` is invalid
2-
--> $DIR/const-cast-different-types.rs:2:23
2+
--> $DIR/const-cast-different-types.rs:2:22
33
|
4-
LL | static b: *const u8 = a as *const u8;
5-
| ^^^^^^^^^^^^^^
4+
LL | const b: *const u8 = a as *const u8;
5+
| ^^^^^^^^^^^^^^
66

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

1313
error: aborting due to 2 previous errors
1414

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
static a: [u8; 3] = ['h' as u8, 'i' as u8, 0 as u8];
2-
static b: *const i8 = &a as *const i8; //~ ERROR mismatched types
1+
const a: [u8; 3] = ['h' as u8, 'i' as u8, 0 as u8];
2+
const b: *const i8 = &a as *const i8; //~ ERROR mismatched types
33

44
fn main() {
55
}

src/test/ui/consts/const-cast-wrong-type.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0308]: mismatched types
2-
--> $DIR/const-cast-wrong-type.rs:2:23
2+
--> $DIR/const-cast-wrong-type.rs:2:22
33
|
4-
LL | static b: *const i8 = &a as *const i8;
5-
| ^^^^^^^^^^^^^^^ expected `u8`, found `i8`
4+
LL | const b: *const i8 = &a as *const i8;
5+
| ^^^^^^^^^^^^^^^ expected `u8`, found `i8`
66

77
error: aborting due to previous error
88

src/test/ui/impl-trait/issues/issue-86201.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
#![feature(type_alias_impl_trait)]
33

44
type FunType = impl Fn<()>;
5-
//~^ could not find defining uses
5+
//~^ ERROR could not find defining uses
66
static STATIC_FN: FunType = some_fn;
7-
//~^ mismatched types
7+
//~^ ERROR mismatched types
88

99
fn some_fn() {}
1010

+14-15
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
2-
--> $DIR/issue-16538.rs:14:27
2+
--> $DIR/issue-16538.rs:15:23
33
|
4-
LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
66

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

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

2423
error: aborting due to 3 previous errors
2524

26-
Some errors have detailed explanations: E0015, E0133, E0277.
25+
Some errors have detailed explanations: E0015, E0133.
2726
For more information about an error, try `rustc --explain E0015`.

src/test/ui/issues/issue-16538.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// revisions: mir thir
22
// [thir]compile-flags: -Z thir-unsafeck
33

4+
#![feature(const_raw_ptr_deref)]
45
mod Y {
56
pub type X = usize;
67
extern "C" {
@@ -11,8 +12,8 @@ mod Y {
1112
}
1213
}
1314

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

+15-16
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
1+
error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
2+
--> $DIR/issue-16538.rs:15:22
3+
|
4+
LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereference of raw pointer
6+
|
7+
= note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
8+
19
error[E0133]: use of extern static is unsafe and requires unsafe function or block
2-
--> $DIR/issue-16538.rs:14:34
10+
--> $DIR/issue-16538.rs:15:30
311
|
4-
LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
5-
| ^^^^ use of extern static
12+
LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
13+
| ^^^^ use of extern static
614
|
715
= note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
816

917
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
10-
--> $DIR/issue-16538.rs:14:27
11-
|
12-
LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
13-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
14-
15-
error[E0277]: `*const usize` cannot be shared between threads safely
16-
--> $DIR/issue-16538.rs:14:1
17-
|
18-
LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
19-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const usize` cannot be shared between threads safely
18+
--> $DIR/issue-16538.rs:15:23
2019
|
21-
= help: the trait `Sync` is not implemented for `*const usize`
22-
= note: shared static variables must have a type that implements `Sync`
20+
LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
2322

2423
error: aborting due to 3 previous errors
2524

26-
Some errors have detailed explanations: E0015, E0133, E0277.
25+
Some errors have detailed explanations: E0015, E0133.
2726
For more information about an error, try `rustc --explain E0015`.

src/test/ui/issues/issue-17718-static-sync.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: `Foo` cannot be shared between threads safely
2-
--> $DIR/issue-17718-static-sync.rs:9:1
2+
--> $DIR/issue-17718-static-sync.rs:9:13
33
|
44
LL | static BAR: Foo = Foo;
5-
| ^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be shared between threads safely
5+
| ^^^ `Foo` cannot be shared between threads safely
66
|
77
= help: the trait `Sync` is not implemented for `Foo`
88
= note: shared static variables must have a type that implements `Sync`

src/test/ui/issues/issue-24446.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
fn main() {
22
static foo: dyn Fn() -> u32 = || -> u32 {
33
//~^ ERROR the size for values of type
4+
//~| ERROR cannot be shared between threads safely
45
0
56
};
67
}

src/test/ui/issues/issue-24446.stderr

+10-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ LL | static foo: dyn Fn() -> u32 = || -> u32 {
66
|
77
= help: the trait `Sized` is not implemented for `(dyn Fn() -> u32 + 'static)`
88

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

1120
For more information about this error, try `rustc --explain E0277`.

src/test/ui/issues/issue-5216.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
fn f() { }
2-
struct S(Box<dyn FnMut()>);
2+
struct S(Box<dyn FnMut() + Sync>);
33
pub static C: S = S(f); //~ ERROR mismatched types
44

55

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

1010
fn main() {}

src/test/ui/issues/issue-5216.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0308]: mismatched types
44
LL | pub static C: S = S(f);
55
| ^ expected struct `Box`, found fn item
66
|
7-
= note: expected struct `Box<(dyn FnMut() + 'static)>`
7+
= note: expected struct `Box<(dyn FnMut() + Sync + 'static)>`
88
found fn item `fn() {f}`
99

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

1919
error: aborting due to 2 previous errors

src/test/ui/issues/issue-7364.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::cell::RefCell;
44

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

109
fn main() { }

src/test/ui/issues/issue-7364.stderr

+4-11
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
1-
error[E0010]: allocations are not allowed in statics
2-
--> $DIR/issue-7364.rs:6:37
3-
|
4-
LL | static boxed: Box<RefCell<isize>> = box RefCell::new(0);
5-
| ^^^^^^^^^^^^^^^^^^^ allocation not allowed in statics
6-
71
error[E0277]: `RefCell<isize>` cannot be shared between threads safely
8-
--> $DIR/issue-7364.rs:6:1
2+
--> $DIR/issue-7364.rs:6:15
93
|
104
LL | static boxed: Box<RefCell<isize>> = box RefCell::new(0);
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `RefCell<isize>` cannot be shared between threads safely
5+
| ^^^^^^^^^^^^^^^^^^^ `RefCell<isize>` cannot be shared between threads safely
126
|
137
= help: the trait `Sync` is not implemented for `RefCell<isize>`
148
= note: required because of the requirements on the impl of `Sync` for `Unique<RefCell<isize>>`
159
= note: required because it appears within the type `Box<RefCell<isize>>`
1610
= note: shared static variables must have a type that implements `Sync`
1711

18-
error: aborting due to 2 previous errors
12+
error: aborting due to previous error
1913

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

0 commit comments

Comments
 (0)