Fix binding unsized expressions to ref patterns
This commit is contained in:
parent
f899513a30
commit
a5eefdef3c
@ -326,7 +326,7 @@ pub enum OptResult<'blk, 'tcx: 'blk> {
|
||||
LowerBound(Result<'blk, 'tcx>)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum TransBindingMode {
|
||||
TrByCopy(/* llbinding */ ValueRef),
|
||||
TrByMove,
|
||||
@ -1000,9 +1000,14 @@ fn compile_submatch<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
None => {
|
||||
let data = &m[0].data;
|
||||
for &(ref ident, ref value_ptr) in &m[0].bound_ptrs {
|
||||
let llmatch = data.bindings_map[*ident].llmatch;
|
||||
call_lifetime_start(bcx, llmatch);
|
||||
Store(bcx, *value_ptr, llmatch);
|
||||
let binfo = data.bindings_map[*ident];
|
||||
call_lifetime_start(bcx, binfo.llmatch);
|
||||
if binfo.trmode == TrByRef && type_is_fat_ptr(bcx.tcx(), binfo.ty) {
|
||||
expr::copy_fat_ptr(bcx, *value_ptr, binfo.llmatch);
|
||||
}
|
||||
else {
|
||||
Store(bcx, *value_ptr, binfo.llmatch);
|
||||
}
|
||||
}
|
||||
match data.arm.guard {
|
||||
Some(ref guard_expr) => {
|
||||
@ -1070,7 +1075,6 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
_ => None
|
||||
}
|
||||
};
|
||||
|
||||
match adt_vals {
|
||||
Some(field_vals) => {
|
||||
let pats = enter_match(bcx, dm, m, col, val, |pats|
|
||||
@ -1677,8 +1681,14 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
|
||||
ast::BindByRef(_) => {
|
||||
// By ref binding: the value of the variable
|
||||
// is the pointer `val` itself.
|
||||
Store(bcx, val, llval);
|
||||
// is the pointer `val` itself or fat pointer referenced by `val`
|
||||
if type_is_fat_ptr(bcx.tcx(), ty) {
|
||||
expr::copy_fat_ptr(bcx, val, llval);
|
||||
}
|
||||
else {
|
||||
Store(bcx, val, llval);
|
||||
}
|
||||
|
||||
bcx
|
||||
}
|
||||
}
|
||||
|
@ -285,6 +285,11 @@ pub fn get_dataptr(bcx: Block, fat_ptr: ValueRef) -> ValueRef {
|
||||
GEPi(bcx, fat_ptr, &[0, abi::FAT_PTR_ADDR])
|
||||
}
|
||||
|
||||
pub fn copy_fat_ptr(bcx: Block, src_ptr: ValueRef, dst_ptr: ValueRef) {
|
||||
Store(bcx, Load(bcx, get_dataptr(bcx, src_ptr)), get_dataptr(bcx, dst_ptr));
|
||||
Store(bcx, Load(bcx, get_len(bcx, src_ptr)), get_len(bcx, dst_ptr));
|
||||
}
|
||||
|
||||
// Retrieve the information we are losing (making dynamic) in an unsizing
|
||||
// adjustment.
|
||||
// When making a dtor, we need to do different things depending on the
|
||||
|
20
src/test/run-pass/match-ref-unsized.rs
Normal file
20
src/test/run-pass/match-ref-unsized.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Binding unsized expressions to ref patterns
|
||||
|
||||
pub fn main() {
|
||||
let ref a = *"abcdef";
|
||||
assert_eq!(a, "abcdef");
|
||||
|
||||
match *"12345" {
|
||||
ref b => { assert_eq!(b, "12345") }
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user