Skip to content

Commit b0aad7d

Browse files
committed
Auto merge of #23361 - petrochenkov:refdst, r=jakub-
After this patch code like `let ref a = *"abcdef"` doesn't cause ICE anymore. Required for #23121 There are still places in rustc_trans where pointers are always assumed to be thin. In particular, #19064 is not resolved by this patch.
2 parents ecf8c64 + a5eefde commit b0aad7d

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,
@@ -1017,9 +1017,14 @@ fn compile_submatch<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
10171017
None => {
10181018
let data = &m[0].data;
10191019
for &(ref ident, ref value_ptr) in &m[0].bound_ptrs {
1020-
let llmatch = data.bindings_map[*ident].llmatch;
1021-
call_lifetime_start(bcx, llmatch);
1022-
Store(bcx, *value_ptr, llmatch);
1020+
let binfo = data.bindings_map[*ident];
1021+
call_lifetime_start(bcx, binfo.llmatch);
1022+
if binfo.trmode == TrByRef && type_is_fat_ptr(bcx.tcx(), binfo.ty) {
1023+
expr::copy_fat_ptr(bcx, *value_ptr, binfo.llmatch);
1024+
}
1025+
else {
1026+
Store(bcx, *value_ptr, binfo.llmatch);
1027+
}
10231028
}
10241029
match data.arm.guard {
10251030
Some(ref guard_expr) => {
@@ -1087,7 +1092,6 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
10871092
_ => None
10881093
}
10891094
};
1090-
10911095
match adt_vals {
10921096
Some(field_vals) => {
10931097
let pats = enter_match(bcx, dm, m, col, val, |pats|
@@ -1694,8 +1698,14 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
16941698

16951699
ast::BindByRef(_) => {
16961700
// By ref binding: the value of the variable
1697-
// is the pointer `val` itself.
1698-
Store(bcx, val, llval);
1701+
// is the pointer `val` itself or fat pointer referenced by `val`
1702+
if type_is_fat_ptr(bcx.tcx(), ty) {
1703+
expr::copy_fat_ptr(bcx, val, llval);
1704+
}
1705+
else {
1706+
Store(bcx, val, llval);
1707+
}
1708+
16991709
bcx
17001710
}
17011711
}

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
//

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)