Skip to content

Commit 5c717a6

Browse files
committed
implement RFC495 semantics for slice patterns
non-MIR translation is still not supported for these and will happily ICE. This is a [breaking-change] for many uses of slice_patterns.
1 parent 088b7e2 commit 5c717a6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+621
-518
lines changed

src/librustc/middle/expr_use_visitor.rs

-34
Original file line numberDiff line numberDiff line change
@@ -993,40 +993,6 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
993993
}
994994
}
995995
}
996-
PatKind::Vec(_, Some(ref slice_pat), _) => {
997-
// The `slice_pat` here creates a slice into
998-
// the original vector. This is effectively a
999-
// borrow of the elements of the vector being
1000-
// matched.
1001-
1002-
let (slice_cmt, slice_mutbl, slice_r) =
1003-
return_if_err!(mc.cat_slice_pattern(cmt_pat, &slice_pat));
1004-
1005-
// Note: We declare here that the borrow
1006-
// occurs upon entering the `[...]`
1007-
// pattern. This implies that something like
1008-
// `[a; b]` where `a` is a move is illegal,
1009-
// because the borrow is already in effect.
1010-
// In fact such a move would be safe-ish, but
1011-
// it effectively *requires* that we use the
1012-
// nulling out semantics to indicate when a
1013-
// value has been moved, which we are trying
1014-
// to move away from. Otherwise, how can we
1015-
// indicate that the first element in the
1016-
// vector has been moved? Eventually, we
1017-
// could perhaps modify this rule to permit
1018-
// `[..a, b]` where `b` is a move, because in
1019-
// that case we can adjust the length of the
1020-
// original vec accordingly, but we'd have to
1021-
// make trans do the right thing, and it would
1022-
// only work for `Box<[T]>`s. It seems simpler
1023-
// to just require that people call
1024-
// `vec.pop()` or `vec.unshift()`.
1025-
let slice_bk = ty::BorrowKind::from_mutbl(slice_mutbl);
1026-
delegate.borrow(pat.id, pat.span,
1027-
slice_cmt, slice_r,
1028-
slice_bk, RefBinding);
1029-
}
1030996
_ => {}
1031997
}
1032998
}));

src/librustc/middle/mem_categorization.rs

+1-40
Original file line numberDiff line numberDiff line change
@@ -1061,43 +1061,6 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
10611061
Ok(ret)
10621062
}
10631063

1064-
/// Given a pattern P like: `[_, ..Q, _]`, where `vec_cmt` is the cmt for `P`, `slice_pat` is
1065-
/// the pattern `Q`, returns:
1066-
///
1067-
/// * a cmt for `Q`
1068-
/// * the mutability and region of the slice `Q`
1069-
///
1070-
/// These last two bits of info happen to be things that borrowck needs.
1071-
pub fn cat_slice_pattern(&self,
1072-
vec_cmt: cmt<'tcx>,
1073-
slice_pat: &hir::Pat)
1074-
-> McResult<(cmt<'tcx>, hir::Mutability, ty::Region)> {
1075-
let slice_ty = self.node_ty(slice_pat.id)?;
1076-
let (slice_mutbl, slice_r) = vec_slice_info(slice_pat, slice_ty);
1077-
let context = InteriorOffsetKind::Pattern;
1078-
let cmt_vec = self.deref_vec(slice_pat, vec_cmt, context)?;
1079-
let cmt_slice = self.cat_index(slice_pat, cmt_vec, context)?;
1080-
return Ok((cmt_slice, slice_mutbl, slice_r));
1081-
1082-
/// In a pattern like [a, b, ..c], normally `c` has slice type, but if you have [a, b,
1083-
/// ..ref c], then the type of `ref c` will be `&&[]`, so to extract the slice details we
1084-
/// have to recurse through rptrs.
1085-
fn vec_slice_info(pat: &hir::Pat, slice_ty: Ty)
1086-
-> (hir::Mutability, ty::Region) {
1087-
match slice_ty.sty {
1088-
ty::TyRef(r, ref mt) => match mt.ty.sty {
1089-
ty::TySlice(_) => (mt.mutbl, *r),
1090-
_ => vec_slice_info(pat, mt.ty),
1091-
},
1092-
1093-
_ => {
1094-
span_bug!(pat.span,
1095-
"type of slice pattern is not a slice");
1096-
}
1097-
}
1098-
}
1099-
}
1100-
11011064
pub fn cat_imm_interior<N:ast_node>(&self,
11021065
node: &N,
11031066
base_cmt: cmt<'tcx>,
@@ -1325,9 +1288,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
13251288
self.cat_pattern_(elt_cmt.clone(), &before_pat, op)?;
13261289
}
13271290
if let Some(ref slice_pat) = *slice {
1328-
let slice_ty = self.pat_ty(&slice_pat)?;
1329-
let slice_cmt = self.cat_rvalue_node(pat.id(), pat.span(), slice_ty);
1330-
self.cat_pattern_(slice_cmt, &slice_pat, op)?;
1291+
self.cat_pattern_(elt_cmt.clone(), &slice_pat, op)?;
13311292
}
13321293
for after_pat in after {
13331294
self.cat_pattern_(elt_cmt.clone(), &after_pat, op)?;

src/librustc/mir/repr.rs

+16-13
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,14 @@ pub enum ProjectionElem<'tcx, V> {
674674
from_end: bool,
675675
},
676676

677+
/// These indices are generated by slice patterns.
678+
///
679+
/// slice[from:-to] in Python terms.
680+
Subslice {
681+
from: u32,
682+
to: u32,
683+
},
684+
677685
/// "Downcast" to a variant of an ADT. Currently, we only introduce
678686
/// this for ADTs with more than one variant. It may be better to
679687
/// just introduce it always, or always for enums.
@@ -753,6 +761,14 @@ impl<'tcx> Debug for Lvalue<'tcx> {
753761
write!(fmt, "{:?}[{:?} of {:?}]", data.base, offset, min_length),
754762
ProjectionElem::ConstantIndex { offset, min_length, from_end: true } =>
755763
write!(fmt, "{:?}[-{:?} of {:?}]", data.base, offset, min_length),
764+
ProjectionElem::Subslice { from, to } if to == 0 =>
765+
write!(fmt, "{:?}[{:?}:", data.base, from),
766+
ProjectionElem::Subslice { from, to } if from == 0 =>
767+
write!(fmt, "{:?}[:-{:?}]", data.base, to),
768+
ProjectionElem::Subslice { from, to } =>
769+
write!(fmt, "{:?}[{:?}:-{:?}]", data.base,
770+
from, to),
771+
756772
},
757773
}
758774
}
@@ -856,17 +872,6 @@ pub enum Rvalue<'tcx> {
856872
/// away after type-checking and before lowering.
857873
Aggregate(AggregateKind<'tcx>, Vec<Operand<'tcx>>),
858874

859-
/// Generates a slice of the form `&input[from_start..L-from_end]`
860-
/// where `L` is the length of the slice. This is only created by
861-
/// slice pattern matching, so e.g. a pattern of the form `[x, y,
862-
/// .., z]` might create a slice with `from_start=2` and
863-
/// `from_end=1`.
864-
Slice {
865-
input: Lvalue<'tcx>,
866-
from_start: usize,
867-
from_end: usize,
868-
},
869-
870875
InlineAsm {
871876
asm: InlineAsm,
872877
outputs: Vec<Lvalue<'tcx>>,
@@ -972,8 +977,6 @@ impl<'tcx> Debug for Rvalue<'tcx> {
972977
InlineAsm { ref asm, ref outputs, ref inputs } => {
973978
write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs)
974979
}
975-
Slice { ref input, from_start, from_end } =>
976-
write!(fmt, "{:?}[{:?}..-{:?}]", input, from_start, from_end),
977980

978981
Ref(_, borrow_kind, ref lv) => {
979982
let kind_str = match borrow_kind {

src/librustc/mir/tcx.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,20 @@ impl<'a, 'gcx, 'tcx> LvalueTy<'tcx> {
5959
LvalueTy::Ty {
6060
ty: self.to_ty(tcx).builtin_index().unwrap()
6161
},
62+
ProjectionElem::Subslice { from, to } => {
63+
let ty = self.to_ty(tcx);
64+
LvalueTy::Ty {
65+
ty: match ty.sty {
66+
ty::TyArray(inner, size) => {
67+
tcx.mk_array(inner, size-(from as usize)-(to as usize))
68+
}
69+
ty::TySlice(..) => ty,
70+
_ => {
71+
bug!("cannot subslice non-array type: `{:?}`", self)
72+
}
73+
}
74+
}
75+
}
6276
ProjectionElem::Downcast(adt_def1, index) =>
6377
match self.to_ty(tcx).sty {
6478
ty::TyEnum(adt_def, substs) => {
@@ -219,7 +233,6 @@ impl<'a, 'gcx, 'tcx> Mir<'tcx> {
219233
}
220234
}
221235
}
222-
Rvalue::Slice { .. } => None,
223236
Rvalue::InlineAsm { .. } => None
224237
}
225238
}

src/librustc/mir/visit.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -533,15 +533,6 @@ macro_rules! make_mir_visitor {
533533
}
534534
}
535535

536-
Rvalue::Slice { ref $($mutability)* input,
537-
from_start,
538-
from_end } => {
539-
self.visit_lvalue(input, LvalueContext::Slice {
540-
from_start: from_start,
541-
from_end: from_end,
542-
});
543-
}
544-
545536
Rvalue::InlineAsm { ref $($mutability)* outputs,
546537
ref $($mutability)* inputs,
547538
asm: _ } => {
@@ -602,6 +593,8 @@ macro_rules! make_mir_visitor {
602593
match *proj {
603594
ProjectionElem::Deref => {
604595
}
596+
ProjectionElem::Subslice { from: _, to: _ } => {
597+
}
605598
ProjectionElem::Field(_field, ref $($mutability)* ty) => {
606599
self.visit_ty(ty);
607600
}

src/librustc_borrowck/borrowck/mir/abs_domain.rs

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ impl<'tcx> Lift for LvalueElem<'tcx> {
4949
ProjectionElem::Field(f.clone(), ty.clone()),
5050
ProjectionElem::Index(ref i) =>
5151
ProjectionElem::Index(i.lift()),
52+
ProjectionElem::Subslice {from, to} =>
53+
ProjectionElem::Subslice { from: from, to: to },
5254
ProjectionElem::ConstantIndex {offset,min_length,from_end} =>
5355
ProjectionElem::ConstantIndex {
5456
offset: offset,

src/librustc_borrowck/borrowck/mir/gather_moves.rs

-16
Original file line numberDiff line numberDiff line change
@@ -620,22 +620,6 @@ fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> MoveD
620620
Rvalue::Ref(..) |
621621
Rvalue::Len(..) |
622622
Rvalue::InlineAsm { .. } => {}
623-
624-
Rvalue::Slice {..} => {
625-
// A slice pattern `x..` binds `x` to a
626-
// reference; thus no move occurs.
627-
//
628-
// FIXME: I recall arielb1 questioning
629-
// whether this is even a legal thing to
630-
// have as an R-value. The particular
631-
// example where I am seeing this arise is
632-
// `TargetDataLayout::parse(&Session)` in
633-
// `rustc::ty::layout`.
634-
//
635-
// this should be removed soon.
636-
debug!("encountered Rvalue::Slice as RHS of Assign, source: {:?}",
637-
source);
638-
}
639623
}
640624
}
641625
}

0 commit comments

Comments
 (0)