Skip to content

Commit 7504d2a

Browse files
authored
Merge pull request #36620 from pnkfelix/beta-next
Beta backports
2 parents f1376ce + f0d4add commit 7504d2a

File tree

4 files changed

+133
-31
lines changed

4 files changed

+133
-31
lines changed

src/librustc_trans/mir/block.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use common::{C_bool, C_str_slice, C_struct, C_u32, C_undef};
2323
use consts;
2424
use debuginfo::DebugLoc;
2525
use Disr;
26+
use expr;
2627
use machine::{llalign_of_min, llbitsize_of_real};
2728
use meth;
2829
use type_of;
@@ -242,10 +243,28 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
242243
let lvalue = self.trans_lvalue(&bcx, location);
243244
let drop_fn = glue::get_drop_glue(bcx.ccx(), ty);
244245
let drop_ty = glue::get_drop_glue_type(bcx.tcx(), ty);
245-
let llvalue = if drop_ty != ty {
246-
bcx.pointercast(lvalue.llval, type_of::type_of(bcx.ccx(), drop_ty).ptr_to())
246+
let is_sized = common::type_is_sized(bcx.tcx(), ty);
247+
let llvalue = if is_sized {
248+
if drop_ty != ty {
249+
bcx.pointercast(lvalue.llval, type_of::type_of(bcx.ccx(), drop_ty).ptr_to())
250+
} else {
251+
lvalue.llval
252+
}
247253
} else {
248-
lvalue.llval
254+
// FIXME(#36457) Currently drop glue takes sized
255+
// values as a `*(data, meta)`, but elsewhere in
256+
// MIR we pass `(data, meta)` as two separate
257+
// arguments. It would be better to fix drop glue,
258+
// but I am shooting for a quick fix to #35546
259+
// here that can be cleanly backported to beta, so
260+
// I want to avoid touching all of trans.
261+
bcx.with_block(|bcx| {
262+
let scratch = base::alloc_ty(bcx, ty, "drop");
263+
base::call_lifetime_start(bcx, scratch);
264+
build::Store(bcx, lvalue.llval, expr::get_dataptr(bcx, scratch));
265+
build::Store(bcx, lvalue.llextra, expr::get_meta(bcx, scratch));
266+
scratch
267+
})
249268
};
250269
if let Some(unwind) = unwind {
251270
bcx.invoke(drop_fn,

src/librustc_trans/mir/constant.rs

+58-28
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use value::Value;
3636

3737
use syntax_pos::{Span, DUMMY_SP};
3838

39+
use std::fmt;
3940
use std::ptr;
4041

4142
use super::operand::{OperandRef, OperandValue};
@@ -147,6 +148,12 @@ impl<'tcx> Const<'tcx> {
147148
}
148149
}
149150

151+
impl<'tcx> fmt::Debug for Const<'tcx> {
152+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
153+
write!(f, "Const({:?}: {:?})", Value(self.llval), self.ty)
154+
}
155+
}
156+
150157
#[derive(Copy, Clone)]
151158
enum Base {
152159
/// A constant value without an unique address.
@@ -466,7 +473,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
466473

467474
fn const_operand(&self, operand: &mir::Operand<'tcx>, span: Span)
468475
-> Result<Const<'tcx>, ConstEvalFailure> {
469-
match *operand {
476+
debug!("const_operand({:?} @ {:?})", operand, span);
477+
let result = match *operand {
470478
mir::Operand::Consume(ref lvalue) => {
471479
Ok(self.const_lvalue(lvalue, span)?.to_const(span))
472480
}
@@ -495,29 +503,41 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
495503
}
496504
}
497505
}
498-
}
506+
};
507+
debug!("const_operand({:?} @ {:?}) = {:?}", operand, span,
508+
result.as_ref().ok());
509+
result
510+
}
511+
512+
fn const_array(&self, array_ty: Ty<'tcx>, fields: &[ValueRef])
513+
-> Const<'tcx>
514+
{
515+
let elem_ty = array_ty.builtin_index().unwrap_or_else(|| {
516+
bug!("bad array type {:?}", array_ty)
517+
});
518+
let llunitty = type_of::type_of(self.ccx, elem_ty);
519+
// If the array contains enums, an LLVM array won't work.
520+
let val = if fields.iter().all(|&f| val_ty(f) == llunitty) {
521+
C_array(llunitty, fields)
522+
} else {
523+
C_struct(self.ccx, fields, false)
524+
};
525+
Const::new(val, array_ty)
499526
}
500527

501528
fn const_rvalue(&self, rvalue: &mir::Rvalue<'tcx>,
502529
dest_ty: Ty<'tcx>, span: Span)
503530
-> Result<Const<'tcx>, ConstEvalFailure> {
504531
let tcx = self.ccx.tcx();
532+
debug!("const_rvalue({:?}: {:?} @ {:?})", rvalue, dest_ty, span);
505533
let val = match *rvalue {
506534
mir::Rvalue::Use(ref operand) => self.const_operand(operand, span)?,
507535

508536
mir::Rvalue::Repeat(ref elem, ref count) => {
509537
let elem = self.const_operand(elem, span)?;
510538
let size = count.value.as_u64(tcx.sess.target.uint_type);
511539
let fields = vec![elem.llval; size as usize];
512-
513-
let llunitty = type_of::type_of(self.ccx, elem.ty);
514-
// If the array contains enums, an LLVM array won't work.
515-
let val = if val_ty(elem.llval) == llunitty {
516-
C_array(llunitty, &fields)
517-
} else {
518-
C_struct(self.ccx, &fields, false)
519-
};
520-
Const::new(val, dest_ty)
540+
self.const_array(dest_ty, &fields)
521541
}
522542

523543
mir::Rvalue::Aggregate(ref kind, ref operands) => {
@@ -541,22 +561,26 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
541561
self.monomorphize(&substs));
542562
}
543563

544-
let val = if let mir::AggregateKind::Adt(adt_def, index, _) = *kind {
545-
let repr = adt::represent_type(self.ccx, dest_ty);
546-
let disr = Disr::from(adt_def.variants[index].disr_val);
547-
adt::trans_const(self.ccx, &repr, disr, &fields)
548-
} else if let ty::TyArray(elem_ty, _) = dest_ty.sty {
549-
let llunitty = type_of::type_of(self.ccx, elem_ty);
550-
// If the array contains enums, an LLVM array won't work.
551-
if fields.iter().all(|&f| val_ty(f) == llunitty) {
552-
C_array(llunitty, &fields)
553-
} else {
554-
C_struct(self.ccx, &fields, false)
564+
match *kind {
565+
mir::AggregateKind::Vec => {
566+
self.const_array(dest_ty, &fields)
555567
}
556-
} else {
557-
C_struct(self.ccx, &fields, false)
558-
};
559-
Const::new(val, dest_ty)
568+
mir::AggregateKind::Adt(..) |
569+
mir::AggregateKind::Closure(..) |
570+
mir::AggregateKind::Tuple => {
571+
let disr = match *kind {
572+
mir::AggregateKind::Adt(adt_def, index, _) => {
573+
Disr::from(adt_def.variants[index].disr_val)
574+
}
575+
_ => Disr(0)
576+
};
577+
let repr = adt::represent_type(self.ccx, dest_ty);
578+
Const::new(
579+
adt::trans_const(self.ccx, &repr, disr, &fields),
580+
dest_ty
581+
)
582+
}
583+
}
560584
}
561585

562586
mir::Rvalue::Cast(ref kind, ref source, cast_ty) => {
@@ -780,6 +804,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
780804
_ => span_bug!(span, "{:?} in constant", rvalue)
781805
};
782806

807+
debug!("const_rvalue({:?}: {:?} @ {:?}) = {:?}", rvalue, dest_ty, span, val);
808+
783809
Ok(val)
784810
}
785811

@@ -881,6 +907,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
881907
constant: &mir::Constant<'tcx>)
882908
-> Const<'tcx>
883909
{
910+
debug!("trans_constant({:?})", constant);
884911
let ty = bcx.monomorphize(&constant.ty);
885912
let result = match constant.literal.clone() {
886913
mir::Literal::Item { def_id, substs } => {
@@ -905,7 +932,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
905932
}
906933
};
907934

908-
match result {
935+
let result = match result {
909936
Ok(v) => v,
910937
Err(ConstEvalFailure::Compiletime(_)) => {
911938
// We've errored, so we don't have to produce working code.
@@ -917,7 +944,10 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
917944
"MIR constant {:?} results in runtime panic: {:?}",
918945
constant, err.description())
919946
}
920-
}
947+
};
948+
949+
debug!("trans_constant({:?}) = {:?}", constant, result);
950+
result
921951
}
922952
}
923953

src/test/run-pass/issue-35546.rs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2016 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+
// Regression test for #35546. Check that we are able to codegen
12+
// this. Before we had problems because of the drop glue signature
13+
// around dropping a trait object (specifically, when dropping the
14+
// `value` field of `Node<Send>`).
15+
16+
struct Node<T: ?Sized + Send> {
17+
next: Option<Box<Node<Send>>>,
18+
value: T,
19+
}
20+
21+
fn clear(head: &mut Option<Box<Node<Send>>>) {
22+
match head.take() {
23+
Some(node) => *head = node.next,
24+
None => (),
25+
}
26+
}
27+
28+
fn main() {}

src/test/run-pass/issue-36401.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2016 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+
#[derive(Debug)]
12+
pub enum Event {
13+
Key(u8),
14+
Resize,
15+
Unknown(u16),
16+
}
17+
18+
static XTERM_SINGLE_BYTES : [(u8, Event); 1] = [(1, Event::Resize)];
19+
20+
fn main() {
21+
match XTERM_SINGLE_BYTES[0] {
22+
(1, Event::Resize) => {},
23+
ref bad => panic!("unexpected {:?}", bad)
24+
}
25+
}

0 commit comments

Comments
 (0)