Skip to content

Commit a5eefde

Browse files
committed
Fix binding unsized expressions to ref patterns
1 parent f899513 commit a5eefde

File tree

3 files changed

+42
-7
lines changed

3 files changed

+42
-7
lines changed

Diff for: src/librustc_trans/trans/_match.rs

+17-7
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ pub enum OptResult<'blk, 'tcx: 'blk> {
326326
LowerBound(Result<'blk, 'tcx>)
327327
}
328328

329-
#[derive(Clone, Copy)]
329+
#[derive(Clone, Copy, PartialEq)]
330330
pub enum TransBindingMode {
331331
TrByCopy(/* llbinding */ ValueRef),
332332
TrByMove,
@@ -1000,9 +1000,14 @@ fn compile_submatch<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
10001000
None => {
10011001
let data = &m[0].data;
10021002
for &(ref ident, ref value_ptr) in &m[0].bound_ptrs {
1003-
let llmatch = data.bindings_map[*ident].llmatch;
1004-
call_lifetime_start(bcx, llmatch);
1005-
Store(bcx, *value_ptr, llmatch);
1003+
let binfo = data.bindings_map[*ident];
1004+
call_lifetime_start(bcx, binfo.llmatch);
1005+
if binfo.trmode == TrByRef && type_is_fat_ptr(bcx.tcx(), binfo.ty) {
1006+
expr::copy_fat_ptr(bcx, *value_ptr, binfo.llmatch);
1007+
}
1008+
else {
1009+
Store(bcx, *value_ptr, binfo.llmatch);
1010+
}
10061011
}
10071012
match data.arm.guard {
10081013
Some(ref guard_expr) => {
@@ -1070,7 +1075,6 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
10701075
_ => None
10711076
}
10721077
};
1073-
10741078
match adt_vals {
10751079
Some(field_vals) => {
10761080
let pats = enter_match(bcx, dm, m, col, val, |pats|
@@ -1677,8 +1681,14 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
16771681

16781682
ast::BindByRef(_) => {
16791683
// By ref binding: the value of the variable
1680-
// is the pointer `val` itself.
1681-
Store(bcx, val, llval);
1684+
// is the pointer `val` itself or fat pointer referenced by `val`
1685+
if type_is_fat_ptr(bcx.tcx(), ty) {
1686+
expr::copy_fat_ptr(bcx, val, llval);
1687+
}
1688+
else {
1689+
Store(bcx, val, llval);
1690+
}
1691+
16821692
bcx
16831693
}
16841694
}

Diff for: src/librustc_trans/trans/expr.rs

+5
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,11 @@ pub fn get_dataptr(bcx: Block, fat_ptr: ValueRef) -> ValueRef {
285285
GEPi(bcx, fat_ptr, &[0, abi::FAT_PTR_ADDR])
286286
}
287287

288+
pub fn copy_fat_ptr(bcx: Block, src_ptr: ValueRef, dst_ptr: ValueRef) {
289+
Store(bcx, Load(bcx, get_dataptr(bcx, src_ptr)), get_dataptr(bcx, dst_ptr));
290+
Store(bcx, Load(bcx, get_len(bcx, src_ptr)), get_len(bcx, dst_ptr));
291+
}
292+
288293
// Retrieve the information we are losing (making dynamic) in an unsizing
289294
// adjustment.
290295
// When making a dtor, we need to do different things depending on the

Diff for: src/test/run-pass/match-ref-unsized.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Binding unsized expressions to ref patterns
12+
13+
pub fn main() {
14+
let ref a = *"abcdef";
15+
assert_eq!(a, "abcdef");
16+
17+
match *"12345" {
18+
ref b => { assert_eq!(b, "12345") }
19+
}
20+
}

0 commit comments

Comments
 (0)