Skip to content

Rollup of 7 pull requests #71230

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

Merged
merged 23 commits into from
Apr 17, 2020
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0a54a94
Added FuseIteratorImpl, FustDoubleEndedIteratorImpl and FuseExactSize…
rakshith-ravi Apr 8, 2020
51cd29c
Added comments.
rakshith-ravi Apr 10, 2020
908436f
Add proper explanation of error code E0657
Polkaverse Mar 30, 2020
9ee4d1a
reword Miri validity errors: undefined -> uninitialized
RalfJung Apr 15, 2020
abe5973
Inlined everything into a single trait and trait impl
rakshith-ravi Apr 15, 2020
0d01ce6
switch back to 'bytes'
RalfJung Apr 16, 2020
69423bf
test fast path offset reporting
RalfJung Apr 16, 2020
18d0907
Miri error messages: avoid try terminology
RalfJung Apr 16, 2020
250b27d
bikeshed
RalfJung Apr 16, 2020
2edd123
Dogfood or_patterns in the standard library
cuviper Apr 16, 2020
9fb3f55
Add test for issue-24843
JohnTitor Apr 16, 2020
077a7f7
Add test for issue-28575
JohnTitor Apr 16, 2020
119bbbe
Add test for issue-54067
JohnTitor Apr 16, 2020
0b85356
Add test for issue-67893
JohnTitor Apr 16, 2020
a6855b9
Avoid emitting stderr for now
JohnTitor Apr 16, 2020
da48550
Fix typo in Default trait docs: Provides -> Provide
leocassarani Apr 16, 2020
abd72f7
Rollup merge of #70578 - PankajChaudhary5:master, r=GuillaumeGomez
Dylan-DPC Apr 17, 2020
d194587
Rollup merge of #70910 - rakshith-ravi:master, r=cuviper
Dylan-DPC Apr 17, 2020
5280d15
Rollup merge of #71164 - RalfJung:uninit-not-undef, r=oli-obk
Dylan-DPC Apr 17, 2020
b347097
Rollup merge of #71182 - JohnTitor:regression-tests, r=Mark-Simulacrum
Dylan-DPC Apr 17, 2020
b2e4d48
Rollup merge of #71206 - RalfJung:dont-try, r=oli-obk
Dylan-DPC Apr 17, 2020
28964b4
Rollup merge of #71220 - cuviper:std_or_patterns, r=Mark-Simulacrum
Dylan-DPC Apr 17, 2020
65243a8
Rollup merge of #71225 - leocassarani:patch-1, r=jonas-schievink
Dylan-DPC Apr 17, 2020
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 src/liballoc/collections/btree/map.rs
Original file line number Diff line number Diff line change
@@ -2058,12 +2058,7 @@ where
(Excluded(s), Excluded(e)) if s == e => {
panic!("range start and end are equal and excluded in BTreeMap")
}
(Included(s), Included(e))
| (Included(s), Excluded(e))
| (Excluded(s), Included(e))
| (Excluded(s), Excluded(e))
if s > e =>
{
(Included(s) | Excluded(s), Included(e) | Excluded(e)) if s > e => {
panic!("range start is greater than range end in BTreeMap")
}
_ => {}
1 change: 1 addition & 0 deletions src/liballoc/lib.rs
Original file line number Diff line number Diff line change
@@ -103,6 +103,7 @@
#![feature(new_uninit)]
#![feature(nll)]
#![feature(optin_builtin_traits)]
#![feature(or_patterns)]
#![feature(pattern)]
#![feature(ptr_internals)]
#![feature(ptr_offset_from)]
4 changes: 2 additions & 2 deletions src/libcore/cmp.rs
Original file line number Diff line number Diff line change
@@ -858,7 +858,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn le(&self, other: &Rhs) -> bool {
matches!(self.partial_cmp(other), Some(Less) | Some(Equal))
matches!(self.partial_cmp(other), Some(Less | Equal))
}

/// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
@@ -895,7 +895,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn ge(&self, other: &Rhs) -> bool {
matches!(self.partial_cmp(other), Some(Greater) | Some(Equal))
matches!(self.partial_cmp(other), Some(Greater | Equal))
}
}

2 changes: 1 addition & 1 deletion src/libcore/default.rs
Original file line number Diff line number Diff line change
@@ -54,7 +54,7 @@
///
/// ## How can I implement `Default`?
///
/// Provides an implementation for the `default()` method that returns the value of
/// Provide an implementation for the `default()` method that returns the value of
/// your type that should be the default:
///
/// ```
307 changes: 244 additions & 63 deletions src/libcore/iter/adapters/fuse.rs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/libcore/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
@@ -3109,7 +3109,7 @@ pub trait Iterator {
Self::Item: PartialOrd<I::Item>,
Self: Sized,
{
matches!(self.partial_cmp(other), Some(Ordering::Less) | Some(Ordering::Equal))
matches!(self.partial_cmp(other), Some(Ordering::Less | Ordering::Equal))
}

/// Determines if the elements of this `Iterator` are lexicographically
@@ -3149,7 +3149,7 @@ pub trait Iterator {
Self::Item: PartialOrd<I::Item>,
Self: Sized,
{
matches!(self.partial_cmp(other), Some(Ordering::Greater) | Some(Ordering::Equal))
matches!(self.partial_cmp(other), Some(Ordering::Greater | Ordering::Equal))
}

/// Checks if the elements of this iterator are sorted.
1 change: 1 addition & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
@@ -105,6 +105,7 @@
#![feature(exhaustive_patterns)]
#![feature(no_core)]
#![feature(optin_builtin_traits)]
#![feature(or_patterns)]
#![feature(prelude_import)]
#![feature(repr_simd, platform_intrinsics)]
#![feature(rustc_attrs)]
4 changes: 2 additions & 2 deletions src/libcore/num/dec2flt/parse.rs
Original file line number Diff line number Diff line change
@@ -54,7 +54,7 @@ pub fn parse_decimal(s: &str) -> ParseResult<'_> {

match s.first() {
None => Valid(Decimal::new(integral, b"", 0)),
Some(&b'e') | Some(&b'E') => {
Some(&b'e' | &b'E') => {
if integral.is_empty() {
return Invalid; // No digits before 'e'
}
@@ -70,7 +70,7 @@ pub fn parse_decimal(s: &str) -> ParseResult<'_> {

match s.first() {
None => Valid(Decimal::new(integral, fractional, 0)),
Some(&b'e') | Some(&b'E') => parse_exp(integral, fractional, &s[1..]),
Some(&b'e' | &b'E') => parse_exp(integral, fractional, &s[1..]),
_ => Invalid, // Trailing junk after fractional part
}
}
4 changes: 2 additions & 2 deletions src/libcore/num/flt2dec/mod.rs
Original file line number Diff line number Diff line change
@@ -422,14 +422,14 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static
"+"
}
}
(_, Sign::Minus) | (_, Sign::MinusRaw) => {
(_, Sign::Minus | Sign::MinusRaw) => {
if negative {
"-"
} else {
""
}
}
(_, Sign::MinusPlus) | (_, Sign::MinusPlusRaw) => {
(_, Sign::MinusPlus | Sign::MinusPlusRaw) => {
if negative {
"-"
} else {
2 changes: 1 addition & 1 deletion src/librustc_error_codes/error_codes.rs
Original file line number Diff line number Diff line change
@@ -366,6 +366,7 @@ E0644: include_str!("./error_codes/E0644.md"),
E0646: include_str!("./error_codes/E0646.md"),
E0647: include_str!("./error_codes/E0647.md"),
E0648: include_str!("./error_codes/E0648.md"),
E0657: include_str!("./error_codes/E0657.md"),
E0658: include_str!("./error_codes/E0658.md"),
E0659: include_str!("./error_codes/E0659.md"),
E0660: include_str!("./error_codes/E0660.md"),
@@ -597,7 +598,6 @@ E0751: include_str!("./error_codes/E0751.md"),
// used in argument position
E0640, // infer outlives requirements
// E0645, // trait aliases not finished
E0657, // `impl Trait` can only capture lifetimes bound at the fn level
E0667, // `impl Trait` in projections
E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
57 changes: 57 additions & 0 deletions src/librustc_error_codes/error_codes/E0657.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
A lifetime bound on a trait implementation was captured at an incorrect place.

Erroneous code example:

```compile_fail,E0657
trait Id<T> {}
trait Lt<'a> {}
impl<'a> Lt<'a> for () {}
impl<T> Id<T> for T {}
fn free_fn_capture_hrtb_in_impl_trait()
-> Box<for<'a> Id<impl Lt<'a>>> // error!
{
Box::new(())
}
struct Foo;
impl Foo {
fn impl_fn_capture_hrtb_in_impl_trait()
-> Box<for<'a> Id<impl Lt<'a>>> // error!
{
Box::new(())
}
}
```

Here, you have used the inappropriate lifetime in the `impl Trait`,
The `impl Trait` can only capture lifetimes bound at the fn or impl
level.

To fix this we have to define the lifetime at the function or impl
level and use that lifetime in the `impl Trait`. For example you can
define the lifetime at the function:

```
trait Id<T> {}
trait Lt<'a> {}
impl<'a> Lt<'a> for () {}
impl<T> Id<T> for T {}
fn free_fn_capture_hrtb_in_impl_trait<'b>()
-> Box<for<'a> Id<impl Lt<'b>>> // ok!
{
Box::new(())
}
struct Foo;
impl Foo {
fn impl_fn_capture_hrtb_in_impl_trait<'b>()
-> Box<for<'a> Id<impl Lt<'b>>> // ok!
{
Box::new(())
}
}
```
8 changes: 4 additions & 4 deletions src/librustc_middle/mir/interpret/error.rs
Original file line number Diff line number Diff line change
@@ -305,7 +305,7 @@ impl fmt::Debug for InvalidProgramInfo<'_> {
Layout(ref err) => write!(f, "{}", err),
TransmuteSizeDiff(from_ty, to_ty) => write!(
f,
"tried to transmute from {:?} to {:?}, but their sizes differed",
"transmuting `{}` to `{}` is not possible, because these types do not have the same size",
from_ty, to_ty
),
}
@@ -431,7 +431,7 @@ impl fmt::Debug for UndefinedBehaviorInfo {
"using uninitialized data, but this operation requires initialized memory"
),
DeadLocal => write!(f, "accessing a dead local variable"),
ReadFromReturnPlace => write!(f, "tried to read from the return place"),
ReadFromReturnPlace => write!(f, "reading from return place"),
}
}
}
@@ -462,9 +462,9 @@ impl fmt::Debug for UnsupportedOpInfo {
match self {
Unsupported(ref msg) => write!(f, "{}", msg),
ReadForeignStatic(did) => {
write!(f, "tried to read from foreign (extern) static {:?}", did)
write!(f, "cannot read from foreign (extern) static {:?}", did)
}
NoMirFor(did) => write!(f, "could not load MIR for {:?}", did),
NoMirFor(did) => write!(f, "no MIR body is available for {:?}", did),
ReadPointerAsBytes => write!(f, "unable to turn pointer into raw bytes",),
ReadBytesAsPointer => write!(f, "unable to turn bytes into a pointer"),
}
17 changes: 11 additions & 6 deletions src/librustc_mir/interpret/validity.rs
Original file line number Diff line number Diff line change
@@ -322,7 +322,11 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
let value = self.ecx.read_immediate(value)?;
// Handle wide pointers.
// Check metadata early, for better diagnostics
let place = try_validation!(self.ecx.ref_to_mplace(value), "undefined pointer", self.path);
let place = try_validation!(
self.ecx.ref_to_mplace(value),
format_args!("uninitialized {}", kind),
self.path
);
if place.layout.is_unsized() {
self.check_wide_ptr_meta(place.meta, place.layout)?;
}
@@ -334,7 +338,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
format_args!("invalid {} metadata: {}", kind, msg),
self.path
),
_ => bug!("Unexpected error during ptr size_and_align_of: {}", err),
_ => bug!("unexpected error during ptr size_and_align_of: {}", err),
},
};
let (size, align) = size_and_align
@@ -477,10 +481,11 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
}
ty::RawPtr(..) => {
// We are conservative with undef for integers, but try to
// actually enforce our current rules for raw pointers.
// actually enforce the strict rules for raw pointers (mostly because
// that lets us re-use `ref_to_mplace`).
let place = try_validation!(
self.ecx.ref_to_mplace(self.ecx.read_immediate(value)?),
"undefined pointer",
"uninitialized raw pointer",
self.path
);
if place.layout.is_unsized() {
@@ -776,14 +781,14 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
// For some errors we might be able to provide extra information
match err.kind {
err_ub!(InvalidUndefBytes(Some(ptr))) => {
// Some byte was undefined, determine which
// Some byte was uninitialized, determine which
// element that byte belongs to so we can
// provide an index.
let i = usize::try_from(ptr.offset.bytes() / layout.size.bytes())
.unwrap();
self.path.push(PathElem::ArrayElem(i));

throw_validation_failure!("undefined bytes", self.path)
throw_validation_failure!("uninitialized bytes", self.path)
}
// Other errors shouldn't be possible
_ => return Err(err),
1 change: 1 addition & 0 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
@@ -285,6 +285,7 @@
#![feature(never_type)]
#![feature(nll)]
#![feature(optin_builtin_traits)]
#![feature(or_patterns)]
#![feature(panic_info_message)]
#![feature(panic_internals)]
#![feature(panic_unwind)]
2 changes: 1 addition & 1 deletion src/libstd/sync/mpsc/oneshot.rs
Original file line number Diff line number Diff line change
@@ -260,7 +260,7 @@ impl<T> Packet<T> {
let state = match self.state.load(Ordering::SeqCst) {
// Each of these states means that no further activity will happen
// with regard to abortion selection
s @ EMPTY | s @ DATA | s @ DISCONNECTED => s,
s @ (EMPTY | DATA | DISCONNECTED) => s,

// If we've got a blocked thread, then use an atomic to gain ownership
// of it (may fail)
2 changes: 1 addition & 1 deletion src/libstd/sync/mpsc/stream.rs
Original file line number Diff line number Diff line change
@@ -205,7 +205,7 @@ impl<T> Packet<T> {
// Messages which actually popped from the queue shouldn't count as
// a steal, so offset the decrement here (we already have our
// "steal" factored into the channel count above).
data @ Ok(..) | data @ Err(Upgraded(..)) => unsafe {
data @ (Ok(..) | Err(Upgraded(..))) => unsafe {
*self.queue.consumer_addition().steals.get() -= 1;
data
},
12 changes: 12 additions & 0 deletions src/test/ui/asm/issue-54067.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// check-pass
// ignore-emscripten no llvm_asm! support

#![feature(llvm_asm)]

pub fn boot(addr: Option<u32>) {
unsafe {
llvm_asm!("mov sp, $0"::"r" (addr));
}
}

fn main() {}
10 changes: 10 additions & 0 deletions src/test/ui/async-await/issues/auxiliary/issue_67893.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// edition:2018

use std::sync::{Arc, Mutex};

pub async fn f(_: ()) {}

pub async fn run() {
let x: Arc<Mutex<()>> = unimplemented!();
f(*x.lock().unwrap()).await;
}
13 changes: 13 additions & 0 deletions src/test/ui/async-await/issues/issue-67893.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// aux-build: issue_67893.rs
// edition:2018
// dont-check-compiler-stderr
// FIXME(#71222): Add above flag because of the difference of stderrs on some env.

extern crate issue_67893;

fn g(_: impl Send) {}

fn main() {
g(issue_67893::run())
//~^ ERROR: `std::sync::MutexGuard<'_, ()>` cannot be sent between threads safely
}
65 changes: 65 additions & 0 deletions src/test/ui/consts/const-eval/ub-int-array.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#![feature(const_transmute)]
#![allow(const_err)] // make sure we cannot allow away the errors tested here

//! Test the "array of int" fast path in validity checking, and in particular whether it
//! points at the right array element.
use std::mem;

#[repr(C)]
union MaybeUninit<T: Copy> {
uninit: (),
init: T,
}

const UNINIT_INT_0: [u32; 3] = unsafe {
//~^ ERROR it is undefined behavior to use this value
//~| type validation failed: encountered uninitialized bytes at [0]
[
MaybeUninit { uninit: () }.init,
1,
2,
]
};
const UNINIT_INT_1: [u32; 3] = unsafe {
//~^ ERROR it is undefined behavior to use this value
//~| type validation failed: encountered uninitialized bytes at [1]
mem::transmute(
[
0u8,
0u8,
0u8,
0u8,
1u8,
MaybeUninit { uninit: () }.init,
1u8,
1u8,
2u8,
2u8,
MaybeUninit { uninit: () }.init,
2u8,
]
)
};
const UNINIT_INT_2: [u32; 3] = unsafe {
//~^ ERROR it is undefined behavior to use this value
//~| type validation failed: encountered uninitialized bytes at [2]
mem::transmute(
[
0u8,
0u8,
0u8,
0u8,
1u8,
1u8,
1u8,
1u8,
2u8,
2u8,
2u8,
MaybeUninit { uninit: () }.init,
]
)
};

fn main() {}
45 changes: 45 additions & 0 deletions src/test/ui/consts/const-eval/ub-int-array.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-int-array.rs:15:1
|
LL | / const UNINIT_INT_0: [u32; 3] = unsafe {
LL | |
LL | |
LL | | [
... |
LL | | ]
LL | | };
| |__^ type validation failed: encountered uninitialized bytes at [0]
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.

error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-int-array.rs:24:1
|
LL | / const UNINIT_INT_1: [u32; 3] = unsafe {
LL | |
LL | |
LL | | mem::transmute(
... |
LL | | )
LL | | };
| |__^ type validation failed: encountered uninitialized bytes at [1]
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.

error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-int-array.rs:44:1
|
LL | / const UNINIT_INT_2: [u32; 3] = unsafe {
LL | |
LL | |
LL | | mem::transmute(
... |
LL | | )
LL | | };
| |__^ type validation failed: encountered uninitialized bytes at [2]
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0080`.
4 changes: 2 additions & 2 deletions src/test/ui/consts/const-eval/ub-ref.rs
Original file line number Diff line number Diff line change
@@ -6,11 +6,11 @@ use std::mem;

const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
//~^ ERROR it is undefined behavior to use this value
//~^^ type validation failed: encountered an unaligned reference (required 2 byte alignment but found 1)
//~| type validation failed: encountered an unaligned reference (required 2 byte alignment but found 1)

const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) };
//~^ ERROR it is undefined behavior to use this value
//~^^ type validation failed: encountered an unaligned box (required 2 byte alignment but found 1)
//~| type validation failed: encountered an unaligned box (required 2 byte alignment but found 1)

const NULL: &u16 = unsafe { mem::transmute(0usize) };
//~^ ERROR it is undefined behavior to use this value
4 changes: 2 additions & 2 deletions src/test/ui/consts/const-eval/ub-wide-ptr.stderr
Original file line number Diff line number Diff line change
@@ -62,7 +62,7 @@ LL | |
LL | | let uninit_len = MaybeUninit::<usize> { uninit: () };
LL | | mem::transmute((42, uninit_len))
LL | | };
| |__^ type validation failed: encountered undefined pointer
| |__^ type validation failed: encountered uninitialized reference
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.

@@ -130,7 +130,7 @@ LL | |
LL | | let uninit_len = MaybeUninit::<usize> { uninit: () };
LL | | mem::transmute((42, uninit_len))
LL | | };
| |__^ type validation failed: encountered undefined pointer
| |__^ type validation failed: encountered uninitialized raw pointer
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.

2 changes: 1 addition & 1 deletion src/test/ui/consts/const-eval/union-ice.stderr
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ LL | | unsafe { UNION.field3 },
... |
LL | | a: 42,
LL | | };
| |__^ type validation failed: encountered undefined bytes at .b[1]
| |__^ type validation failed: encountered uninitialized bytes at .b[1]
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.

Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ error: any use of this value will cause an error
LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) };
| ----------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^---
| |
| tried to transmute from usize to &[u8], but their sizes differed
| transmuting `usize` to `&[u8]` is not possible, because these types do not have the same size
|
= note: `#[deny(const_err)]` on by default

1 change: 1 addition & 0 deletions src/test/ui/error-codes/E0657.stderr
Original file line number Diff line number Diff line change
@@ -12,3 +12,4 @@ LL | -> Box<for<'a> Id<impl Lt<'a>>>

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0657`.
9 changes: 9 additions & 0 deletions src/test/ui/intrinsics/issue-28575.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#![feature(intrinsics)]

extern "C" {
pub static FOO: extern "rust-intrinsic" fn();
}

fn main() {
FOO() //~ ERROR: use of extern static is unsafe
}
11 changes: 11 additions & 0 deletions src/test/ui/intrinsics/issue-28575.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0133]: use of extern static is unsafe and requires unsafe function or block
--> $DIR/issue-28575.rs:8:5
|
LL | FOO()
| ^^^ 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: aborting due to previous error

For more information about this error, try `rustc --explain E0133`.
1 change: 1 addition & 0 deletions src/test/ui/static/auxiliary/issue_24843.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub static TEST_STR: &'static str = "Hello world";
8 changes: 8 additions & 0 deletions src/test/ui/static/issue-24843.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// aux-build: issue_24843.rs
// check-pass

extern crate issue_24843;

static _TEST_STR_2: &'static str = &issue_24843::TEST_STR;

fn main() {}