Skip to content

Commit a860abe

Browse files
committed
---
yaml --- r: 235827 b: refs/heads/stable c: 11aa875 h: refs/heads/master i: 235825: babffaa 235823: f32498a v: v3
1 parent 5aaeca8 commit a860abe

File tree

22 files changed

+188
-327
lines changed

22 files changed

+188
-327
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/heads/tmp: afae2ff723393b3ab4ccffef6ac7c6d1809e2da0
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: f859507de8c410b648d934d8f5ec1c52daac971d
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: 7276d8b7613c81c09feeec3bf94d47c4a5174bc8
32+
refs/heads/stable: 11aa8756c1a6439fa73ef804665d13fc1bb29fef
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/src/librustc/middle/check_static_recursion.rs

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// This compiler pass detects constants that refer to themselves
11+
// This compiler pass detects static items that refer to themselves
1212
// recursively.
1313

1414
use ast_map;
@@ -18,7 +18,6 @@ use util::nodemap::NodeMap;
1818

1919
use syntax::{ast, ast_util};
2020
use syntax::codemap::Span;
21-
use syntax::feature_gate::emit_feature_err;
2221
use syntax::visit::Visitor;
2322
use syntax::visit;
2423

@@ -126,27 +125,8 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
126125
}
127126
fn with_item_id_pushed<F>(&mut self, id: ast::NodeId, f: F)
128127
where F: Fn(&mut Self) {
129-
if self.idstack.iter().any(|&x| x == id) {
130-
let any_static = self.idstack.iter().any(|&x| {
131-
if let ast_map::NodeItem(item) = self.ast_map.get(x) {
132-
if let ast::ItemStatic(..) = item.node {
133-
true
134-
} else {
135-
false
136-
}
137-
} else {
138-
false
139-
}
140-
});
141-
if any_static {
142-
if !self.sess.features.borrow().static_recursion {
143-
emit_feature_err(&self.sess.parse_sess.span_diagnostic,
144-
"static_recursion",
145-
*self.root_span, "recursive static");
146-
}
147-
} else {
148-
span_err!(self.sess, *self.root_span, E0265, "recursive constant");
149-
}
128+
if self.idstack.iter().any(|x| *x == id) {
129+
span_err!(self.sess, *self.root_span, E0265, "recursive constant");
150130
return;
151131
}
152132
self.idstack.push(id);

branches/stable/src/librustc/middle/infer/mod.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -698,8 +698,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
698698
}
699699
}
700700

701-
fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot) {
702-
debug!("rollback_to(cause={})", cause);
701+
fn rollback_to(&self, snapshot: CombinedSnapshot) {
702+
debug!("rollback!");
703703
let CombinedSnapshot { type_snapshot,
704704
int_snapshot,
705705
float_snapshot,
@@ -759,7 +759,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
759759
debug!("commit_if_ok() -- r.is_ok() = {}", r.is_ok());
760760
match r {
761761
Ok(_) => { self.commit_from(snapshot); }
762-
Err(_) => { self.rollback_to("commit_if_ok -- error", snapshot); }
762+
Err(_) => { self.rollback_to(snapshot); }
763763
}
764764
r
765765
}
@@ -778,8 +778,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
778778

779779
let r = self.commit_if_ok(|_| f());
780780

781-
debug!("commit_regions_if_ok: rolling back everything but regions");
782-
783781
// Roll back any non-region bindings - they should be resolved
784782
// inside `f`, with, e.g. `resolve_type_vars_if_possible`.
785783
self.type_variables
@@ -806,7 +804,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
806804
debug!("probe()");
807805
let snapshot = self.start_snapshot();
808806
let r = f(&snapshot);
809-
self.rollback_to("probe", snapshot);
807+
self.rollback_to(snapshot);
810808
r
811809
}
812810

branches/stable/src/librustc/middle/traits/select.rs

Lines changed: 26 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,15 +1351,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13511351
// correct trait, but also the correct type parameters.
13521352
// For example, we may be trying to upcast `Foo` to `Bar<i32>`,
13531353
// but `Foo` is declared as `trait Foo : Bar<u32>`.
1354-
let upcast_trait_refs =
1355-
util::supertraits(self.tcx(), poly_trait_ref)
1356-
.filter(|upcast_trait_ref| {
1357-
self.infcx.probe(|_| {
1358-
let upcast_trait_ref = upcast_trait_ref.clone();
1359-
self.match_poly_trait_ref(obligation, upcast_trait_ref).is_ok()
1360-
})
1361-
})
1362-
.count();
1354+
let upcast_trait_refs = util::supertraits(self.tcx(), poly_trait_ref)
1355+
.filter(|upcast_trait_ref| self.infcx.probe(|_| {
1356+
let upcast_trait_ref = upcast_trait_ref.clone();
1357+
self.match_poly_trait_ref(obligation, upcast_trait_ref).is_ok()
1358+
})).count();
13631359

13641360
if upcast_trait_refs > 1 {
13651361
// can be upcast in many ways; need more type information
@@ -1631,9 +1627,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16311627
let principal =
16321628
data.principal_trait_ref_with_self_ty(self.tcx(),
16331629
self.tcx().types.err);
1634-
let copy_def_id = obligation.predicate.def_id();
1630+
let desired_def_id = obligation.predicate.def_id();
16351631
for tr in util::supertraits(self.tcx(), principal) {
1636-
if tr.def_id() == copy_def_id {
1632+
if tr.def_id() == desired_def_id {
16371633
return ok_if(Vec::new())
16381634
}
16391635
}
@@ -2286,41 +2282,31 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
22862282
}
22872283
};
22882284

2285+
// Upcast the object type to the obligation type. There must
2286+
// be exactly one applicable trait-reference; if this were not
2287+
// the case, we would have reported an ambiguity error rather
2288+
// than successfully selecting one of the candidates.
2289+
let mut upcast_trait_refs = util::supertraits(self.tcx(), poly_trait_ref)
2290+
.map(|upcast_trait_ref| {
2291+
(upcast_trait_ref.clone(), self.infcx.probe(|_| {
2292+
self.match_poly_trait_ref(obligation, upcast_trait_ref)
2293+
}).is_ok())
2294+
});
22892295
let mut upcast_trait_ref = None;
2290-
let vtable_base;
2291-
2292-
{
2293-
// We want to find the first supertrait in the list of
2294-
// supertraits that we can unify with, and do that
2295-
// unification. We know that there is exactly one in the list
2296-
// where we can unify because otherwise select would have
2297-
// reported an ambiguity. (When we do find a match, also
2298-
// record it for later.)
2299-
let nonmatching =
2300-
util::supertraits(self.tcx(), poly_trait_ref)
2301-
.take_while(|&t| {
2302-
match
2303-
self.infcx.commit_if_ok(
2304-
|_| self.match_poly_trait_ref(obligation, t))
2305-
{
2306-
Ok(_) => { upcast_trait_ref = Some(t); false }
2307-
Err(_) => { true }
2308-
}
2309-
});
2310-
2311-
// Additionally, for each of the nonmatching predicates that
2312-
// we pass over, we sum up the set of number of vtable
2313-
// entries, so that we can compute the offset for the selected
2314-
// trait.
2315-
vtable_base =
2316-
nonmatching.map(|t| util::count_own_vtable_entries(self.tcx(), t))
2317-
.sum();
2296+
let mut vtable_base = 0;
23182297

2298+
while let Some((supertrait, matches)) = upcast_trait_refs.next() {
2299+
if matches {
2300+
upcast_trait_ref = Some(supertrait);
2301+
break;
2302+
}
2303+
vtable_base += util::count_own_vtable_entries(self.tcx(), supertrait);
23192304
}
2305+
assert!(upcast_trait_refs.all(|(_, matches)| !matches));
23202306

23212307
VtableObjectData {
23222308
upcast_trait_ref: upcast_trait_ref.unwrap(),
2323-
vtable_base: vtable_base,
2309+
vtable_base: vtable_base
23242310
}
23252311
}
23262312

branches/stable/src/librustc/middle/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1985,7 +1985,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
19851985
/// erase, or otherwise "discharge" these bound regions, we change the
19861986
/// type from `Binder<T>` to just `T` (see
19871987
/// e.g. `liberate_late_bound_regions`).
1988-
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
1988+
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
19891989
pub struct Binder<T>(pub T);
19901990

19911991
impl<T> Binder<T> {

branches/stable/src/librustc_trans/trans/base.rs

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,7 +2090,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
20902090
let mut v = TransItemVisitor{ ccx: ccx };
20912091
v.visit_expr(&**expr);
20922092

2093-
let g = consts::trans_static(ccx, m, expr, item.id, &item.attrs);
2093+
let g = consts::trans_static(ccx, m, item.id);
20942094
update_linkage(ccx, g, Some(item.id), OriginalTranslation);
20952095
},
20962096
ast::ItemForeignMod(ref foreign_mod) => {
@@ -2334,25 +2334,44 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
23342334
let sym = || exported_name(ccx, id, ty, &i.attrs);
23352335

23362336
let v = match i.node {
2337-
ast::ItemStatic(..) => {
2337+
ast::ItemStatic(_, _, ref expr) => {
23382338
// If this static came from an external crate, then
23392339
// we need to get the symbol from csearch instead of
23402340
// using the current crate's name/version
23412341
// information in the hash of the symbol
23422342
let sym = sym();
23432343
debug!("making {}", sym);
23442344

2345-
// Create the global before evaluating the initializer;
2346-
// this is necessary to allow recursive statics.
2347-
let llty = type_of(ccx, ty);
2348-
let g = declare::define_global(ccx, &sym[..],
2349-
llty).unwrap_or_else(|| {
2350-
ccx.sess().span_fatal(i.span, &format!("symbol `{}` is already defined",
2351-
sym))
2352-
});
2353-
2354-
ccx.item_symbols().borrow_mut().insert(i.id, sym);
2355-
g
2345+
// We need the translated value here, because for enums the
2346+
// LLVM type is not fully determined by the Rust type.
2347+
let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
2348+
let (v, ty) = consts::const_expr(ccx, &**expr, empty_substs, None);
2349+
ccx.static_values().borrow_mut().insert(id, v);
2350+
unsafe {
2351+
// boolean SSA values are i1, but they have to be stored in i8 slots,
2352+
// otherwise some LLVM optimization passes don't work as expected
2353+
let llty = if ty.is_bool() {
2354+
llvm::LLVMInt8TypeInContext(ccx.llcx())
2355+
} else {
2356+
llvm::LLVMTypeOf(v)
2357+
};
2358+
2359+
// FIXME(nagisa): probably should be declare_global, because no definition
2360+
// is happening here, but we depend on it being defined here from
2361+
// const::trans_static. This all logic should be replaced.
2362+
let g = declare::define_global(ccx, &sym[..],
2363+
Type::from_ref(llty)).unwrap_or_else(||{
2364+
ccx.sess().span_fatal(i.span, &format!("symbol `{}` is already defined",
2365+
sym))
2366+
});
2367+
2368+
if attr::contains_name(&i.attrs,
2369+
"thread_local") {
2370+
llvm::set_thread_local(g, true);
2371+
}
2372+
ccx.item_symbols().borrow_mut().insert(i.id, sym);
2373+
g
2374+
}
23562375
}
23572376

23582377
ast::ItemFn(_, _, _, abi, _, _) => {
@@ -2719,13 +2738,6 @@ pub fn trans_crate(tcx: &ty::ctxt, analysis: ty::CrateAnalysis) -> CrateTranslat
27192738
if ccx.sess().opts.debuginfo != NoDebugInfo {
27202739
debuginfo::finalize(&ccx);
27212740
}
2722-
for &(old_g, new_g) in ccx.statics_to_rauw().borrow().iter() {
2723-
unsafe {
2724-
let bitcast = llvm::LLVMConstPointerCast(new_g, llvm::LLVMTypeOf(old_g));
2725-
llvm::LLVMReplaceAllUsesWith(old_g, bitcast);
2726-
llvm::LLVMDeleteGlobal(old_g);
2727-
}
2728-
}
27292741
}
27302742

27312743
// Translate the metadata.

branches/stable/src/librustc_trans/trans/consts.rs

Lines changed: 11 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,8 @@ use middle::subst::Substs;
3737
use middle::ty::{self, Ty};
3838
use util::nodemap::NodeMap;
3939

40-
use std::ffi::{CStr, CString};
4140
use libc::c_uint;
42-
use syntax::{ast, ast_util, attr};
41+
use syntax::{ast, ast_util};
4342
use syntax::parse::token;
4443
use syntax::ptr::P;
4544

@@ -899,70 +898,37 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
899898
"bad constant expression type in consts::const_expr"),
900899
}
901900
}
902-
pub fn trans_static(ccx: &CrateContext,
903-
m: ast::Mutability,
904-
expr: &ast::Expr,
905-
id: ast::NodeId,
906-
attrs: &Vec<ast::Attribute>)
907-
-> ValueRef {
901+
902+
pub fn trans_static(ccx: &CrateContext, m: ast::Mutability, id: ast::NodeId) -> ValueRef {
908903
unsafe {
909904
let _icx = push_ctxt("trans_static");
910905
let g = base::get_item_val(ccx, id);
911-
912-
let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
913-
let (v, _) = const_expr(ccx, expr, empty_substs, None);
914-
906+
// At this point, get_item_val has already translated the
907+
// constant's initializer to determine its LLVM type.
908+
let v = ccx.static_values().borrow().get(&id).unwrap().clone();
915909
// boolean SSA values are i1, but they have to be stored in i8 slots,
916910
// otherwise some LLVM optimization passes don't work as expected
917-
let mut val_llty = llvm::LLVMTypeOf(v);
918-
let v = if val_llty == Type::i1(ccx).to_ref() {
919-
val_llty = Type::i8(ccx).to_ref();
920-
llvm::LLVMConstZExt(v, val_llty)
911+
let v = if llvm::LLVMTypeOf(v) == Type::i1(ccx).to_ref() {
912+
llvm::LLVMConstZExt(v, Type::i8(ccx).to_ref())
921913
} else {
922914
v
923915
};
924-
925-
let ty = ccx.tcx().node_id_to_type(id);
926-
let llty = type_of::type_of(ccx, ty);
927-
let g = if val_llty == llty.to_ref() {
928-
g
929-
} else {
930-
// If we created the global with the wrong type,
931-
// correct the type.
932-
let empty_string = CString::new("").unwrap();
933-
let name_str_ref = CStr::from_ptr(llvm::LLVMGetValueName(g));
934-
let name_string = CString::new(name_str_ref.to_bytes()).unwrap();
935-
llvm::LLVMSetValueName(g, empty_string.as_ptr());
936-
let new_g = llvm::LLVMGetOrInsertGlobal(
937-
ccx.llmod(), name_string.as_ptr(), val_llty);
938-
// To avoid breaking any invariants, we leave around the old
939-
// global for the moment; we'll replace all references to it
940-
// with the new global later. (See base::trans_crate.)
941-
ccx.statics_to_rauw().borrow_mut().push((g, new_g));
942-
new_g
943-
};
944916
llvm::LLVMSetInitializer(g, v);
945917

946918
// As an optimization, all shared statics which do not have interior
947919
// mutability are placed into read-only memory.
948920
if m != ast::MutMutable {
949-
let tcontents = ty.type_contents(ccx.tcx());
921+
let node_ty = ccx.tcx().node_id_to_type(id);
922+
let tcontents = node_ty.type_contents(ccx.tcx());
950923
if !tcontents.interior_unsafe() {
951-
llvm::LLVMSetGlobalConstant(g, llvm::True);
924+
llvm::LLVMSetGlobalConstant(g, True);
952925
}
953926
}
954-
955927
debuginfo::create_global_var_metadata(ccx, id, g);
956-
957-
if attr::contains_name(attrs,
958-
"thread_local") {
959-
llvm::set_thread_local(g, true);
960-
}
961928
g
962929
}
963930
}
964931

965-
966932
fn get_static_val<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: ast::DefId,
967933
ty: Ty<'tcx>) -> ValueRef {
968934
if ast_util::is_local(did) { return base::get_item_val(ccx, did.node) }

0 commit comments

Comments
 (0)