Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
42 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
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
2536c75
Don't ICE on the use of integer addresses for ZST constants in patter…
oli-obk Dec 13, 2019
cc5cc67
Retire `to_ptr` which should already have no users but still kept get…
oli-obk Dec 13, 2019
8be7c54
Simplify `force_allocation_maybe_sized`
oli-obk Dec 13, 2019
53ca738
Comment on a few odd things that we should look at
oli-obk Dec 13, 2019
6976435
Prevent an ICE on invalid transmutes
oli-obk Dec 13, 2019
68ecc21
Interning even happens when validation of a constant fails
oli-obk Dec 14, 2019
c4f9215
Immediately evaluate and validate constants when we want them as oper…
oli-obk Dec 20, 2019
7ef8cf4
Add regression test for ZST statics being allowed to "read" from them…
oli-obk Dec 20, 2019
58eec17
Explain ParamEnv::reveal_all usage
oli-obk Dec 22, 2019
51937ef
Comments should start capitalized and end in a period
oli-obk Dec 22, 2019
5b278bc
Explain what we are doing with parameter environments for statics
oli-obk Dec 22, 2019
efbbc69
Explain the currently necessary existance of `TransmuteSizeDiff`
oli-obk Dec 22, 2019
405dbc6
Remove unintended noisy log statement
oli-obk Dec 22, 2019
eabe066
Typo
oli-obk Dec 22, 2019
af8ca7a
Explain why `const_eval` is ok here
oli-obk Dec 22, 2019
4c40bb7
Early abort instead of building up zero sized values
oli-obk Dec 22, 2019
09dd13c
Add a `const_eval` helper to `InterpCx`
oli-obk Dec 22, 2019
79960b4
Documentation nit
oli-obk Dec 22, 2019
e9dc860
Reintroduce the recursion comment
oli-obk Dec 22, 2019
aaf7015
Use the targetted const eval functions
oli-obk Dec 23, 2019
65bb805
Fix rebase fallout
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
318c52f
Rollup merge of #67192 - oli-obk:const_zst_addr, r=RalfJung,varkor
Mark-Simulacrum Dec 24, 2019
587f694
Rollup merge of #67543 - JohnTitor:regression-tests, r=Centril
Mark-Simulacrum Dec 24, 2019
93116b2
Rollup merge of #67547 - GuillaumeGomez:cleanup-err-codes, r=Dylan-DPC
Mark-Simulacrum Dec 24, 2019
8a1015f
Rollup merge of #67551 - ldm0:E0627, r=Dylan-DPC
Mark-Simulacrum Dec 24, 2019
b8b9a0f
Rollup merge of #67561 - euclio:remove-description, r=jonas-schievink
Mark-Simulacrum Dec 24, 2019
cb5e4ab
Rollup merge of #67569 - Mark-Simulacrum:opt-char-encode, r=oli-obk
Mark-Simulacrum Dec 24, 2019
37f97de
Rollup merge of #67572 - aidanhs:aphs-choco-direct-cdn, r=Mark-Simula…
Mark-Simulacrum 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
Prev Previous commit
Next Next commit
Don't ICE on the use of integer addresses for ZST constants in patter…
…n matching
  • Loading branch information
oli-obk committed Dec 23, 2019
commit 2536c75d4fff3b86087c3ffd9ea7540ce99ae2fd
4 changes: 4 additions & 0 deletions src/librustc/mir/interpret/allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ impl<Tag> Allocation<Tag> {
extra: (),
}
}

pub fn zst(align: Align) -> Self {
Self::undef(Size::ZERO, align)
}
}

impl Allocation<(), ()> {
Expand Down
52 changes: 40 additions & 12 deletions src/librustc_mir/hair/pattern/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,11 @@ use super::{FieldPat, Pat, PatKind, PatRange};

use rustc::hir::def_id::DefId;
use rustc::hir::{HirId, RangeEnd};
use rustc::ty::layout::{Integer, IntegerExt, Size, VariantIdx};
use rustc::ty::layout::{Align, Integer, IntegerExt, Size, VariantIdx};
use rustc::ty::{self, Const, Ty, TyCtxt, TypeFoldable, VariantDef};

use rustc::lint;
use rustc::mir::interpret::{truncate, AllocId, ConstValue, Pointer, Scalar};
use rustc::mir::interpret::{truncate, AllocId, Allocation, ConstValue, Pointer, Scalar};
use rustc::mir::Field;
use rustc::util::captures::Captures;
use rustc::util::common::ErrorReported;
Expand All @@ -252,6 +252,7 @@ use syntax_pos::{Span, DUMMY_SP};
use arena::TypedArena;

use smallvec::{smallvec, SmallVec};
use std::borrow::Cow;
use std::cmp::{self, max, min, Ordering};
use std::convert::TryInto;
use std::fmt;
Expand All @@ -260,11 +261,12 @@ use std::ops::RangeInclusive;
use std::u128;

pub fn expand_pattern<'a, 'tcx>(cx: &MatchCheckCtxt<'a, 'tcx>, pat: Pat<'tcx>) -> Pat<'tcx> {
LiteralExpander { tcx: cx.tcx }.fold_pattern(&pat)
LiteralExpander { tcx: cx.tcx, param_env: cx.param_env }.fold_pattern(&pat)
}

struct LiteralExpander<'tcx> {
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
}

impl LiteralExpander<'tcx> {
Expand All @@ -284,9 +286,23 @@ impl LiteralExpander<'tcx> {
debug!("fold_const_value_deref {:?} {:?} {:?}", val, rty, crty);
match (val, &crty.kind, &rty.kind) {
// the easy case, deref a reference
(ConstValue::Scalar(Scalar::Ptr(p)), x, y) if x == y => {
let alloc = self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id);
ConstValue::ByRef { alloc, offset: p.offset }
(ConstValue::Scalar(p), x, y) if x == y => {
match p {
Scalar::Ptr(p) => {
let alloc = self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id);
ConstValue::ByRef { alloc, offset: p.offset }
}
Scalar::Raw { .. } => {
let layout = self.tcx.layout_of(self.param_env.and(rty)).unwrap();
if layout.is_zst() {
// Deref of a reference to a ZST is a nop.
ConstValue::Scalar(Scalar::zst())
} else {
// FIXME(oli-obk): this is reachable for `const FOO: &&&u32 = &&&42;`
bug!("cannot deref {:#?}, {} -> {}", val, crty, rty);
}
}
}
}
// unsize array to slice if pattern is array but match value or other patterns are slice
(ConstValue::Scalar(Scalar::Ptr(p)), ty::Array(t, n), ty::Slice(u)) => {
Expand Down Expand Up @@ -2348,16 +2364,28 @@ fn specialize_one_pattern<'p, 'tcx>(
// just integers. The only time they should be pointing to memory
// is when they are subslices of nonzero slices.
let (alloc, offset, n, ty) = match value.ty.kind {
ty::Array(t, n) => match value.val {
ty::ConstKind::Value(ConstValue::ByRef { offset, alloc, .. }) => {
(alloc, offset, n.eval_usize(cx.tcx, cx.param_env), t)
ty::Array(t, n) => {
let n = n.eval_usize(cx.tcx, cx.param_env);
match value.val {
ty::ConstKind::Value(ConstValue::ByRef { offset, alloc, .. }) => {
(Cow::Borrowed(alloc), offset, n, t)
}
ty::ConstKind::Value(ConstValue::Scalar(Scalar::Raw { data, .. }))
if n == 0 =>
{
let align = Align::from_bytes(data as u64).unwrap();
// empty array
(Cow::Owned(Allocation::zst(align)), Size::ZERO, 0, t)
}
_ => span_bug!(pat.span, "array pattern is {:?}", value,),
}
_ => span_bug!(pat.span, "array pattern is {:?}", value,),
},
}
ty::Slice(t) => {
match value.val {
ty::ConstKind::Value(ConstValue::Slice { data, start, end }) => {
(data, Size::from_bytes(start as u64), (end - start) as u64, t)
let offset = Size::from_bytes(start as u64);
let n = (end - start) as u64;
(Cow::Borrowed(data), offset, n, t)
}
ty::ConstKind::Value(ConstValue::ByRef { .. }) => {
// FIXME(oli-obk): implement `deref` for `ConstValue`
Expand Down
6 changes: 6 additions & 0 deletions src/librustc_mir/hair/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,12 @@ pub fn compare_const_vals<'tcx>(
return fallback();
}

// Early return for equal constants (so e.g. references to ZSTs can be compared, even if they
// are just integer addresses).
if a.val == b.val {
return from_bool(true);
}

let a_bits = a.try_eval_bits(tcx, param_env, ty);
let b_bits = b.try_eval_bits(tcx, param_env, ty);

Expand Down
13 changes: 13 additions & 0 deletions src/test/ui/consts/consts-in-patterns.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// run-pass
#![feature(const_transmute)]

const FOO: isize = 10;
const BAR: isize = 3;
const ZST: &() = unsafe { std::mem::transmute(1usize) };
const ZST_ARR: &[u8; 0] = unsafe { std::mem::transmute(1usize) };

const fn foo() -> isize { 4 }
const BOO: isize = foo();
Expand All @@ -15,4 +18,14 @@ pub fn main() {
_ => 3
};
assert_eq!(y, 2);
let z = match &() {
ZST => 9,
// FIXME: this should not be required
_ => 42,
};
assert_eq!(z, 9);
let z = match b"" {
ZST_ARR => 10,
};
assert_eq!(z, 10);
}