Skip to content

Commit bfa9f37

Browse files
committed
---
yaml --- r: 233727 b: refs/heads/beta c: 1c3b19d h: refs/heads/master i: 233725: adc74ae 233723: 6e44368 233719: 5adff35 233711: a2be484 233695: 6ab30e9 233663: 5236a16 233599: 2ded8e4 233471: 1bfa0b2 v: v3
1 parent 715fccb commit bfa9f37

File tree

11 files changed

+231
-96
lines changed

11 files changed

+231
-96
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ refs/tags/0.9: 36870b185fc5f5486636d4515f0e22677493f225
2323
refs/tags/0.10: ac33f2b15782272ae348dbd7b14b8257b2148b5a
2424
refs/tags/0.11.0: e1247cb1d0d681be034adb4b558b5a0c0d5720f9
2525
refs/tags/0.12.0: f0c419429ef30723ceaf6b42f9b5a2aeb5d2e2d1
26-
refs/heads/beta: dec43510f1f8f053f86178b0710ec141f4644d20
26+
refs/heads/beta: 1c3b19d69d87a1d2e1a32be9ba80042458c5f0cc
2727
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
2828
refs/heads/tmp: 370fe2786109360f7c35b8ba552b83b773dd71d6
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f

branches/beta/src/librustc/middle/entry.rs

Lines changed: 36 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,19 @@
1111

1212
use ast_map;
1313
use session::{config, Session};
14-
use syntax::ast::{Name, NodeId, Item, ItemFn};
14+
use syntax;
15+
use syntax::ast::{NodeId, Item};
1516
use syntax::attr;
1617
use syntax::codemap::Span;
17-
use syntax::parse::token;
18+
use syntax::entry::EntryPointType;
1819
use syntax::visit;
1920
use syntax::visit::Visitor;
2021

21-
struct EntryContext<'a, 'ast: 'a> {
22+
struct EntryContext<'a> {
2223
session: &'a Session,
2324

24-
ast_map: &'a ast_map::Map<'ast>,
25-
26-
// The interned Name for "main".
27-
main_name: Name,
25+
// The current depth in the ast
26+
depth: usize,
2827

2928
// The top-level function called 'main'
3029
main_fn: Option<(NodeId, Span)>,
@@ -40,9 +39,11 @@ struct EntryContext<'a, 'ast: 'a> {
4039
non_main_fns: Vec<(NodeId, Span)> ,
4140
}
4241

43-
impl<'a, 'ast, 'v> Visitor<'v> for EntryContext<'a, 'ast> {
42+
impl<'a, 'v> Visitor<'v> for EntryContext<'a> {
4443
fn visit_item(&mut self, item: &Item) {
44+
self.depth += 1;
4545
find_item(item, self);
46+
self.depth -= 1;
4647
}
4748
}
4849

@@ -63,8 +64,7 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
6364

6465
let mut ctxt = EntryContext {
6566
session: session,
66-
main_name: token::intern("main"),
67-
ast_map: ast_map,
67+
depth: 0,
6868
main_fn: None,
6969
attr_main_fn: None,
7070
start_fn: None,
@@ -77,44 +77,35 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
7777
}
7878

7979
fn find_item(item: &Item, ctxt: &mut EntryContext) {
80-
match item.node {
81-
ItemFn(..) => {
82-
if item.ident.name == ctxt.main_name {
83-
ctxt.ast_map.with_path(item.id, |path| {
84-
if path.count() == 1 {
85-
// This is a top-level function so can be 'main'
86-
if ctxt.main_fn.is_none() {
87-
ctxt.main_fn = Some((item.id, item.span));
88-
} else {
89-
span_err!(ctxt.session, item.span, E0136,
90-
"multiple 'main' functions");
91-
}
92-
} else {
93-
// This isn't main
94-
ctxt.non_main_fns.push((item.id, item.span));
95-
}
96-
});
80+
match syntax::entry::entry_point_type(item, ctxt.depth) {
81+
EntryPointType::MainNamed => {
82+
if ctxt.main_fn.is_none() {
83+
ctxt.main_fn = Some((item.id, item.span));
84+
} else {
85+
span_err!(ctxt.session, item.span, E0136,
86+
"multiple 'main' functions");
9787
}
98-
99-
if attr::contains_name(&item.attrs, "main") {
100-
if ctxt.attr_main_fn.is_none() {
101-
ctxt.attr_main_fn = Some((item.id, item.span));
102-
} else {
103-
span_err!(ctxt.session, item.span, E0137,
104-
"multiple functions with a #[main] attribute");
105-
}
88+
},
89+
EntryPointType::OtherMain => {
90+
ctxt.non_main_fns.push((item.id, item.span));
91+
},
92+
EntryPointType::MainAttr => {
93+
if ctxt.attr_main_fn.is_none() {
94+
ctxt.attr_main_fn = Some((item.id, item.span));
95+
} else {
96+
span_err!(ctxt.session, item.span, E0137,
97+
"multiple functions with a #[main] attribute");
10698
}
107-
108-
if attr::contains_name(&item.attrs, "start") {
109-
if ctxt.start_fn.is_none() {
110-
ctxt.start_fn = Some((item.id, item.span));
111-
} else {
112-
span_err!(ctxt.session, item.span, E0138,
113-
"multiple 'start' functions");
114-
}
99+
},
100+
EntryPointType::Start => {
101+
if ctxt.start_fn.is_none() {
102+
ctxt.start_fn = Some((item.id, item.span));
103+
} else {
104+
span_err!(ctxt.session, item.span, E0138,
105+
"multiple 'start' functions");
115106
}
116-
}
117-
_ => ()
107+
},
108+
EntryPointType::None => ()
118109
}
119110

120111
visit::walk_item(ctxt, item);

branches/beta/src/libstd/collections/mod.rs

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
//!
2626
//! Rust's collections can be grouped into four major categories:
2727
//!
28-
//! * Sequences: `Vec`, `VecDeque`, `LinkedList`, `BitVec`
29-
//! * Maps: `HashMap`, `BTreeMap`, `VecMap`
30-
//! * Sets: `HashSet`, `BTreeSet`, `BitSet`
28+
//! * Sequences: `Vec`, `VecDeque`, `LinkedList`
29+
//! * Maps: `HashMap`, `BTreeMap`
30+
//! * Sets: `HashSet`, `BTreeSet`
3131
//! * Misc: `BinaryHeap`
3232
//!
3333
//! # When Should You Use Which Collection?
@@ -70,22 +70,11 @@
7070
//! * You want to be able to get all of the entries in order on-demand.
7171
//! * You want a sorted map.
7272
//!
73-
//! ### Use a `VecMap` when:
74-
//! * You want a `HashMap` but with known to be small `usize` keys.
75-
//! * You want a `BTreeMap`, but with known to be small `usize` keys.
76-
//!
7773
//! ### Use the `Set` variant of any of these `Map`s when:
7874
//! * You just want to remember which keys you've seen.
7975
//! * There is no meaningful value to associate with your keys.
8076
//! * You just want a set.
8177
//!
82-
//! ### Use a `BitVec` when:
83-
//! * You want to store an unbounded number of booleans in a small space.
84-
//! * You want a bit vector.
85-
//!
86-
//! ### Use a `BitSet` when:
87-
//! * You want a `BitVec`, but want `Set` properties
88-
//!
8978
//! ### Use a `BinaryHeap` when:
9079
//!
9180
//! * You want to store a bunch of elements, but only ever want to process the
@@ -123,31 +112,20 @@
123112
//! | Vec | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) |
124113
//! | VecDeque | O(1) | O(min(i, n-i))* | O(min(i, n-i)) | O(m)* | O(min(i, n-i)) |
125114
//! | LinkedList | O(min(i, n-i)) | O(min(i, n-i)) | O(min(i, n-i)) | O(1) | O(min(i, n-i)) |
126-
//! | BitVec | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) |
127115
//!
128116
//! Note that where ties occur, Vec is generally going to be faster than VecDeque, and VecDeque
129-
//! is generally going to be faster than LinkedList. BitVec is not a general purpose collection, and
130-
//! therefore cannot reasonably be compared.
117+
//! is generally going to be faster than LinkedList.
131118
//!
132119
//! ## Maps
133120
//!
134-
//! For Sets, all operations have the cost of the equivalent Map operation. For
135-
//! BitSet,
136-
//! refer to VecMap.
121+
//! For Sets, all operations have the cost of the equivalent Map operation.
137122
//!
138123
//! | | get | insert | remove | predecessor |
139124
//! |----------|-----------|----------|----------|-------------|
140125
//! | HashMap | O(1)~ | O(1)~* | O(1)~ | N/A |
141126
//! | BTreeMap | O(log n) | O(log n) | O(log n) | O(log n) |
142-
//! | VecMap | O(1) | O(1)? | O(1) | O(n) |
143-
//!
144-
//! Note that VecMap is *incredibly* inefficient in terms of space. The O(1)
145-
//! insertion time assumes space for the element is already allocated.
146-
//! Otherwise, a large key may require a massive reallocation, with no direct
147-
//! relation to the number of elements in the collection. VecMap should only be
148-
//! seriously considered for small keys.
149127
//!
150-
//! Note also that BTreeMap's precise performance depends on the value of B.
128+
//! Note that BTreeMap's precise performance depends on the value of B.
151129
//!
152130
//! # Correct and Efficient Usage of Collections
153131
//!

branches/beta/src/libsyntax/entry.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2012-2015 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+
use attr;
12+
use ast::{Item, ItemFn};
13+
14+
pub enum EntryPointType {
15+
None,
16+
MainNamed,
17+
MainAttr,
18+
Start,
19+
OtherMain, // Not an entry point, but some other function named main
20+
}
21+
22+
pub fn entry_point_type(item: &Item, depth: usize) -> EntryPointType {
23+
match item.node {
24+
ItemFn(..) => {
25+
if attr::contains_name(&item.attrs, "start") {
26+
EntryPointType::Start
27+
} else if attr::contains_name(&item.attrs, "main") {
28+
EntryPointType::MainAttr
29+
} else if item.ident.name == "main" {
30+
if depth == 1 {
31+
// This is a top-level function so can be 'main'
32+
EntryPointType::MainNamed
33+
} else {
34+
EntryPointType::OtherMain
35+
}
36+
} else {
37+
EntryPointType::None
38+
}
39+
}
40+
_ => EntryPointType::None,
41+
}
42+
}

branches/beta/src/libsyntax/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ pub mod attr;
9090
pub mod codemap;
9191
pub mod config;
9292
pub mod diagnostic;
93+
pub mod entry;
9394
pub mod feature_gate;
9495
pub mod fold;
9596
pub mod owned_slice;

branches/beta/src/libsyntax/test.rs

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#![allow(unused_imports)]
1515
use self::HasTestSignature::*;
1616

17+
use std::iter;
1718
use std::slice;
1819
use std::mem;
1920
use std::vec;
@@ -24,6 +25,7 @@ use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute};
2425
use codemap;
2526
use diagnostic;
2627
use config;
28+
use entry::{self, EntryPointType};
2729
use ext::base::ExtCtxt;
2830
use ext::build::AstBuilder;
2931
use ext::expand::ExpansionConfig;
@@ -173,28 +175,6 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
173175
let tests = mem::replace(&mut self.tests, tests);
174176
let tested_submods = mem::replace(&mut self.tested_submods, tested_submods);
175177

176-
// Remove any #[main] from the AST so it doesn't clash with
177-
// the one we're going to add. Only if compiling an executable.
178-
179-
mod_folded.items = mem::replace(&mut mod_folded.items, vec![]).move_map(|item| {
180-
item.map(|ast::Item {id, ident, attrs, node, vis, span}| {
181-
ast::Item {
182-
id: id,
183-
ident: ident,
184-
attrs: attrs.into_iter().filter_map(|attr| {
185-
if !attr.check_name("main") {
186-
Some(attr)
187-
} else {
188-
None
189-
}
190-
}).collect(),
191-
node: node,
192-
vis: vis,
193-
span: span
194-
}
195-
})
196-
});
197-
198178
if !tests.is_empty() || !tested_submods.is_empty() {
199179
let (it, sym) = mk_reexport_mod(&mut self.cx, tests, tested_submods);
200180
mod_folded.items.push(it);
@@ -211,6 +191,55 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
211191
}
212192
}
213193

194+
struct EntryPointCleaner {
195+
// Current depth in the ast
196+
depth: usize,
197+
}
198+
199+
impl fold::Folder for EntryPointCleaner {
200+
fn fold_item(&mut self, i: P<ast::Item>) -> SmallVector<P<ast::Item>> {
201+
self.depth += 1;
202+
let folded = fold::noop_fold_item(i, self).expect_one("noop did something");
203+
self.depth -= 1;
204+
205+
// Remove any #[main] or #[start] from the AST so it doesn't
206+
// clash with the one we're going to add, but mark it as
207+
// #[allow(dead_code)] to avoid printing warnings.
208+
let folded = match entry::entry_point_type(&*folded, self.depth) {
209+
EntryPointType::MainNamed |
210+
EntryPointType::MainAttr |
211+
EntryPointType::Start =>
212+
folded.map(|ast::Item {id, ident, attrs, node, vis, span}| {
213+
let allow_str = InternedString::new("allow");
214+
let dead_code_str = InternedString::new("dead_code");
215+
let allow_dead_code_item =
216+
attr::mk_list_item(allow_str,
217+
vec![attr::mk_word_item(dead_code_str)]);
218+
let allow_dead_code = attr::mk_attr_outer(attr::mk_attr_id(),
219+
allow_dead_code_item);
220+
221+
ast::Item {
222+
id: id,
223+
ident: ident,
224+
attrs: attrs.into_iter()
225+
.filter(|attr| {
226+
!attr.check_name("main") && !attr.check_name("start")
227+
})
228+
.chain(iter::once(allow_dead_code))
229+
.collect(),
230+
node: node,
231+
vis: vis,
232+
span: span
233+
}
234+
}),
235+
EntryPointType::None |
236+
EntryPointType::OtherMain => folded,
237+
};
238+
239+
SmallVector::one(folded)
240+
}
241+
}
242+
214243
fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec<ast::Ident>,
215244
tested_submods: Vec<(ast::Ident, ast::Ident)>) -> (P<ast::Item>, ast::Ident) {
216245
let super_ = token::str_to_ident("super");
@@ -246,6 +275,10 @@ fn generate_test_harness(sess: &ParseSess,
246275
krate: ast::Crate,
247276
cfg: &ast::CrateConfig,
248277
sd: &diagnostic::SpanHandler) -> ast::Crate {
278+
// Remove the entry points
279+
let mut cleaner = EntryPointCleaner { depth: 0 };
280+
let krate = cleaner.fold_crate(krate);
281+
249282
let mut feature_gated_cfgs = vec![];
250283
let mut cx: TestCtxt = TestCtxt {
251284
sess: sess,
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2015 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+
// compile-flags: --test
12+
13+
#![deny(dead_code)]
14+
15+
fn dead() {} //~ error: function is never used: `dead`
16+
17+
fn main() {}

0 commit comments

Comments
 (0)