Skip to content

Commit 1177f50

Browse files
committed
---
yaml --- r: 75758 b: refs/heads/master c: cdbdfe8 h: refs/heads/master v: v3
1 parent aef6233 commit 1177f50

35 files changed

+793
-519
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: a8c3fe45c6138cd1f4d143fdb0e843ee2d4759b2
2+
refs/heads/master: cdbdfe88a5e95428055f0c630bd3346a78436486
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 67c954e365970e4c2cd06f0c50724656d7010f45
55
refs/heads/try: 10089455287dcc3652b984ab4bfd6971e1b5f302

trunk/src/librustc/back/passes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ pub static transform_passes : &'static [(&'static str, &'static str)] = &'static
293293
("scalarrepl", "Scalar Replacement of Aggregates (DT)"),
294294
("scalarrepl-ssa", "Scalar Replacement of Aggregates (SSAUp)"),
295295
("sccp", "Sparse Conditional Constant Propagation"),
296+
("simplify-libcalls", "Simplify well-known library calls"),
296297
("simplifycfg", "Simplify the CFG"),
297298
("sink", "Code sinking"),
298299
("strip", "Strip all symbols from a module"),

trunk/src/librustc/lib/llvm.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ pub enum Attribute {
8989
ReturnsTwiceAttribute = 1 << 29,
9090
UWTableAttribute = 1 << 30,
9191
NonLazyBindAttribute = 1 << 31,
92+
93+
// Not added to LLVM yet, so may need to stay updated if LLVM changes.
94+
// FIXME(#8199): if this changes, be sure to change the relevant constant
95+
// down below
96+
// FixedStackSegment = 1 << 41,
9297
}
9398

9499
// enum for the LLVM IntPredicate type
@@ -842,9 +847,7 @@ pub mod llvm {
842847
#[fast_ffi]
843848
pub fn LLVMSetGC(Fn: ValueRef, Name: *c_char);
844849
#[fast_ffi]
845-
pub fn LLVMAddFunctionAttr(Fn: ValueRef, PA: c_uint);
846-
#[fast_ffi]
847-
pub fn LLVMAddFunctionAttrString(Fn: ValueRef, Name: *c_char);
850+
pub fn LLVMAddFunctionAttr(Fn: ValueRef, PA: c_uint, HighPA: c_uint);
848851
#[fast_ffi]
849852
pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;
850853
#[fast_ffi]
@@ -2135,7 +2138,23 @@ pub fn ConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef {
21352138

21362139
pub fn SetFunctionAttribute(Fn: ValueRef, attr: Attribute) {
21372140
unsafe {
2138-
llvm::LLVMAddFunctionAttr(Fn, attr as c_uint)
2141+
let attr = attr as u64;
2142+
let lower = attr & 0xffffffff;
2143+
let upper = (attr >> 32) & 0xffffffff;
2144+
llvm::LLVMAddFunctionAttr(Fn, lower as c_uint, upper as c_uint);
2145+
}
2146+
}
2147+
2148+
// FIXME(#8199): this shouldn't require this hackery. On i686
2149+
// (FixedStackSegment as u64) will return 0 instead of 1 << 41.
2150+
// Furthermore, if we use a match of any sort then an LLVM
2151+
// assertion is generated!
2152+
pub fn SetFixedStackSegmentAttribute(Fn: ValueRef) {
2153+
unsafe {
2154+
let attr = 1u64 << 41;
2155+
let lower = attr & 0xffffffff;
2156+
let upper = (attr >> 32) & 0xffffffff;
2157+
llvm::LLVMAddFunctionAttr(Fn, lower as c_uint, upper as c_uint);
21392158
}
21402159
}
21412160
/* Memory-managed object interface to type handles. */

trunk/src/librustc/metadata/decoder.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,9 +375,21 @@ pub fn get_trait_def(cdata: cmd,
375375
let tp_defs = item_ty_param_defs(item_doc, tcx, cdata,
376376
tag_items_data_item_ty_param_bounds);
377377
let rp = item_ty_region_param(item_doc);
378+
let mut bounds = ty::EmptyBuiltinBounds();
379+
// Collect the builtin bounds from the encoded supertraits.
380+
// FIXME(#8559): They should be encoded directly.
381+
do reader::tagged_docs(item_doc, tag_item_super_trait_ref) |trait_doc| {
382+
// NB. Bypasses real supertraits. See get_supertraits() if you wanted them.
383+
let trait_ref = doc_trait_ref(trait_doc, tcx, cdata);
384+
do tcx.lang_items.to_builtin_kind(trait_ref.def_id).map_move |bound| {
385+
bounds.add(bound);
386+
};
387+
true
388+
};
378389
ty::TraitDef {
379390
generics: ty::Generics {type_param_defs: tp_defs,
380391
region_param: rp},
392+
bounds: bounds,
381393
trait_ref: @item_trait_ref(item_doc, tcx, cdata)
382394
}
383395
}
@@ -929,7 +941,13 @@ pub fn get_supertraits(cdata: cmd, id: ast::NodeId, tcx: ty::ctxt)
929941
let mut results = ~[];
930942
let item_doc = lookup_item(id, cdata.data);
931943
do reader::tagged_docs(item_doc, tag_item_super_trait_ref) |trait_doc| {
932-
results.push(@doc_trait_ref(trait_doc, tcx, cdata));
944+
// NB. Only reads the ones that *aren't* builtin-bounds. See also
945+
// get_trait_def() for collecting the builtin bounds.
946+
// FIXME(#8559): The builtin bounds shouldn't be encoded in the first place.
947+
let trait_ref = doc_trait_ref(trait_doc, tcx, cdata);
948+
if tcx.lang_items.to_builtin_kind(trait_ref.def_id).is_none() {
949+
results.push(@trait_ref);
950+
}
933951
true
934952
};
935953
return results;

trunk/src/librustc/metadata/encoder.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
10761076
ebml_w.end_tag();
10771077
}
10781078
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
1079+
// FIXME(#8559): This should use the tcx's supertrait cache instead of
1080+
// reading the AST's list, because the former has already filtered out
1081+
// the builtin-kinds-as-supertraits. See corresponding fixme in decoder.
10791082
for ast_trait_ref in super_traits.iter() {
10801083
let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
10811084
encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_super_trait_ref);

trunk/src/librustc/middle/kind.rs

Lines changed: 35 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ use syntax::visit::Visitor;
5050
// primitives in the stdlib are explicitly annotated to only take sendable
5151
// types.
5252

53-
pub static try_adding: &'static str = "Try adding a move";
54-
5553
#[deriving(Clone)]
5654
pub struct Context {
5755
tcx: ty::ctxt,
@@ -77,9 +75,6 @@ impl Visitor<Context> for KindAnalysisVisitor {
7775
fn visit_item(&mut self, i:@item, e:Context) {
7876
check_item(self, i, e);
7977
}
80-
fn visit_block(&mut self, b:&Block, e:Context) {
81-
check_block(self, b, e);
82-
}
8378
}
8479

8580
pub fn check_crate(tcx: ty::ctxt,
@@ -125,46 +120,47 @@ fn check_struct_safe_for_destructor(cx: Context,
125120
}
126121
}
127122

128-
fn check_block(visitor: &mut KindAnalysisVisitor,
129-
block: &Block,
130-
cx: Context) {
131-
visit::walk_block(visitor, block, cx);
123+
fn check_impl_of_trait(cx: Context, it: @item, trait_ref: &trait_ref, self_type: &Ty) {
124+
let ast_trait_def = cx.tcx.def_map.find(&trait_ref.ref_id)
125+
.expect("trait ref not in def map!");
126+
let trait_def_id = ast_util::def_id_of_def(*ast_trait_def);
127+
let trait_def = cx.tcx.trait_defs.find(&trait_def_id)
128+
.expect("trait def not in trait-defs map!");
129+
130+
// If this trait has builtin-kind supertraits, meet them.
131+
let self_ty: ty::t = ty::node_id_to_type(cx.tcx, it.id);
132+
error!("checking impl with self type %?", ty::get(self_ty).sty);
133+
do check_builtin_bounds(cx, self_ty, trait_def.bounds) |missing| {
134+
cx.tcx.sess.span_err(self_type.span,
135+
fmt!("the type `%s', which does not fulfill `%s`, cannot implement this \
136+
trait", ty_to_str(cx.tcx, self_ty), missing.user_string(cx.tcx)));
137+
cx.tcx.sess.span_note(self_type.span,
138+
fmt!("types implementing this trait must fulfill `%s`",
139+
trait_def.bounds.user_string(cx.tcx)));
140+
}
141+
142+
// If this is a destructor, check kinds.
143+
if cx.tcx.lang_items.drop_trait() == Some(trait_def_id) {
144+
match self_type.node {
145+
ty_path(_, ref bounds, path_node_id) => {
146+
assert!(bounds.is_none());
147+
let struct_def = cx.tcx.def_map.get_copy(&path_node_id);
148+
let struct_did = ast_util::def_id_of_def(struct_def);
149+
check_struct_safe_for_destructor(cx, self_type.span, struct_did);
150+
}
151+
_ => {
152+
cx.tcx.sess.span_bug(self_type.span,
153+
"the self type for the Drop trait impl is not a path");
154+
}
155+
}
156+
}
132157
}
133158

134159
fn check_item(visitor: &mut KindAnalysisVisitor, item: @item, cx: Context) {
135-
// If this is a destructor, check kinds.
136160
if !attr::contains_name(item.attrs, "unsafe_destructor") {
137161
match item.node {
138162
item_impl(_, Some(ref trait_ref), ref self_type, _) => {
139-
match cx.tcx.def_map.find(&trait_ref.ref_id) {
140-
None => cx.tcx.sess.bug("trait ref not in def map!"),
141-
Some(&trait_def) => {
142-
let trait_def_id = ast_util::def_id_of_def(trait_def);
143-
if cx.tcx.lang_items.drop_trait() == Some(trait_def_id) {
144-
// Yes, it's a destructor.
145-
match self_type.node {
146-
ty_path(_, ref bounds, path_node_id) => {
147-
assert!(bounds.is_none());
148-
let struct_def = cx.tcx.def_map.get_copy(
149-
&path_node_id);
150-
let struct_did =
151-
ast_util::def_id_of_def(struct_def);
152-
check_struct_safe_for_destructor(
153-
cx,
154-
self_type.span,
155-
struct_did);
156-
}
157-
_ => {
158-
cx.tcx.sess.span_bug(self_type.span,
159-
"the self type for \
160-
the Drop trait \
161-
impl is not a \
162-
path");
163-
}
164-
}
165-
}
166-
}
167-
}
163+
check_impl_of_trait(cx, item, trait_ref, self_type);
168164
}
169165
_ => {}
170166
}

trunk/src/librustc/middle/lang_items.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use driver::session::Session;
2424
use metadata::csearch::each_lang_item;
2525
use metadata::cstore::iter_crate_data;
26+
use middle::ty::{BuiltinBound, BoundFreeze, BoundSend, BoundSized};
2627
use syntax::ast::{Crate, def_id, MetaItem};
2728
use syntax::ast_util::local_def;
2829
use syntax::attr::AttrMetaMethods;
@@ -158,6 +159,18 @@ impl LanguageItems {
158159
}
159160
}
160161

162+
pub fn to_builtin_kind(&self, id: def_id) -> Option<BuiltinBound> {
163+
if Some(id) == self.freeze_trait() {
164+
Some(BoundFreeze)
165+
} else if Some(id) == self.send_trait() {
166+
Some(BoundSend)
167+
} else if Some(id) == self.sized_trait() {
168+
Some(BoundSized)
169+
} else {
170+
None
171+
}
172+
}
173+
161174
pub fn freeze_trait(&self) -> Option<def_id> {
162175
self.items[FreezeTraitLangItem as uint]
163176
}

trunk/src/librustc/middle/trans/base.rs

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -442,36 +442,23 @@ pub fn set_inline_hint(f: ValueRef) {
442442
lib::llvm::SetFunctionAttribute(f, lib::llvm::InlineHintAttribute)
443443
}
444444

445-
pub fn set_llvm_fn_attrs(attrs: &[ast::Attribute], llfn: ValueRef) {
445+
pub fn set_inline_hint_if_appr(attrs: &[ast::Attribute],
446+
llfn: ValueRef) {
446447
use syntax::attr::*;
447-
// Set the inline hint if there is one
448448
match find_inline_attr(attrs) {
449449
InlineHint => set_inline_hint(llfn),
450450
InlineAlways => set_always_inline(llfn),
451451
InlineNever => set_no_inline(llfn),
452452
InlineNone => { /* fallthrough */ }
453453
}
454-
455-
// Add the no-split-stack attribute if requested
456-
if contains_name(attrs, "no_split_stack") {
457-
set_no_split_stack(llfn);
458-
}
459454
}
460455

461456
pub fn set_always_inline(f: ValueRef) {
462457
lib::llvm::SetFunctionAttribute(f, lib::llvm::AlwaysInlineAttribute)
463458
}
464459

465460
pub fn set_fixed_stack_segment(f: ValueRef) {
466-
do "fixed-stack-segment".to_c_str().with_ref |buf| {
467-
unsafe { llvm::LLVMAddFunctionAttrString(f, buf); }
468-
}
469-
}
470-
471-
pub fn set_no_split_stack(f: ValueRef) {
472-
do "no-split-stack".to_c_str().with_ref |buf| {
473-
unsafe { llvm::LLVMAddFunctionAttrString(f, buf); }
474-
}
461+
lib::llvm::SetFixedStackSegmentAttribute(f);
475462
}
476463

477464
pub fn set_glue_inlining(f: ValueRef, t: ty::t) {
@@ -2485,7 +2472,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
24852472
sym,
24862473
i.id)
24872474
};
2488-
set_llvm_fn_attrs(i.attrs, llfn);
2475+
set_inline_hint_if_appr(i.attrs, llfn);
24892476
llfn
24902477
}
24912478

@@ -2618,7 +2605,7 @@ pub fn register_method(ccx: @mut CrateContext,
26182605
let sym = exported_name(ccx, path, mty, m.attrs);
26192606

26202607
let llfn = register_fn(ccx, m.span, sym, id, mty);
2621-
set_llvm_fn_attrs(m.attrs, llfn);
2608+
set_inline_hint_if_appr(m.attrs, llfn);
26222609
llfn
26232610
}
26242611

trunk/src/librustc/middle/trans/monomorphize.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
use back::link::mangle_exported_name;
1313
use driver::session;
1414
use lib::llvm::ValueRef;
15-
use middle::trans::base::{set_llvm_fn_attrs, set_inline_hint};
15+
use middle::trans::base::{set_inline_hint_if_appr, set_inline_hint};
1616
use middle::trans::base::{trans_enum_variant,push_ctxt};
1717
use middle::trans::base::{trans_fn, decl_internal_cdecl_fn};
1818
use middle::trans::base::{get_item_val, no_self};
@@ -222,7 +222,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
222222
_
223223
}, _) => {
224224
let d = mk_lldecl();
225-
set_llvm_fn_attrs(i.attrs, d);
225+
set_inline_hint_if_appr(i.attrs, d);
226226
trans_fn(ccx,
227227
pt,
228228
decl,
@@ -266,13 +266,13 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
266266
ast_map::node_method(mth, _, _) => {
267267
// XXX: What should the self type be here?
268268
let d = mk_lldecl();
269-
set_llvm_fn_attrs(mth.attrs, d);
269+
set_inline_hint_if_appr(mth.attrs.clone(), d);
270270
meth::trans_method(ccx, pt, mth, Some(psubsts), d);
271271
d
272272
}
273273
ast_map::node_trait_method(@ast::provided(mth), _, pt) => {
274274
let d = mk_lldecl();
275-
set_llvm_fn_attrs(mth.attrs, d);
275+
set_inline_hint_if_appr(mth.attrs.clone(), d);
276276
meth::trans_method(ccx, (*pt).clone(), mth, Some(psubsts), d);
277277
d
278278
}

0 commit comments

Comments
 (0)