Skip to content

Commit 1dbc467

Browse files
committed
auto merge of #9643 : thestinger/rust/immediate, r=alexcrichton
2 parents bc6dd90 + ab0a884 commit 1dbc467

File tree

8 files changed

+84
-49
lines changed

8 files changed

+84
-49
lines changed

src/librustc/middle/trans/base.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1121,13 +1121,13 @@ pub fn do_spill_noroot(cx: @mut Block, v: ValueRef) -> ValueRef {
11211121

11221122
pub fn spill_if_immediate(cx: @mut Block, v: ValueRef, t: ty::t) -> ValueRef {
11231123
let _icx = push_ctxt("spill_if_immediate");
1124-
if ty::type_is_immediate(cx.tcx(), t) { return do_spill(cx, v, t); }
1124+
if type_is_immediate(cx.tcx(), t) { return do_spill(cx, v, t); }
11251125
return v;
11261126
}
11271127

11281128
pub fn load_if_immediate(cx: @mut Block, v: ValueRef, t: ty::t) -> ValueRef {
11291129
let _icx = push_ctxt("load_if_immediate");
1130-
if ty::type_is_immediate(cx.tcx(), t) { return Load(cx, v); }
1130+
if type_is_immediate(cx.tcx(), t) { return Load(cx, v); }
11311131
return v;
11321132
}
11331133

src/librustc/middle/trans/common.rs

+23-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use driver::session;
1515
use driver::session::Session;
1616
use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef};
1717
use lib::llvm::{True, False, Bool};
18-
use lib::llvm::{llvm};
18+
use lib::llvm::llvm;
1919
use lib;
2020
use middle::lang_items::LangItem;
2121
use middle::trans::base;
@@ -28,24 +28,43 @@ use middle::ty::substs;
2828
use middle::ty;
2929
use middle::typeck;
3030
use middle::borrowck::root_map_key;
31-
use util::ppaux::{Repr};
31+
use util::ppaux::Repr;
3232

3333
use middle::trans::type_::Type;
3434

3535
use std::c_str::ToCStr;
3636
use std::cast::transmute;
3737
use std::cast;
38-
use std::hashmap::{HashMap};
38+
use std::hashmap::HashMap;
3939
use std::libc::{c_uint, c_longlong, c_ulonglong, c_char};
4040
use std::vec;
41-
use syntax::ast::{Name,Ident};
41+
use syntax::ast::{Name, Ident};
4242
use syntax::ast_map::{path, path_elt, path_pretty_name};
4343
use syntax::codemap::Span;
4444
use syntax::parse::token;
4545
use syntax::{ast, ast_map};
4646

4747
pub use middle::trans::context::CrateContext;
4848

49+
fn type_is_newtype_immediate(cx: ty::ctxt, ty: ty::t) -> bool {
50+
match ty::get(ty).sty {
51+
ty::ty_struct(def_id, ref substs) => {
52+
let fields = ty::struct_fields(cx, def_id, substs);
53+
fields.len() == 1 &&
54+
fields[0].ident.name == token::special_idents::unnamed_field.name &&
55+
type_is_immediate(cx, fields[0].mt.ty)
56+
}
57+
_ => false
58+
}
59+
}
60+
61+
pub fn type_is_immediate(cx: ty::ctxt, ty: ty::t) -> bool {
62+
ty::type_is_scalar(ty) || ty::type_is_boxed(ty) ||
63+
ty::type_is_unique(ty) || ty::type_is_region_ptr(ty) ||
64+
type_is_newtype_immediate(cx, ty) ||
65+
ty::type_is_simd(cx, ty)
66+
}
67+
4968
pub fn gensym_name(name: &str) -> (Ident, path_elt) {
5069
let name = token::gensym(name);
5170
let ident = Ident::new(name);

src/librustc/middle/trans/datum.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ pub fn appropriate_mode(tcx: ty::ctxt, ty: ty::t) -> DatumMode {
197197

198198
if ty::type_is_voidish(ty) {
199199
ByValue
200-
} else if ty::type_is_immediate(tcx, ty) {
200+
} else if type_is_immediate(tcx, ty) {
201201
ByValue
202202
} else {
203203
ByRef(RevokeClean)
@@ -667,7 +667,7 @@ impl Datum {
667667
ByValue => {
668668
// Actually, this case cannot happen right
669669
// now, because enums are never immediate.
670-
assert!(ty::type_is_immediate(bcx.tcx(), ty));
670+
assert!(type_is_immediate(bcx.tcx(), ty));
671671
(Some(Datum {ty: ty, ..*self}), bcx)
672672
}
673673
};
@@ -699,7 +699,7 @@ impl Datum {
699699
)
700700
}
701701
ByValue => {
702-
assert!(ty::type_is_immediate(bcx.tcx(), ty));
702+
assert!(type_is_immediate(bcx.tcx(), ty));
703703
(
704704
Some(Datum {
705705
val: ExtractValue(bcx, self.val, 0),

src/librustc/middle/trans/glue.rs

+3-13
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,9 @@ pub fn drop_ty(cx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
7777

7878
pub fn drop_ty_immediate(bcx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
7979
let _icx = push_ctxt("drop_ty_immediate");
80-
match ty::get(t).sty {
81-
ty::ty_uniq(_)
82-
| ty::ty_evec(_, ty::vstore_uniq)
83-
| ty::ty_estr(ty::vstore_uniq) => {
84-
free_ty_immediate(bcx, v, t)
85-
}
86-
ty::ty_box(_) | ty::ty_opaque_box
87-
| ty::ty_evec(_, ty::vstore_box)
88-
| ty::ty_estr(ty::vstore_box) => {
89-
decr_refcnt_maybe_free(bcx, v, None, t)
90-
}
91-
_ => bcx.tcx().sess.bug("drop_ty_immediate: non-box ty")
92-
}
80+
let vp = alloca(bcx, type_of(bcx.ccx(), t), "");
81+
Store(bcx, v, vp);
82+
drop_ty(bcx, vp, t)
9383
}
9484

9585
pub fn free_ty(cx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {

src/librustc/middle/trans/intrinsic.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
278278
"uninit" => {
279279
// Do nothing, this is effectively a no-op
280280
let retty = substs.tys[0];
281-
if ty::type_is_immediate(ccx.tcx, retty) && !ty::type_is_nil(retty) {
281+
if type_is_immediate(ccx.tcx, retty) && !ty::type_is_nil(retty) {
282282
unsafe {
283283
Ret(bcx, lib::llvm::llvm::LLVMGetUndef(type_of(ccx, retty).to_ref()));
284284
}
@@ -316,7 +316,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
316316

317317
if !ty::type_is_voidish(out_type) {
318318
let llsrcval = get_param(decl, first_real_arg);
319-
if ty::type_is_immediate(ccx.tcx, in_type) {
319+
if type_is_immediate(ccx.tcx, in_type) {
320320
match fcx.llretptr {
321321
Some(llretptr) => {
322322
Store(bcx, llsrcval, PointerCast(bcx, llretptr, llintype.ptr_to()));
@@ -335,7 +335,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
335335
}
336336
}
337337
}
338-
} else if ty::type_is_immediate(ccx.tcx, out_type) {
338+
} else if type_is_immediate(ccx.tcx, out_type) {
339339
let llsrcptr = PointerCast(bcx, llsrcval, llouttype.ptr_to());
340340
let ll_load = Load(bcx, llsrcptr);
341341
Ret(bcx, ll_load);

src/librustc/middle/trans/type_of.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ use syntax::ast;
2121
use syntax::opt_vec;
2222

2323
pub fn arg_is_indirect(ccx: &CrateContext, arg_ty: ty::t) -> bool {
24-
!ty::type_is_immediate(ccx.tcx, arg_ty)
24+
!type_is_immediate(ccx.tcx, arg_ty)
2525
}
2626

2727
pub fn return_uses_outptr(tcx: ty::ctxt, ty: ty::t) -> bool {
28-
!ty::type_is_immediate(tcx, ty)
28+
!type_is_immediate(tcx, ty)
2929
}
3030

3131
pub fn type_of_explicit_arg(ccx: &mut CrateContext, arg_ty: ty::t) -> Type {

src/librustc/middle/ty.rs

+10-22
Original file line numberDiff line numberDiff line change
@@ -1752,25 +1752,6 @@ pub fn type_is_scalar(ty: t) -> bool {
17521752
}
17531753
}
17541754

1755-
fn type_is_newtype_immediate(cx: ctxt, ty: t) -> bool {
1756-
match get(ty).sty {
1757-
ty_struct(def_id, ref substs) => {
1758-
let fields = struct_fields(cx, def_id, substs);
1759-
fields.len() == 1 &&
1760-
fields[0].ident.name == token::special_idents::unnamed_field.name &&
1761-
type_is_immediate(cx, fields[0].mt.ty)
1762-
}
1763-
_ => false
1764-
}
1765-
}
1766-
1767-
pub fn type_is_immediate(cx: ctxt, ty: t) -> bool {
1768-
return type_is_scalar(ty) || type_is_boxed(ty) ||
1769-
type_is_unique(ty) || type_is_region_ptr(ty) ||
1770-
type_is_newtype_immediate(cx, ty) ||
1771-
type_is_simd(cx, ty);
1772-
}
1773-
17741755
pub fn type_needs_drop(cx: ctxt, ty: t) -> bool {
17751756
type_contents(cx, ty).needs_drop(cx)
17761757
}
@@ -2538,6 +2519,13 @@ pub fn type_structurally_contains_uniques(cx: ctxt, ty: t) -> bool {
25382519
});
25392520
}
25402521

2522+
pub fn type_is_trait(ty: t) -> bool {
2523+
match get(ty).sty {
2524+
ty_trait(*) => true,
2525+
_ => false
2526+
}
2527+
}
2528+
25412529
pub fn type_is_integral(ty: t) -> bool {
25422530
match get(ty).sty {
25432531
ty_infer(IntVar(_)) | ty_int(_) | ty_uint(_) => true,
@@ -3289,10 +3277,10 @@ pub fn expr_kind(tcx: ctxt,
32893277
ast::ExprCast(*) => {
32903278
match tcx.node_types.find(&(expr.id as uint)) {
32913279
Some(&t) => {
3292-
if ty::type_is_immediate(tcx, t) {
3293-
RvalueDatumExpr
3294-
} else {
3280+
if type_is_trait(t) {
32953281
RvalueDpsExpr
3282+
} else {
3283+
RvalueDatumExpr
32963284
}
32973285
}
32983286
None => {

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

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2013 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+
struct Wrapper(~str);
12+
13+
impl Wrapper {
14+
pub fn new(wrapped: ~str) -> Wrapper {
15+
Wrapper(wrapped)
16+
}
17+
18+
pub fn say_hi(&self) {
19+
println(fmt!("hello %s", **self));
20+
}
21+
}
22+
23+
impl Drop for Wrapper {
24+
fn drop(&mut self) {}
25+
}
26+
27+
pub fn main() {
28+
{
29+
// This runs without complaint.
30+
let x = Wrapper::new(~"Bob");
31+
x.say_hi();
32+
}
33+
{
34+
// This fails to compile, circa 0.8-89-gc635fba.
35+
// error: internal compiler error: drop_ty_immediate: non-box ty
36+
Wrapper::new(~"Bob").say_hi();
37+
}
38+
}

0 commit comments

Comments
 (0)