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

Rollup of 7 pull requests #67575

Merged
merged 28 commits into from
Dec 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4ee18c9
Clean up E0124 explanation
GuillaumeGomez Dec 22, 2019
1474d2a
Clean up E0128 explanation
GuillaumeGomez Dec 22, 2019
101dd7b
Use `is_none` instead of `if let`
JohnTitor Dec 22, 2019
7c485cc
Add test for issue-61747
JohnTitor Dec 22, 2019
96253c2
Add test for issue-66205
JohnTitor Dec 22, 2019
6ec3a63
Add test for issue-66270
JohnTitor Dec 22, 2019
256eec4
Update E0124.md
Dylan-DPC Dec 23, 2019
1485c16
Add long error code explanation message for E0627
ldm0 Dec 23, 2019
587d03b
Yield is an expression form, not a statement.
ldm0 Dec 23, 2019
640e288
Panic on mutable allocs in constants
oli-obk Dec 16, 2019
ad6b9c7
Dynamically prevent constants from accessing statics
oli-obk Dec 16, 2019
2022fac
Constants reading or referencing statics is illegal
oli-obk Dec 22, 2019
e56a861
Show `const_err` lints
oli-obk Dec 22, 2019
89250b9
Update src/librustc_mir/interpret/intern.rs
oli-obk Dec 23, 2019
75bdd95
Tidy
oli-obk Dec 23, 2019
24f3dcf
remove `description` from `Error` impls in docs
euclio Dec 23, 2019
1f2fa93
Add test for issue-67424
JohnTitor Dec 22, 2019
d918319
Apply suggestion from Centril
JohnTitor Dec 22, 2019
87fea04
Bless tests
oli-obk Dec 23, 2019
cefeb66
Use the chocolatey CDN directly to avoid the flaky API
aidanhs Dec 23, 2019
df4d490
Minimize unsafety in encode_utf8
Mark-Simulacrum Dec 23, 2019
1ac8fc7
Rollup merge of #67337 - oli-obk:no_mut_static_ref_from_const, r=Ralf…
Centril Dec 24, 2019
07effe1
Rollup merge of #67543 - JohnTitor:regression-tests, r=Centril
Centril Dec 24, 2019
d130e8d
Rollup merge of #67547 - GuillaumeGomez:cleanup-err-codes, r=Dylan-DPC
Centril Dec 24, 2019
a75968a
Rollup merge of #67551 - ldm0:E0627, r=Dylan-DPC
Centril Dec 24, 2019
75b27ef
Rollup merge of #67561 - euclio:remove-description, r=jonas-schievink
Centril Dec 24, 2019
20d5df9
Rollup merge of #67569 - Mark-Simulacrum:opt-char-encode, r=oli-obk
Centril Dec 24, 2019
a76d67f
Rollup merge of #67572 - aidanhs:aphs-choco-direct-cdn, r=Mark-Simula…
Centril Dec 24, 2019
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
16 changes: 10 additions & 6 deletions src/ci/scripts/install-msys2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ IFS=$'\n\t'
source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"

if isWindows; then
for RETRY_COUNT in 1 2 3 4 5 6 7 8 9 10; do
choco install msys2 \
--params="/InstallDir:$(ciCheckoutPath)/msys2 /NoPath" -y --no-progress \
&& mkdir -p "$(ciCheckoutPath)/msys2/home/${USERNAME}" \
&& ciCommandAddPath "$(ciCheckoutPath)/msys2/usr/bin" && break
done
# Pre-followed the api/v2 URL to the CDN since the API can be a bit flakey
curl -sSL https://packages.chocolatey.org/msys2.20190524.0.0.20191030.nupkg > \
msys2.nupkg
curl -sSL https://packages.chocolatey.org/chocolatey-core.extension.1.3.5.1.nupkg > \
chocolatey-core.extension.nupkg
choco install -s . msys2 \
--params="/InstallDir:$(ciCheckoutPath)/msys2 /NoPath" -y --no-progress
rm msys2.nupkg chocolatey-core.extension.nupkg
mkdir -p "$(ciCheckoutPath)/msys2/home/${USERNAME}"
ciCommandAddPath "$(ciCheckoutPath)/msys2/usr/bin"
fi
59 changes: 29 additions & 30 deletions src/libcore/char/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,36 +434,35 @@ impl char {
#[inline]
pub fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
let code = self as u32;
// SAFETY: each arm checks the size of the slice and only uses `get_unchecked` unsafe ops
unsafe {
let len = if code < MAX_ONE_B && !dst.is_empty() {
*dst.get_unchecked_mut(0) = code as u8;
1
} else if code < MAX_TWO_B && dst.len() >= 2 {
*dst.get_unchecked_mut(0) = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
*dst.get_unchecked_mut(1) = (code & 0x3F) as u8 | TAG_CONT;
2
} else if code < MAX_THREE_B && dst.len() >= 3 {
*dst.get_unchecked_mut(0) = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
*dst.get_unchecked_mut(1) = (code >> 6 & 0x3F) as u8 | TAG_CONT;
*dst.get_unchecked_mut(2) = (code & 0x3F) as u8 | TAG_CONT;
3
} else if dst.len() >= 4 {
*dst.get_unchecked_mut(0) = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
*dst.get_unchecked_mut(1) = (code >> 12 & 0x3F) as u8 | TAG_CONT;
*dst.get_unchecked_mut(2) = (code >> 6 & 0x3F) as u8 | TAG_CONT;
*dst.get_unchecked_mut(3) = (code & 0x3F) as u8 | TAG_CONT;
4
} else {
panic!(
"encode_utf8: need {} bytes to encode U+{:X}, but the buffer has {}",
from_u32_unchecked(code).len_utf8(),
code,
dst.len(),
)
};
from_utf8_unchecked_mut(dst.get_unchecked_mut(..len))
}
let len = self.len_utf8();
match (len, &mut dst[..]) {
(1, [a, ..]) => {
*a = code as u8;
}
(2, [a, b, ..]) => {
*a = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
*b = (code & 0x3F) as u8 | TAG_CONT;
}
(3, [a, b, c, ..]) => {
*a = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
*b = (code >> 6 & 0x3F) as u8 | TAG_CONT;
*c = (code & 0x3F) as u8 | TAG_CONT;
}
(4, [a, b, c, d, ..]) => {
*a = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
*b = (code >> 12 & 0x3F) as u8 | TAG_CONT;
*c = (code >> 6 & 0x3F) as u8 | TAG_CONT;
*d = (code & 0x3F) as u8 | TAG_CONT;
}
_ => panic!(
"encode_utf8: need {} bytes to encode U+{:X}, but the buffer has {}",
len,
code,
dst.len(),
),
};
// SAFETY: We just wrote UTF-8 content in, so converting to str is fine.
unsafe { from_utf8_unchecked_mut(&mut dst[..len]) }
}

/// Encodes this character as UTF-16 into the provided `u16` buffer,
Expand Down
1 change: 1 addition & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
#![feature(associated_type_bounds)]
#![feature(const_type_id)]
#![feature(const_caller_location)]
#![feature(slice_patterns)]

#[prelude_import]
#[allow(unused)]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2373,7 +2373,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let span = self.tcx.def_span(generator_did);

// Do not ICE on closure typeck (#66868).
if let None = self.tcx.hir().as_local_hir_id(generator_did) {
if self.tcx.hir().as_local_hir_id(generator_did).is_none() {
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_error_codes/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ E0622: include_str!("./error_codes/E0622.md"),
E0623: include_str!("./error_codes/E0623.md"),
E0624: include_str!("./error_codes/E0624.md"),
E0626: include_str!("./error_codes/E0626.md"),
E0627: include_str!("./error_codes/E0627.md"),
E0631: include_str!("./error_codes/E0631.md"),
E0633: include_str!("./error_codes/E0633.md"),
E0635: include_str!("./error_codes/E0635.md"),
Expand Down Expand Up @@ -574,7 +575,6 @@ E0745: include_str!("./error_codes/E0745.md"),
// E0612, // merged into E0609
// E0613, // Removed (merged with E0609)
E0625, // thread-local statics cannot be accessed at compile-time
E0627, // yield statement outside of generator literal
E0628, // generators cannot have explicit parameters
E0629, // missing 'feature' (rustc_const_unstable)
// rustc_const_unstable attribute must be paired with stable/unstable
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_error_codes/error_codes/E0124.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
You declared two fields of a struct with the same name. Erroneous code
example:
A struct was declared with two fields having the same name.

Erroneous code example:

```compile_fail,E0124
struct Foo {
Expand Down
9 changes: 5 additions & 4 deletions src/librustc_error_codes/error_codes/E0128.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Type parameter defaults can only use parameters that occur before them.
A type parameter with default value is using forward declared identifier.

Erroneous code example:

```compile_fail,E0128
Expand All @@ -7,11 +8,11 @@ struct Foo<T = U, U = ()> {
field2: U,
}
// error: type parameters with a default cannot use forward declared
// identifiers
// identifiers
```

Since type parameters are evaluated in-order, you may be able to fix this issue
by doing:
Type parameter defaults can only use parameters that occur before them. Since
type parameters are evaluated in-order, this issue could be fixed by doing:

```
struct Foo<U = (), T = U> {
Expand Down
30 changes: 30 additions & 0 deletions src/librustc_error_codes/error_codes/E0627.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
A yield expression was used outside of the generator literal.

Erroneous code example:

```compile_fail,E0627
#![feature(generators, generator_trait)]

fn fake_generator() -> &'static str {
yield 1;
return "foo"
}

fn main() {
let mut generator = fake_generator;
}
```

The error occurs because keyword `yield` can only be used inside the generator
literal. This can be fixed by constructing the generator correctly.

```
#![feature(generators, generator_trait)]

fn main() {
let mut generator = || {
yield 1;
return "foo"
};
}
```
2 changes: 1 addition & 1 deletion src/librustc_mir/borrow_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1424,7 +1424,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}

/// Reports an error if this is a borrow of local data.
/// This is called for all Yield statements on movable generators
/// This is called for all Yield expressions on movable generators
fn check_for_local_borrow(&mut self, borrow: &BorrowData<'tcx>, yield_span: Span) {
debug!("check_for_local_borrow({:?})", borrow);

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/borrow_check/path_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ pub(super) fn is_active<'tcx>(
}

/// Determines if a given borrow is borrowing local data
/// This is called for all Yield statements on movable generators
/// This is called for all Yield expressions on movable generators
pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool {
match place.base {
PlaceBase::Static(_) => false,
Expand Down
53 changes: 41 additions & 12 deletions src/librustc_mir/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,15 @@ fn mk_eval_cx<'mir, 'tcx>(
tcx: TyCtxt<'tcx>,
span: Span,
param_env: ty::ParamEnv<'tcx>,
can_access_statics: bool,
) -> CompileTimeEvalContext<'mir, 'tcx> {
debug!("mk_eval_cx: {:?}", param_env);
InterpCx::new(tcx.at(span), param_env, CompileTimeInterpreter::new(), Default::default())
InterpCx::new(
tcx.at(span),
param_env,
CompileTimeInterpreter::new(),
MemoryExtra { can_access_statics },
)
}

fn op_to_const<'tcx>(
Expand Down Expand Up @@ -176,6 +182,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
#[derive(Clone, Debug)]
pub enum ConstEvalError {
NeedsRfc(String),
ConstAccessesStatic,
}

impl<'tcx> Into<InterpErrorInfo<'tcx>> for ConstEvalError {
Expand All @@ -195,6 +202,7 @@ impl fmt::Display for ConstEvalError {
msg
)
}
ConstAccessesStatic => write!(f, "constant accesses static"),
}
}
}
Expand All @@ -204,6 +212,7 @@ impl Error for ConstEvalError {
use self::ConstEvalError::*;
match *self {
NeedsRfc(_) => "this feature needs an rfc before being allowed inside constants",
ConstAccessesStatic => "constant accesses static",
}
}

Expand All @@ -224,6 +233,12 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
pub(super) loop_detector: snapshot::InfiniteLoopDetector<'mir, 'tcx>,
}

#[derive(Copy, Clone, Debug)]
pub struct MemoryExtra {
/// Whether this machine may read from statics
can_access_statics: bool,
}

impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
fn new() -> Self {
CompileTimeInterpreter {
Expand Down Expand Up @@ -311,7 +326,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
type ExtraFnVal = !;

type FrameExtra = ();
type MemoryExtra = ();
type MemoryExtra = MemoryExtra;
type AllocExtra = ();

type MemoryMap = FxHashMap<AllocId, (MemoryKind<!>, Allocation)>;
Expand Down Expand Up @@ -473,7 +488,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,

#[inline(always)]
fn init_allocation_extra<'b>(
_memory_extra: &(),
_memory_extra: &MemoryExtra,
_id: AllocId,
alloc: Cow<'b, Allocation>,
_kind: Option<MemoryKind<!>>,
Expand All @@ -484,7 +499,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,

#[inline(always)]
fn tag_static_base_pointer(
_memory_extra: &(),
_memory_extra: &MemoryExtra,
_id: AllocId,
) -> Self::PointerTag {
()
Expand Down Expand Up @@ -527,6 +542,17 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
fn stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
Ok(())
}

fn before_access_static(
memory_extra: &MemoryExtra,
_allocation: &Allocation,
) -> InterpResult<'tcx> {
if memory_extra.can_access_statics {
Ok(())
} else {
Err(ConstEvalError::ConstAccessesStatic.into())
}
}
}

/// Extracts a field of a (variant of a) const.
Expand All @@ -540,7 +566,7 @@ pub fn const_field<'tcx>(
value: &'tcx ty::Const<'tcx>,
) -> &'tcx ty::Const<'tcx> {
trace!("const_field: {:?}, {:?}", field, value);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
// get the operand again
let op = ecx.eval_const_to_op(value, None).unwrap();
// downcast
Expand All @@ -560,7 +586,7 @@ pub fn const_caller_location<'tcx>(
(file, line, col): (Symbol, u32, u32),
) -> &'tcx ty::Const<'tcx> {
trace!("const_caller_location: {}:{}:{}", file, line, col);
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, ty::ParamEnv::reveal_all());
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, ty::ParamEnv::reveal_all(), false);

let loc_ty = tcx.caller_location_ty();
let loc_place = ecx.alloc_caller_location(file, line, col);
Expand All @@ -581,7 +607,7 @@ pub fn const_variant_index<'tcx>(
val: &'tcx ty::Const<'tcx>,
) -> VariantIdx {
trace!("const_variant_index: {:?}", val);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
let op = ecx.eval_const_to_op(val, None).unwrap();
ecx.read_discriminant(op).unwrap().1
}
Expand Down Expand Up @@ -610,7 +636,9 @@ fn validate_and_turn_into_const<'tcx>(
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
let cid = key.value;
let ecx = mk_eval_cx(tcx, tcx.def_span(key.value.instance.def_id()), key.param_env);
let def_id = cid.instance.def.def_id();
let is_static = tcx.is_static(def_id);
let ecx = mk_eval_cx(tcx, tcx.def_span(key.value.instance.def_id()), key.param_env, is_static);
let val = (|| {
let mplace = ecx.raw_const_to_mplace(constant)?;
let mut ref_tracking = RefTracking::new(mplace);
Expand All @@ -624,8 +652,7 @@ fn validate_and_turn_into_const<'tcx>(
// Now that we validated, turn this into a proper constant.
// Statics/promoteds are always `ByRef`, for the rest `op_to_const` decides
// whether they become immediates.
let def_id = cid.instance.def.def_id();
if tcx.is_static(def_id) || cid.promoted.is_some() {
if is_static || cid.promoted.is_some() {
let ptr = mplace.ptr.to_ptr()?;
Ok(tcx.mk_const(ty::Const {
val: ty::ConstKind::Value(ConstValue::ByRef {
Expand Down Expand Up @@ -732,12 +759,14 @@ pub fn const_eval_raw_provider<'tcx>(
return Err(ErrorHandled::Reported);
}

let is_static = tcx.is_static(def_id);

let span = tcx.def_span(cid.instance.def_id());
let mut ecx = InterpCx::new(
tcx.at(span),
key.param_env,
CompileTimeInterpreter::new(),
Default::default()
MemoryExtra { can_access_statics: is_static },
);

let res = ecx.load_mir(cid.instance.def, cid.promoted);
Expand All @@ -751,7 +780,7 @@ pub fn const_eval_raw_provider<'tcx>(
}).map_err(|error| {
let err = error_to_const_error(&ecx, error);
// errors in statics are always emitted as fatal errors
if tcx.is_static(def_id) {
if is_static {
// Ensure that if the above error was either `TooGeneric` or `Reported`
// an error must be reported.
let v = err.report_as_error(ecx.tcx, "could not evaluate static initializer");
Expand Down
Loading