Skip to content

Commit 53d04af

Browse files
committed
---
yaml --- r: 153851 b: refs/heads/try2 c: b2bd998 h: refs/heads/master i: 153849: 8fc4aa0 153847: 632c11a v: v3
1 parent 1822609 commit 53d04af

File tree

21 files changed

+233
-80
lines changed

21 files changed

+233
-80
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: 3f568464608ad39f1d620b81d97f844015f971a1
8+
refs/heads/try2: b2bd9986072a010cd68a7f0a814ad99038050983
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/doc/guide-container.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ differently.
118118
## Container iterators
119119

120120
Containers implement iteration over the contained elements by returning an
121-
iterator object. For example, vector slices several iterators available:
121+
iterator object. For example, for vector slices several iterators are available:
122122

123123
* `iter()` for immutable references to the elements
124124
* `mut_iter()` for mutable references to the elements

branches/try2/src/grammar/raw-string-literal-ambiguity.md

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
Rust's lexical grammar is not context-free. Raw string literals are the source
22
of the problem. Informally, a raw string literal is an `r`, followed by `N`
33
hashes (where N can be zero), a quote, any characters, then a quote followed
4-
by `N` hashes. This grammar describes this as best possible:
4+
by `N` hashes. Critically, once inside the first pair of quotes,
5+
another quote cannot be followed by `N` consecutive hashes. e.g.
6+
`r###""###"###` is invalid.
7+
8+
This grammar describes this as best possible:
59

610
R -> 'r' S
711
S -> '"' B '"'
@@ -22,8 +26,39 @@ accepted as one by the above grammar, using the derivation:
2226
(Where `T : U` means the rule `T` is applied, and `U` is the remainder of the
2327
string.) The difficulty arises from the fact that it is fundamentally
2428
context-sensitive. In particular, the context needed is the number of hashes.
25-
I know of no way to resolve this, but also have not come up with a proof that
26-
it is not context sensitive. Such a proof would probably use the pumping lemma
27-
for context-free languages, but I (cmr) could not come up with a proof after
28-
spending a few hours on it, and decided my time best spent elsewhere. Pull
29-
request welcome!
29+
30+
To prove that Rust's string literals are not context-free, we will use
31+
the fact that context-free languages are closed under intersection with
32+
regular languages, and the
33+
[pumping lemma for context-free languages](https://en.wikipedia.org/wiki/Pumping_lemma_for_context-free_languages).
34+
35+
Consider the regular language `R = r#+""#*"#+`. If Rust's raw string literals are
36+
context-free, then their intersection with `R`, `R'`, should also be context-free.
37+
Therefore, to prove that raw string literals are not context-free,
38+
it is sufficient to prove that `R'` is not context-free.
39+
40+
The language `R'` is `{r#^n""#^m"#^n | m < n}`.
41+
42+
Assume `R'` *is* context-free. Then `R'` has some pumping length `p > 0` for which
43+
the pumping lemma applies. Consider the following string `s` in `R'`:
44+
45+
`r#^p""#^{p-1}"#^p`
46+
47+
e.g. for `p = 2`: `s = r##""#"##`
48+
49+
Then `s = uvwxy` for some choice of `uvwxy` such that `vx` is non-empty,
50+
`|vwx| < p+1`, and `uv^iwx^iy` is in `R'` for all `i >= 0`.
51+
52+
Neither `v` nor `x` can contain a `"` or `r`, as the number of these characters
53+
in any string in `R'` is fixed. So `v` and `x` contain only hashes.
54+
Consequently, of the three sequences of hashes, `v` and `x` combined
55+
can only pump two of them.
56+
If we ever choose the central sequence of hashes, then one of the outer sequences
57+
will not grow when we pump, leading to an imbalance between the outer sequences.
58+
Therefore, we must pump both outer sequences of hashes. However,
59+
there are `p+2` characters between these two sequences of hashes, and `|vwx|` must
60+
be less than `p+1`. Therefore we have a contradiction, and `R'` must not be
61+
context-free.
62+
63+
Since `R'` is not context-free, it follows that the Rust's raw string literals
64+
must not be context-free.

branches/try2/src/libcollections/ringbuf.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ use core::cmp;
1919
use core::default::Default;
2020
use core::fmt;
2121
use core::iter::RandomAccessIterator;
22+
use core::iter;
23+
use std::hash::{Writer, Hash};
2224

2325
use {Deque, Collection, Mutable, MutableSeq};
2426
use vec::Vec;
@@ -450,6 +452,21 @@ impl<A: PartialEq> PartialEq for RingBuf<A> {
450452
}
451453
}
452454

455+
impl<A: PartialOrd> PartialOrd for RingBuf<A> {
456+
fn partial_cmp(&self, other: &RingBuf<A>) -> Option<Ordering> {
457+
iter::order::partial_cmp(self.iter(), other.iter())
458+
}
459+
}
460+
461+
impl<S: Writer, A: Hash<S>> Hash<S> for RingBuf<A> {
462+
fn hash(&self, state: &mut S) {
463+
self.len().hash(state);
464+
for elt in self.iter() {
465+
elt.hash(state);
466+
}
467+
}
468+
}
469+
453470
impl<A> FromIterator<A> for RingBuf<A> {
454471
fn from_iter<T: Iterator<A>>(iterator: T) -> RingBuf<A> {
455472
let (lower, _) = iterator.size_hint();
@@ -485,6 +502,7 @@ mod tests {
485502
use std::fmt::Show;
486503
use std::prelude::*;
487504
use std::gc::{GC, Gc};
505+
use std::hash;
488506
use test::Bencher;
489507
use test;
490508

@@ -912,6 +930,37 @@ mod tests {
912930
assert!(e == RingBuf::new());
913931
}
914932

933+
#[test]
934+
fn test_hash() {
935+
let mut x = RingBuf::new();
936+
let mut y = RingBuf::new();
937+
938+
x.push(1i);
939+
x.push(2);
940+
x.push(3);
941+
942+
y.push(0i);
943+
y.push(1i);
944+
y.pop_front();
945+
y.push(2);
946+
y.push(3);
947+
948+
assert!(hash::hash(&x) == hash::hash(&y));
949+
}
950+
951+
#[test]
952+
fn test_ord() {
953+
let x = RingBuf::new();
954+
let mut y = RingBuf::new();
955+
y.push(1i);
956+
y.push(2);
957+
y.push(3);
958+
assert!(x < y);
959+
assert!(y > x);
960+
assert!(x <= x);
961+
assert!(x >= x);
962+
}
963+
915964
#[test]
916965
fn test_show() {
917966
let ringbuf: RingBuf<int> = range(0i, 10).collect();

branches/try2/src/libcore/failure.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use intrinsics;
3737
#[lang="fail_"]
3838
fn fail_(expr: &'static str, file: &'static str, line: uint) -> ! {
3939
format_args!(|args| -> () {
40-
begin_unwind(args, file, line);
40+
begin_unwind(args, &(file, line));
4141
}, "{}", expr);
4242

4343
unsafe { intrinsics::abort() }
@@ -48,18 +48,20 @@ fn fail_(expr: &'static str, file: &'static str, line: uint) -> ! {
4848
fn fail_bounds_check(file: &'static str, line: uint,
4949
index: uint, len: uint) -> ! {
5050
format_args!(|args| -> () {
51-
begin_unwind(args, file, line);
51+
begin_unwind(args, &(file, line));
5252
}, "index out of bounds: the len is {} but the index is {}", len, index);
5353
unsafe { intrinsics::abort() }
5454
}
5555

5656
#[cold]
57-
pub fn begin_unwind(fmt: &fmt::Arguments, file: &'static str, line: uint) -> ! {
57+
pub fn begin_unwind(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
5858
#[allow(ctypes)]
5959
extern {
6060
#[lang = "begin_unwind"]
6161
fn begin_unwind(fmt: &fmt::Arguments, file: &'static str,
6262
line: uint) -> !;
6363
}
64+
let (file, line) = *file_line;
6465
unsafe { begin_unwind(fmt, file, line) }
6566
}
67+

branches/try2/src/libcore/macros.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ macro_rules! fail(
3333
// up with the number of calls to fail!()
3434
#[inline(always)]
3535
fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
36-
::core::failure::begin_unwind(fmt, file!(), line!())
36+
static FILE_LINE: (&'static str, uint) = (file!(), line!());
37+
::core::failure::begin_unwind(fmt, &FILE_LINE)
3738
}
3839
format_args!(run_fmt, $fmt, $($arg)*)
3940
});

branches/try2/src/librustc/metadata/common.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,9 @@ pub static tag_region_param_def_index: uint = 0x94;
227227
pub static tag_unboxed_closures: uint = 0x95;
228228
pub static tag_unboxed_closure: uint = 0x96;
229229
pub static tag_unboxed_closure_type: uint = 0x97;
230+
231+
pub static tag_struct_fields: uint = 0x98;
232+
pub static tag_struct_field: uint = 0x99;
233+
pub static tag_struct_field_id: uint = 0x9a;
234+
235+
pub static tag_attribute_is_sugared_doc: uint = 0x9b;

branches/try2/src/librustc/metadata/csearch.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ use syntax::attr;
2929
use syntax::diagnostic::expect;
3030
use syntax::parse::token;
3131

32+
use std::collections::hashmap::HashMap;
33+
3234
pub struct StaticMethodInfo {
3335
pub ident: ast::Ident,
3436
pub def_id: ast::DefId,
@@ -192,6 +194,12 @@ pub fn get_struct_fields(cstore: &cstore::CStore,
192194
decoder::get_struct_fields(cstore.intr.clone(), &*cdata, def.node)
193195
}
194196

197+
pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: ast::DefId) -> HashMap<ast::NodeId,
198+
Vec<ast::Attribute>> {
199+
let cdata = cstore.get_crate_data(def.krate);
200+
decoder::get_struct_field_attrs(&*cdata)
201+
}
202+
195203
pub fn get_type(tcx: &ty::ctxt,
196204
def: ast::DefId)
197205
-> ty::Polytype {

branches/try2/src/librustc/metadata/decoder.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use std::hash::Hash;
3434
use std::hash;
3535
use std::io::extensions::u64_from_be_bytes;
3636
use std::io;
37+
use std::collections::hashmap::HashMap;
3738
use std::rc::Rc;
3839
use std::u64;
3940
use serialize::ebml::reader;
@@ -963,6 +964,19 @@ pub fn get_item_attrs(cdata: Cmd,
963964
f(get_attributes(item));
964965
}
965966

967+
pub fn get_struct_field_attrs(cdata: Cmd) -> HashMap<ast::NodeId, Vec<ast::Attribute>> {
968+
let data = ebml::Doc::new(cdata.data());
969+
let fields = reader::get_doc(data, tag_struct_fields);
970+
let mut map = HashMap::new();
971+
reader::tagged_docs(fields, tag_struct_field, |field| {
972+
let id = reader::doc_as_u32(reader::get_doc(field, tag_struct_field_id));
973+
let attrs = get_attributes(field);
974+
map.insert(id, attrs);
975+
true
976+
});
977+
map
978+
}
979+
966980
fn struct_field_family_to_visibility(family: Family) -> ast::Visibility {
967981
match family {
968982
PublicField => ast::Public,
@@ -1042,6 +1056,9 @@ fn get_attributes(md: ebml::Doc) -> Vec<ast::Attribute> {
10421056
match reader::maybe_get_doc(md, tag_attributes) {
10431057
Some(attrs_d) => {
10441058
reader::tagged_docs(attrs_d, tag_attribute, |attr_doc| {
1059+
let is_sugared_doc = reader::doc_as_u8(
1060+
reader::get_doc(attr_doc, tag_attribute_is_sugared_doc)
1061+
) == 1;
10451062
let meta_items = get_meta_items(attr_doc);
10461063
// Currently it's only possible to have a single meta item on
10471064
// an attribute
@@ -1053,7 +1070,7 @@ fn get_attributes(md: ebml::Doc) -> Vec<ast::Attribute> {
10531070
id: attr::mk_attr_id(),
10541071
style: ast::AttrOuter,
10551072
value: meta_item,
1056-
is_sugared_doc: false,
1073+
is_sugared_doc: is_sugared_doc,
10571074
},
10581075
span: codemap::DUMMY_SP
10591076
});

branches/try2/src/librustc/metadata/encoder.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,6 +1490,7 @@ fn encode_attributes(ebml_w: &mut Encoder, attrs: &[Attribute]) {
14901490
ebml_w.start_tag(tag_attributes);
14911491
for attr in attrs.iter() {
14921492
ebml_w.start_tag(tag_attribute);
1493+
ebml_w.wr_tagged_u8(tag_attribute_is_sugared_doc, attr.node.is_sugared_doc as u8);
14931494
encode_meta_item(ebml_w, attr.node.value);
14941495
ebml_w.end_tag();
14951496
}
@@ -1644,6 +1645,29 @@ fn encode_unboxed_closures<'a>(
16441645
ebml_w.end_tag();
16451646
}
16461647

1648+
fn encode_struct_field_attrs(ebml_w: &mut Encoder, krate: &Crate) {
1649+
struct StructFieldVisitor<'a, 'b> {
1650+
ebml_w: &'a mut Encoder<'b>,
1651+
}
1652+
1653+
impl<'a, 'b> Visitor<()> for StructFieldVisitor<'a, 'b> {
1654+
fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) {
1655+
self.ebml_w.start_tag(tag_struct_field);
1656+
self.ebml_w.wr_tagged_u32(tag_struct_field_id, field.node.id);
1657+
encode_attributes(self.ebml_w, field.node.attrs.as_slice());
1658+
self.ebml_w.end_tag();
1659+
}
1660+
}
1661+
1662+
ebml_w.start_tag(tag_struct_fields);
1663+
visit::walk_crate(&mut StructFieldVisitor {
1664+
ebml_w: ebml_w
1665+
}, krate, ());
1666+
ebml_w.end_tag();
1667+
}
1668+
1669+
1670+
16471671
struct ImplVisitor<'a,'b,'c> {
16481672
ecx: &'a EncodeContext<'b>,
16491673
ebml_w: &'a mut Encoder<'c>,
@@ -1928,6 +1952,8 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
19281952
stats.index_bytes = ebml_w.writer.tell().unwrap() - i;
19291953
ebml_w.end_tag();
19301954

1955+
encode_struct_field_attrs(&mut ebml_w, krate);
1956+
19311957
stats.total_bytes = ebml_w.writer.tell().unwrap();
19321958

19331959
if tcx.sess.meta_stats() {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4071,7 +4071,7 @@ pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec<field_ty> {
40714071

40724072
let len = results.as_slice().iter().map(|x| x.len()).sum();
40734073
let mut result: Vec<field_ty> = Vec::with_capacity(len);
4074-
result.extend(results.as_slice().iter().flat_map(|rs| rs.iter().map(|&f| f)));
4074+
result.extend(results.as_slice().iter().flat_map(|rs| rs.iter().map(|f| f.clone())));
40754075
assert!(result.len() == len);
40764076
result
40774077
} else {
@@ -4085,7 +4085,7 @@ pub fn lookup_struct_field(cx: &ctxt,
40854085
-> field_ty {
40864086
let r = lookup_struct_fields(cx, parent);
40874087
match r.iter().find(|f| f.id.node == field_id.node) {
4088-
Some(t) => *t,
4088+
Some(t) => t.clone(),
40894089
None => cx.sess.bug("struct ID not found in parent's fields")
40904090
}
40914091
}

branches/try2/src/librustc/middle/typeck/check/_match.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt,
322322
}
323323
Some(&(index, ref mut used)) => {
324324
*used = true;
325-
let class_field = *class_fields.get(index);
325+
let class_field = class_fields.get(index).clone();
326326
let field_type = ty::lookup_field_type(tcx,
327327
class_id,
328328
class_field.id,

branches/try2/src/librustc/middle/typeck/coherence.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,29 +60,25 @@ fn get_base_type(inference_context: &InferCtxt,
6060
span: Span,
6161
original_type: t)
6262
-> Option<t> {
63-
let resolved_type;
64-
match resolve_type(inference_context,
65-
Some(span),
66-
original_type,
67-
resolve_ivar) {
68-
Ok(resulting_type) if !type_is_ty_var(resulting_type) => {
69-
resolved_type = resulting_type;
70-
}
63+
let resolved_type = match resolve_type(inference_context,
64+
Some(span),
65+
original_type,
66+
resolve_ivar) {
67+
Ok(resulting_type) if !type_is_ty_var(resulting_type) => resulting_type,
7168
_ => {
7269
inference_context.tcx.sess.span_fatal(span,
7370
"the type of this value must be known in order \
7471
to determine the base type");
7572
}
76-
}
73+
};
7774

7875
match get(resolved_type).sty {
7976
ty_enum(..) | ty_struct(..) | ty_unboxed_closure(..) => {
8077
debug!("(getting base type) found base type");
8178
Some(resolved_type)
8279
}
83-
// FIXME(14865) I would prefere to use `_` here, but that causes a
84-
// compiler error.
85-
ty_uniq(_) | ty_rptr(_, _) | ty_trait(..) if ty::type_is_trait(resolved_type) => {
80+
81+
_ if ty::type_is_trait(resolved_type) => {
8682
debug!("(getting base type) found base type (trait)");
8783
Some(resolved_type)
8884
}

branches/try2/src/librustdoc/clean/inline.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ fn build_struct(tcx: &ty::ctxt, did: ast::DefId) -> clean::Struct {
209209
_ => doctree::Plain,
210210
},
211211
generics: (&t.generics, subst::TypeSpace).clean(),
212-
fields: fields.iter().map(|f| f.clean()).collect(),
212+
fields: fields.clean(),
213213
fields_stripped: false,
214214
}
215215
}

0 commit comments

Comments
 (0)