Skip to content

Commit 37d3257

Browse files
committed
---
yaml --- r: 278245 b: refs/heads/auto c: 216f3f4 h: refs/heads/master i: 278243: 6c3f245
1 parent 890fdfd commit 37d3257

File tree

24 files changed

+709
-522
lines changed

24 files changed

+709
-522
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
88
refs/tags/release-0.3.1: 495bae036dfe5ec6ceafd3312b4dca48741e845b
99
refs/tags/release-0.4: e828ea2080499553b97dfe33b3f4d472b4562ad7
1010
refs/tags/release-0.5: 7e3bcfbf21278251ee936ad53e92e9b719702d73
11-
refs/heads/auto: 84034d4598bca00250723557e02614b72503861b
11+
refs/heads/auto: 216f3f4b1e5d96e6e8308ab435a8a125f9cc7b0e
1212
refs/tags/release-0.6: b4ebcfa1812664df5e142f0134a5faea3918544c
1313
refs/tags/0.1: b19db808c2793fe2976759b85a355c3ad8c8b336
1414
refs/tags/0.2: 1754d02027f2924bed83b0160ee340c7f41d5ea1

branches/auto/src/librustc_const_eval/diagnostics.rs

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -215,22 +215,63 @@ match Some("hi".to_string()) {
215215
The variable `s` has type `String`, and its use in the guard is as a variable of
216216
type `String`. The guard code effectively executes in a separate scope to the
217217
body of the arm, so the value would be moved into this anonymous scope and
218-
therefore become unavailable in the body of the arm. Although this example seems
219-
innocuous, the problem is most clear when considering functions that take their
220-
argument by value.
218+
therefore becomes unavailable in the body of the arm.
221219
222-
```compile_fail
220+
The problem above can be solved by using the `ref` keyword.
221+
222+
```
223223
match Some("hi".to_string()) {
224-
Some(s) if { drop(s); false } => (),
225-
Some(s) => {}, // use s.
224+
Some(ref s) if s.len() == 0 => {},
226225
_ => {},
227226
}
228227
```
229228
230-
The value would be dropped in the guard then become unavailable not only in the
231-
body of that arm but also in all subsequent arms! The solution is to bind by
232-
reference when using guards or refactor the entire expression, perhaps by
233-
putting the condition inside the body of the arm.
229+
Though this example seems innocuous and easy to solve, the problem becomes clear
230+
when it encounters functions which consume the value:
231+
232+
```compile_fail
233+
struct A{}
234+
235+
impl A {
236+
fn consume(self) -> usize {
237+
0
238+
}
239+
}
240+
241+
fn main() {
242+
let a = Some(A{});
243+
match a {
244+
Some(y) if y.consume() > 0 => {}
245+
_ => {}
246+
}
247+
}
248+
```
249+
250+
In this situation, even the `ref` keyword cannot solve it, since borrowed
251+
content cannot be moved. This problem cannot be solved generally. If the value
252+
can be cloned, here is a not-so-specific solution:
253+
254+
```
255+
#[derive(Clone)]
256+
struct A{}
257+
258+
impl A {
259+
fn consume(self) -> usize {
260+
0
261+
}
262+
}
263+
264+
fn main() {
265+
let a = Some(A{});
266+
match a{
267+
Some(ref y) if y.clone().consume() > 0 => {}
268+
_ => {}
269+
}
270+
}
271+
```
272+
273+
If the value will be consumed in the pattern guard, using its clone will not
274+
move its ownership, so the code works.
234275
"##,
235276

236277
E0009: r##"

branches/auto/src/librustc_resolve/lib.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ use rustc::util::nodemap::{NodeMap, NodeSet, FnvHashMap, FnvHashSet};
5757
use syntax::ext::mtwt;
5858
use syntax::ast::{self, FloatTy};
5959
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, IntTy, UintTy};
60-
use syntax::codemap::{self, Span, Pos};
60+
use syntax::codemap::{self, Span};
6161
use syntax::errors::DiagnosticBuilder;
6262
use syntax::parse::token::{self, keywords};
6363
use syntax::util::lev_distance::find_best_match_for_name;
@@ -1260,10 +1260,7 @@ impl<'a> Resolver<'a> {
12601260
Failed(None) => {
12611261
let segment_name = name.as_str();
12621262
let module_name = module_to_string(search_module);
1263-
let mut span = span;
12641263
let msg = if "???" == &module_name {
1265-
span.hi = span.lo + Pos::from_usize(segment_name.len());
1266-
12671264
match search_parent_externals(name, &self.current_module) {
12681265
Some(module) => {
12691266
let path_str = names_to_string(module_path);

branches/auto/src/librustc_trans/back/write.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,8 @@ pub fn run_passes(sess: &Session,
639639
}
640640

641641
// Sanity check
642-
assert!(trans.modules.len() == sess.opts.cg.codegen_units);
642+
assert!(trans.modules.len() == sess.opts.cg.codegen_units ||
643+
sess.opts.debugging_opts.incremental.is_some());
643644

644645
let tm = create_target_machine(sess);
645646

branches/auto/src/librustc_trans/base.rs

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ use common::{node_id_type, fulfill_obligation};
6868
use common::{type_is_immediate, type_is_zero_size, val_ty};
6969
use common;
7070
use consts;
71-
use context::SharedCrateContext;
71+
use context::{SharedCrateContext, CrateContextList};
7272
use controlflow;
7373
use datum;
7474
use debuginfo::{self, DebugLoc, ToDebugLoc};
@@ -81,7 +81,7 @@ use machine::{llalign_of_min, llsize_of, llsize_of_real};
8181
use meth;
8282
use mir;
8383
use monomorphize::{self, Instance};
84-
use partitioning::{self, PartitioningStrategy, InstantiationMode};
84+
use partitioning::{self, PartitioningStrategy, InstantiationMode, CodegenUnit};
8585
use symbol_names_test;
8686
use tvec;
8787
use type_::Type;
@@ -664,7 +664,7 @@ pub fn coerce_unsized_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
664664
}
665665
}
666666

667-
pub fn custom_coerce_unsize_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>,
667+
pub fn custom_coerce_unsize_info<'scx, 'tcx>(scx: &SharedCrateContext<'scx, 'tcx>,
668668
source_ty: Ty<'tcx>,
669669
target_ty: Ty<'tcx>)
670670
-> CustomCoerceUnsized {
@@ -674,13 +674,13 @@ pub fn custom_coerce_unsize_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>,
674674
subst::VecPerParamSpace::empty());
675675

676676
let trait_ref = ty::Binder(ty::TraitRef {
677-
def_id: ccx.tcx().lang_items.coerce_unsized_trait().unwrap(),
678-
substs: ccx.tcx().mk_substs(trait_substs)
677+
def_id: scx.tcx().lang_items.coerce_unsized_trait().unwrap(),
678+
substs: scx.tcx().mk_substs(trait_substs)
679679
});
680680

681-
match fulfill_obligation(ccx, DUMMY_SP, trait_ref) {
681+
match fulfill_obligation(scx, DUMMY_SP, trait_ref) {
682682
traits::VtableImpl(traits::VtableImplData { impl_def_id, .. }) => {
683-
ccx.tcx().custom_coerce_unsized_kind(impl_def_id)
683+
scx.tcx().custom_coerce_unsized_kind(impl_def_id)
684684
}
685685
vtable => {
686686
bug!("invalid CoerceUnsized vtable: {:?}", vtable);
@@ -1824,7 +1824,7 @@ pub fn trans_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
18241824
closure_env: closure::ClosureEnv) {
18251825
ccx.stats().n_closures.set(ccx.stats().n_closures.get() + 1);
18261826

1827-
if collector::collecting_debug_information(ccx) {
1827+
if collector::collecting_debug_information(ccx.shared()) {
18281828
ccx.record_translation_item_as_generated(TransItem::Fn(instance));
18291829
}
18301830

@@ -2188,7 +2188,8 @@ pub fn update_linkage(ccx: &CrateContext,
21882188
// `llval` is a translation of an item defined in a separate
21892189
// compilation unit. This only makes sense if there are at least
21902190
// two compilation units.
2191-
assert!(ccx.sess().opts.cg.codegen_units > 1);
2191+
assert!(ccx.sess().opts.cg.codegen_units > 1 ||
2192+
ccx.sess().opts.debugging_opts.incremental.is_some());
21922193
// `llval` is a copy of something defined elsewhere, so use
21932194
// `AvailableExternallyLinkage` to avoid duplicating code in the
21942195
// output.
@@ -2524,7 +2525,7 @@ pub fn write_metadata<'a, 'tcx>(cx: &SharedCrateContext<'a, 'tcx>,
25242525

25252526
/// Find any symbols that are defined in one compilation unit, but not declared
25262527
/// in any other compilation unit. Give these symbols internal linkage.
2527-
fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
2528+
fn internalize_symbols(cx: &CrateContextList, reachable: &HashSet<&str>) {
25282529
unsafe {
25292530
let mut declared = HashSet::new();
25302531

@@ -2579,12 +2580,12 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
25792580
// when using MSVC linker. We do this only for data, as linker can fix up
25802581
// code references on its own.
25812582
// See #26591, #27438
2582-
fn create_imps(cx: &SharedCrateContext) {
2583+
fn create_imps(cx: &CrateContextList) {
25832584
// The x86 ABI seems to require that leading underscores are added to symbol
25842585
// names, so we need an extra underscore on 32-bit. There's also a leading
25852586
// '\x01' here which disables LLVM's symbol mangling (e.g. no extra
25862587
// underscores added in front).
2587-
let prefix = if cx.sess().target.target.target_pointer_width == "32" {
2588+
let prefix = if cx.shared().sess().target.target.target_pointer_width == "32" {
25882589
"\x01__imp__"
25892590
} else {
25902591
"\x01__imp_"
@@ -2661,10 +2662,10 @@ fn iter_functions(llmod: llvm::ModuleRef) -> ValueIter {
26612662
///
26622663
/// This list is later used by linkers to determine the set of symbols needed to
26632664
/// be exposed from a dynamic library and it's also encoded into the metadata.
2664-
pub fn filter_reachable_ids(ccx: &SharedCrateContext) -> NodeSet {
2665-
ccx.reachable().iter().map(|x| *x).filter(|id| {
2665+
pub fn filter_reachable_ids(scx: &SharedCrateContext) -> NodeSet {
2666+
scx.reachable().iter().map(|x| *x).filter(|id| {
26662667
// First, only worry about nodes which have a symbol name
2667-
ccx.item_symbols().borrow().contains_key(id)
2668+
scx.item_symbols().borrow().contains_key(id)
26682669
}).filter(|&id| {
26692670
// Next, we want to ignore some FFI functions that are not exposed from
26702671
// this crate. Reachable FFI functions can be lumped into two
@@ -2679,9 +2680,9 @@ pub fn filter_reachable_ids(ccx: &SharedCrateContext) -> NodeSet {
26792680
//
26802681
// As a result, if this id is an FFI item (foreign item) then we only
26812682
// let it through if it's included statically.
2682-
match ccx.tcx().map.get(id) {
2683+
match scx.tcx().map.get(id) {
26832684
hir_map::NodeForeignItem(..) => {
2684-
ccx.sess().cstore.is_statically_included_foreign_item(id)
2685+
scx.sess().cstore.is_statically_included_foreign_item(id)
26852686
}
26862687
_ => true,
26872688
}
@@ -2716,10 +2717,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27162717

27172718
let link_meta = link::build_link_meta(&tcx, name);
27182719

2719-
let codegen_units = tcx.sess.opts.cg.codegen_units;
2720-
let shared_ccx = SharedCrateContext::new(&link_meta.crate_name,
2721-
codegen_units,
2722-
tcx,
2720+
let shared_ccx = SharedCrateContext::new(tcx,
27232721
&mir_map,
27242722
export_map,
27252723
Sha256::new(),
@@ -2728,9 +2726,15 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27282726
check_overflow,
27292727
check_dropflag);
27302728

2729+
let codegen_units = collect_and_partition_translation_items(&shared_ccx);
2730+
let codegen_unit_count = codegen_units.len();
2731+
assert!(tcx.sess.opts.cg.codegen_units == codegen_unit_count ||
2732+
tcx.sess.opts.debugging_opts.incremental.is_some());
2733+
2734+
let crate_context_list = CrateContextList::new(&shared_ccx, codegen_units);
2735+
27312736
{
2732-
let ccx = shared_ccx.get_ccx(0);
2733-
collect_translation_items(&ccx);
2737+
let ccx = crate_context_list.get_ccx(0);
27342738

27352739
// Translate all items. See `TransModVisitor` for
27362740
// details on why we walk in this particular way.
@@ -2740,12 +2744,12 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27402744
krate.visit_all_items(&mut TransModVisitor { ccx: &ccx });
27412745
}
27422746

2743-
collector::print_collection_results(&ccx);
2747+
collector::print_collection_results(ccx.shared());
27442748

27452749
symbol_names_test::report_symbol_names(&ccx);
27462750
}
27472751

2748-
for ccx in shared_ccx.iter() {
2752+
for ccx in crate_context_list.iter() {
27492753
if ccx.sess().opts.debuginfo != NoDebugInfo {
27502754
debuginfo::finalize(&ccx);
27512755
}
@@ -2794,7 +2798,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27942798
}
27952799
}
27962800

2797-
let modules = shared_ccx.iter()
2801+
let modules = crate_context_list.iter()
27982802
.map(|ccx| ModuleTranslation { llcx: ccx.llcx(), llmod: ccx.llmod() })
27992803
.collect();
28002804

@@ -2820,14 +2824,14 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
28202824
}
28212825
}
28222826

2823-
if codegen_units > 1 {
2824-
internalize_symbols(&shared_ccx,
2827+
if codegen_unit_count > 1 {
2828+
internalize_symbols(&crate_context_list,
28252829
&reachable_symbols.iter().map(|x| &x[..]).collect());
28262830
}
28272831

28282832
if sess.target.target.options.is_like_msvc &&
28292833
sess.crate_types.borrow().iter().any(|ct| *ct == config::CrateTypeRlib) {
2830-
create_imps(&shared_ccx);
2834+
create_imps(&crate_context_list);
28312835
}
28322836

28332837
let metadata_module = ModuleTranslation {
@@ -2912,10 +2916,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemsWithinModVisitor<'a, 'tcx> {
29122916
}
29132917
}
29142918

2915-
fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
2916-
let time_passes = ccx.sess().time_passes();
2919+
fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>)
2920+
-> Vec<CodegenUnit<'tcx>> {
2921+
let time_passes = scx.sess().time_passes();
29172922

2918-
let collection_mode = match ccx.sess().opts.debugging_opts.print_trans_items {
2923+
let collection_mode = match scx.sess().opts.debugging_opts.print_trans_items {
29192924
Some(ref s) => {
29202925
let mode_string = s.to_lowercase();
29212926
let mode_string = mode_string.trim();
@@ -2926,7 +2931,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29262931
let message = format!("Unknown codegen-item collection mode '{}'. \
29272932
Falling back to 'lazy' mode.",
29282933
mode_string);
2929-
ccx.sess().warn(&message);
2934+
scx.sess().warn(&message);
29302935
}
29312936

29322937
TransItemCollectionMode::Lazy
@@ -2936,27 +2941,27 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29362941
};
29372942

29382943
let (items, reference_map) = time(time_passes, "translation item collection", || {
2939-
collector::collect_crate_translation_items(&ccx, collection_mode)
2944+
collector::collect_crate_translation_items(scx, collection_mode)
29402945
});
29412946

2942-
let strategy = if ccx.sess().opts.debugging_opts.incremental.is_some() {
2947+
let strategy = if scx.sess().opts.debugging_opts.incremental.is_some() {
29432948
PartitioningStrategy::PerModule
29442949
} else {
2945-
PartitioningStrategy::FixedUnitCount(ccx.sess().opts.cg.codegen_units)
2950+
PartitioningStrategy::FixedUnitCount(scx.sess().opts.cg.codegen_units)
29462951
};
29472952

29482953
let codegen_units = time(time_passes, "codegen unit partitioning", || {
2949-
partitioning::partition(ccx.tcx(),
2954+
partitioning::partition(scx.tcx(),
29502955
items.iter().cloned(),
29512956
strategy,
29522957
&reference_map)
29532958
});
29542959

2955-
if ccx.sess().opts.debugging_opts.print_trans_items.is_some() {
2960+
if scx.sess().opts.debugging_opts.print_trans_items.is_some() {
29562961
let mut item_to_cgus = HashMap::new();
29572962

2958-
for cgu in codegen_units {
2959-
for (trans_item, linkage) in cgu.items {
2963+
for cgu in &codegen_units {
2964+
for (&trans_item, &linkage) in &cgu.items {
29602965
item_to_cgus.entry(trans_item)
29612966
.or_insert(Vec::new())
29622967
.push((cgu.name.clone(), linkage));
@@ -2966,7 +2971,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29662971
let mut item_keys: Vec<_> = items
29672972
.iter()
29682973
.map(|i| {
2969-
let mut output = i.to_string(ccx);
2974+
let mut output = i.to_string(scx.tcx());
29702975
output.push_str(" @@");
29712976
let mut empty = Vec::new();
29722977
let mut cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
@@ -3005,10 +3010,12 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
30053010
println!("TRANS_ITEM {}", item);
30063011
}
30073012

3008-
let mut ccx_map = ccx.translation_items().borrow_mut();
3013+
let mut ccx_map = scx.translation_items().borrow_mut();
30093014

30103015
for cgi in items {
30113016
ccx_map.insert(cgi, TransItemState::PredictedButNotGenerated);
30123017
}
30133018
}
3019+
3020+
codegen_units
30143021
}

branches/auto/src/librustc_trans/callee.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ impl<'tcx> Callee<'tcx> {
156156
let trait_id = method_item.container().id();
157157
let trait_ref = ty::Binder(substs.to_trait_ref(tcx, trait_id));
158158
let trait_ref = infer::normalize_associated_type(tcx, &trait_ref);
159-
match common::fulfill_obligation(ccx, DUMMY_SP, trait_ref) {
159+
match common::fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref) {
160160
traits::VtableImpl(vtable_impl) => {
161161
let impl_did = vtable_impl.impl_def_id;
162162
let mname = tcx.item_name(def_id);

0 commit comments

Comments
 (0)