diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 71b20cb0946c4..0bcb3219858c9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -84,7 +84,8 @@ feature. We use the 'fork and pull' model described there. Please make pull requests against the `master` branch. All pull requests are reviewed by another person. We have a bot, -@rust-highfive, that will automatically assign a random person to review your request. +@rust-highfive, that will automatically assign a random person to review your +request. If you want to request that a specific person reviews your pull request, you can add an `r?` to the message. For example, Steve usually reviews @@ -124,6 +125,10 @@ To save @bors some work, and to get small changes through more quickly, when the other rollup-eligible patches too, and they'll get tested and merged at the same time. +To find documentation-related issues, sort by the [A-docs label][adocs]. + +[adocs]: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AA-docs + ## Issue Triage Sometimes, an issue will stay open, even though the bug has been fixed. And @@ -132,8 +137,40 @@ meantime. It can be helpful to go through older bug reports and make sure that they are still valid. Load up an older issue, double check that it's still true, and -leave a comment letting us know if it is or is not. The [least recently updated sort][lru] is good for finding issues like this. +leave a comment letting us know if it is or is not. The [least recently +updated sort][lru] is good for finding issues like this. + +Contributors with sufficient permissions on the Rust repo can help by adding +labels to triage issues: + +* Yellow, **A**-prefixed labels state which **area** of the project an issue + relates to. + +* Magenta, **B**-prefixed labels identify bugs which **belong** elsewhere. + +* Green, **E**-prefixed labels explain the level of **experience** necessary + to fix the issue. + +* Red, **I**-prefixed labels indicate the **importance** of the issue. The + [I-nominated][inom] label indicates that an issue has been nominated for + prioritizing at the next triage meeting. + +* Orange, **P**-prefixed labels indicate a bug's **priority**. These labels + are only assigned during triage meetings, and replace the [I-nominated][inom] + label. + +* Blue, **T**-prefixed bugs denote which **team** the issue belongs to. + +* Dark blue, **beta-** labels track changes which need to be backported into + the beta branches. + +* The purple **metabug** label marks lists of bugs collected by other + categories. + +If you're looking for somewhere to start, check out the [E-easy][eeasy] tag. +[inom]: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AI-nominated +[eeasy]: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy [lru]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-asc ## Out-of-tree Contributions diff --git a/src/doc/reference.md b/src/doc/reference.md index 8d1b93ce3c8b9..f69f15200d085 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -1892,12 +1892,13 @@ interpreted: On `enum`s: -- `repr` - on C-like enums, this sets the underlying type used for - representation. Takes one argument, which is the primitive - type this enum should be represented for, or `C`, which specifies that it - should be the default `enum` size of the C ABI for that platform. Note that - enum representation in C is undefined, and this may be incorrect when the C - code is compiled with certain flags. +- `repr` - this sets the underlying type used for representation of the + discriminant. Takes one argument, which is the primitive type this enum + should be represented as, or `C`, which specifies that it should be the + default `enum` size of the C ABI for that platform. Note that enum + representation in C is implementation defined, and this may be incorrect when + the C code is compiled with certain flags. The representation attribute + inhibits elision of the enum discriminant in layout optimizations. On `struct`s: @@ -3255,8 +3256,8 @@ User-defined types have limited capabilities. The primitive types are the following: * The boolean type `bool` with values `true` and `false`. -* The machine types. -* The machine-dependent integer and floating-point types. +* The machine types (integer and floating-point). +* The machine-dependent integer types. #### Machine types diff --git a/src/doc/style/features/functions-and-methods/README.md b/src/doc/style/features/functions-and-methods/README.md index 2dcfc382d0baf..611cd564ccac7 100644 --- a/src/doc/style/features/functions-and-methods/README.md +++ b/src/doc/style/features/functions-and-methods/README.md @@ -20,6 +20,7 @@ for any operation that is clearly associated with a particular type. Methods have numerous advantages over functions: + * They do not need to be imported or qualified to be used: all you need is a value of the appropriate type. * Their invocation performs autoborrowing (including mutable borrows). diff --git a/src/doc/style/features/functions-and-methods/input.md b/src/doc/style/features/functions-and-methods/input.md index a1310de2e6063..072021194c13e 100644 --- a/src/doc/style/features/functions-and-methods/input.md +++ b/src/doc/style/features/functions-and-methods/input.md @@ -159,7 +159,7 @@ fn foo(a: u8) { ... } Note that [`ascii::Ascii`](http://static.rust-lang.org/doc/master/std/ascii/struct.Ascii.html) is a _wrapper_ around `u8` that guarantees the highest bit is zero; see -[newtype patterns]() for more details on creating typesafe wrappers. +[newtype patterns](../types/newtype.md) for more details on creating typesafe wrappers. Static enforcement usually comes at little run-time cost: it pushes the costs to the boundaries (e.g. when a `u8` is first converted into an diff --git a/src/doc/style/features/let.md b/src/doc/style/features/let.md index f13a84f6fee86..01dff3dcceaf1 100644 --- a/src/doc/style/features/let.md +++ b/src/doc/style/features/let.md @@ -34,7 +34,7 @@ Prefer ```rust let foo = match bar { - Baz => 0, + Baz => 0, Quux => 1 }; ``` @@ -44,7 +44,7 @@ over ```rust let foo; match bar { - Baz => { + Baz => { foo = 0; } Quux => { @@ -61,8 +61,8 @@ conditional expression. Prefer ```rust -s.iter().map(|x| x * 2) - .collect::>() +let v = s.iter().map(|x| x * 2) + .collect::>(); ``` over diff --git a/src/doc/style/ownership/builders.md b/src/doc/style/ownership/builders.md index 54992341ce54a..348be516e374d 100644 --- a/src/doc/style/ownership/builders.md +++ b/src/doc/style/ownership/builders.md @@ -16,7 +16,7 @@ If `T` is such a data structure, consider introducing a `T` _builder_: value. When possible, choose a better name: e.g. `Command` is the builder for `Process`. 2. The builder constructor should take as parameters only the data _required_ to - to make a `T`. + make a `T`. 3. The builder should offer a suite of convenient methods for configuration, including setting up compound inputs (like slices) incrementally. These methods should return `self` to allow chaining. diff --git a/src/doc/trpl/conditional-compilation.md b/src/doc/trpl/conditional-compilation.md index 73eb0101692af..a944b852d249f 100644 --- a/src/doc/trpl/conditional-compilation.md +++ b/src/doc/trpl/conditional-compilation.md @@ -34,7 +34,7 @@ These can nest arbitrarily: As for how to enable or disable these switches, if you’re using Cargo, they get set in the [`[features]` section][features] of your `Cargo.toml`: -[features]: http://doc.crates.io/manifest.html#the-[features]-section +[features]: http://doc.crates.io/manifest.html#the-%5Bfeatures%5D-section ```toml [features] diff --git a/src/doc/trpl/glossary.md b/src/doc/trpl/glossary.md index 9845fcbdcd173..c97da0e95b823 100644 --- a/src/doc/trpl/glossary.md +++ b/src/doc/trpl/glossary.md @@ -19,7 +19,7 @@ In the example above `x` and `y` have arity 2. `z` has arity 3. When a compiler is compiling your program, it does a number of different things. One of the things that it does is turn the text of your program into an -‘abstract syntax tree’, or‘AST’. This tree is a representation of the +‘abstract syntax tree’, or ‘AST’. This tree is a representation of the structure of your program. For example, `2 + 3` can be turned into a tree: ```text diff --git a/src/doc/trpl/method-syntax.md b/src/doc/trpl/method-syntax.md index e5f490e15e13e..1f694f71a883f 100644 --- a/src/doc/trpl/method-syntax.md +++ b/src/doc/trpl/method-syntax.md @@ -4,7 +4,7 @@ Functions are great, but if you want to call a bunch of them on some data, it can be awkward. Consider this code: ```rust,ignore -baz(bar(foo))); +baz(bar(foo)); ``` We would read this left-to right, and so we see ‘baz bar foo’. But this isn’t the diff --git a/src/doc/trpl/traits.md b/src/doc/trpl/traits.md index 9ac170ddec298..2ef9e7ca22e60 100644 --- a/src/doc/trpl/traits.md +++ b/src/doc/trpl/traits.md @@ -285,7 +285,7 @@ fn bar(x: T, y: K) where T: Clone, K: Clone + Debug { fn main() { foo("Hello", "world"); - bar("Hello", "workd"); + bar("Hello", "world"); } ``` diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 4d52eb8e8ae67..8dacfa53bc980 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -440,6 +440,8 @@ impl Vec { } /// Extracts a slice containing the entire vector. + /// + /// Equivalent to `&s[..]`. #[inline] #[unstable(feature = "convert", reason = "waiting on RFC revision")] @@ -447,7 +449,9 @@ impl Vec { self } - /// Deprecated: use `&mut s[..]` instead. + /// Extracts a mutable slice of the entire vector. + /// + /// Equivalent to `&mut s[..]`. #[inline] #[unstable(feature = "convert", reason = "waiting on RFC revision")] diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index da873f76d1bdd..ee1cab4076dc5 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -269,6 +269,50 @@ impl<'a> Display for Arguments<'a> { /// Format trait for the `:?` format. Useful for debugging, all types /// should implement this. +/// +/// Generally speaking, you should just `derive` a `Debug` implementation. +/// +/// # Examples +/// +/// Deriving an implementation: +/// +/// ``` +/// #[derive(Debug)] +/// struct Point { +/// x: i32, +/// y: i32, +/// } +/// +/// let origin = Point { x: 0, y: 0 }; +/// +/// println!("The origin is: {:?}", origin); +/// ``` +/// +/// Manually implementing: +/// +/// ``` +/// use std::fmt; +/// +/// struct Point { +/// x: i32, +/// y: i32, +/// } +/// +/// impl fmt::Debug for Point { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// write!(f, "({}, {})", self.x, self.y) +/// } +/// } +/// +/// let origin = Point { x: 0, y: 0 }; +/// +/// println!("The origin is: {:?}", origin); +/// ``` +/// +/// There are a number of `debug_*` methods on `Formatter` to help you with manual +/// implementations, such as [`debug_struct`][debug_struct]. +/// +/// [debug_struct]: ../std/fmt/struct.Formatter.html#method.debug_struct #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is \ defined in your crate, add `#[derive(Debug)]` or \ diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index 65433c528bc52..41ae0f2d5e203 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -436,23 +436,29 @@ pub mod reader { } } - pub fn tagged_docs(d: Doc, tg: usize, mut it: F) -> bool where - F: FnMut(Doc) -> bool, - { - let mut pos = d.start; - while pos < d.end { - let elt_tag = try_or!(tag_at(d.data, pos), false); - let elt_size = try_or!(tag_len_at(d.data, elt_tag), false); - pos = elt_size.next + elt_size.val; - if elt_tag.val == tg { - let doc = Doc { data: d.data, start: elt_size.next, - end: pos }; - if !it(doc) { - return false; + pub fn tagged_docs<'a>(d: Doc<'a>, tag: usize) -> TaggedDocsIterator<'a> { + TaggedDocsIterator { + iter: docs(d), + tag: tag, + } + } + + pub struct TaggedDocsIterator<'a> { + iter: DocsIterator<'a>, + tag: usize, + } + + impl<'a> Iterator for TaggedDocsIterator<'a> { + type Item = Doc<'a>; + + fn next(&mut self) -> Option> { + while let Some((tag, doc)) = self.iter.next() { + if tag == self.tag { + return Some(doc); } } + None } - return true; } pub fn with_doc_data(d: Doc, f: F) -> T where diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 5eefb99b058f1..ebb24bbd24843 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -76,19 +76,12 @@ fn lookup_hash<'a, F>(d: rbml::Doc<'a>, mut eq_fn: F, hash: u64) -> Option(item_id: ast::NodeId, @@ -191,12 +184,9 @@ fn fn_constness(item: rbml::Doc) -> ast::Constness { } fn item_sort(item: rbml::Doc) -> Option { - let mut ret = None; - reader::tagged_docs(item, tag_item_trait_item_sort, |doc| { - ret = Some(doc.as_str_slice().as_bytes()[0] as char); - false - }); - ret + reader::tagged_docs(item, tag_item_trait_item_sort).nth(0).map(|doc| { + doc.as_str_slice().as_bytes()[0] as char + }) } fn item_symbol(item: rbml::Doc) -> String { @@ -210,12 +200,9 @@ fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> ast::DefId { } fn item_parent_item(cdata: Cmd, d: rbml::Doc) -> Option { - let mut ret = None; - reader::tagged_docs(d, tag_items_data_parent_item, |did| { - ret = Some(translated_def_id(cdata, did)); - false - }); - ret + reader::tagged_docs(d, tag_items_data_parent_item).nth(0).map(|did| { + translated_def_id(cdata, did) + }) } fn item_require_parent_item(cdata: Cmd, d: rbml::Doc) -> ast::DefId { @@ -232,10 +219,8 @@ fn get_provided_source(d: rbml::Doc, cdata: Cmd) -> Option { }) } -fn each_reexport(d: rbml::Doc, f: F) -> bool where - F: FnMut(rbml::Doc) -> bool, -{ - reader::tagged_docs(d, tag_items_data_item_reexport, f) +fn reexports<'a>(d: rbml::Doc<'a>) -> reader::TaggedDocsIterator<'a> { + reader::tagged_docs(d, tag_items_data_item_reexport) } fn variant_disr_val(d: rbml::Doc) -> Option { @@ -284,12 +269,9 @@ fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) } fn enum_variant_ids(item: rbml::Doc, cdata: Cmd) -> Vec { - let mut ids = vec![]; - reader::tagged_docs(item, tag_items_data_item_variant, |p| { - ids.push(translated_def_id(cdata, p)); - true - }); - ids + reader::tagged_docs(item, tag_items_data_item_variant) + .map(|p| translated_def_id(cdata, p)) + .collect() } fn item_path(item_doc: rbml::Doc) -> Vec { @@ -406,13 +388,9 @@ fn parse_polarity(item_doc: rbml::Doc) -> ast::ImplPolarity { fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec { let names_doc = reader::get_doc(item_doc, tag_associated_type_names); - let mut names = Vec::new(); - reader::tagged_docs(names_doc, tag_associated_type_name, |name_doc| { - let name = token::intern(name_doc.as_str_slice()); - names.push(name); - true - }); - names + reader::tagged_docs(names_doc, tag_associated_type_name) + .map(|name_doc| token::intern(name_doc.as_str_slice())) + .collect() } pub fn get_trait_def<'tcx>(cdata: Cmd, @@ -546,7 +524,7 @@ pub fn each_lang_item(cdata: Cmd, mut f: F) -> bool where { let root = rbml::Doc::new(cdata.data()); let lang_items = reader::get_doc(root, tag_lang_items); - reader::tagged_docs(lang_items, tag_lang_items_item, |item_doc| { + reader::tagged_docs(lang_items, tag_lang_items_item).all(|item_doc| { let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id); let id = reader::doc_as_u32(id_doc) as usize; let node_id_doc = reader::get_doc(item_doc, @@ -566,7 +544,7 @@ fn each_child_of_item_or_crate(intr: Rc, G: FnMut(ast::CrateNum) -> Rc, { // Iterate over all children. - let _ = reader::tagged_docs(item_doc, tag_mod_child, |child_info_doc| { + for child_info_doc in reader::tagged_docs(item_doc, tag_mod_child) { let child_def_id = translated_def_id(cdata, child_info_doc); // This item may be in yet another crate if it was the child of a @@ -592,26 +570,20 @@ fn each_child_of_item_or_crate(intr: Rc, let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id); let visibility = item_visibility(child_item_doc); callback(def_like, child_name, visibility); - } } - - true - }); + } // As a special case, iterate over all static methods of // associated implementations too. This is a bit of a botch. // --pcwalton - let _ = reader::tagged_docs(item_doc, - tag_items_data_item_inherent_impl, - |inherent_impl_def_id_doc| { - let inherent_impl_def_id = item_def_id(inherent_impl_def_id_doc, - cdata); + for inherent_impl_def_id_doc in reader::tagged_docs(item_doc, + tag_items_data_item_inherent_impl) { + let inherent_impl_def_id = item_def_id(inherent_impl_def_id_doc, cdata); let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items); if let Some(inherent_impl_doc) = maybe_find_item(inherent_impl_def_id.node, items) { - let _ = reader::tagged_docs(inherent_impl_doc, - tag_item_impl_item, - |impl_item_def_id_doc| { + for impl_item_def_id_doc in reader::tagged_docs(inherent_impl_doc, + tag_item_impl_item) { let impl_item_def_id = item_def_id(impl_item_def_id_doc, cdata); if let Some(impl_method_doc) = maybe_find_item(impl_item_def_id.node, items) { @@ -625,14 +597,11 @@ fn each_child_of_item_or_crate(intr: Rc, item_visibility(impl_method_doc)); } } - true - }); + } } - true - }); + } - // Iterate over all reexports. - let _ = each_reexport(item_doc, |reexport_doc| { + for reexport_doc in reexports(item_doc) { let def_id_doc = reader::get_doc(reexport_doc, tag_items_data_item_reexport_def_id); let child_def_id = translated_def_id(cdata, def_id_doc); @@ -662,9 +631,8 @@ fn each_child_of_item_or_crate(intr: Rc, // a public re-export. callback(def_like, token::intern(name), ast::Public); } - true - }); + } } /// Iterates over each child of the given item. @@ -841,22 +809,15 @@ fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory { /// Returns the def IDs of all the items in the given implementation. pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId) -> Vec { - let mut impl_items = Vec::new(); - reader::tagged_docs(lookup_item(impl_id, cdata.data()), - tag_item_impl_item, |doc| { + reader::tagged_docs(lookup_item(impl_id, cdata.data()), tag_item_impl_item).map(|doc| { let def_id = item_def_id(doc, cdata); match item_sort(doc) { - Some('C') => impl_items.push(ty::ConstTraitItemId(def_id)), - Some('r') | Some('p') => { - impl_items.push(ty::MethodTraitItemId(def_id)) - } - Some('t') => impl_items.push(ty::TypeTraitItemId(def_id)), + Some('C') => ty::ConstTraitItemId(def_id), + Some('r') | Some('p') => ty::MethodTraitItemId(def_id), + Some('t') => ty::TypeTraitItemId(def_id), _ => panic!("unknown impl item sort"), } - true - }); - - impl_items + }).collect() } pub fn get_trait_name(intr: Rc, @@ -944,20 +905,15 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId) -> Vec { let data = cdata.data(); let item = lookup_item(id, data); - let mut result = Vec::new(); - reader::tagged_docs(item, tag_item_trait_item, |mth| { + reader::tagged_docs(item, tag_item_trait_item).map(|mth| { let def_id = item_def_id(mth, cdata); match item_sort(mth) { - Some('C') => result.push(ty::ConstTraitItemId(def_id)), - Some('r') | Some('p') => { - result.push(ty::MethodTraitItemId(def_id)); - } - Some('t') => result.push(ty::TypeTraitItemId(def_id)), + Some('C') => ty::ConstTraitItemId(def_id), + Some('r') | Some('p') => ty::MethodTraitItemId(def_id), + Some('t') => ty::TypeTraitItemId(def_id), _ => panic!("unknown trait item sort"), } - true - }); - result + }).collect() } pub fn get_item_variances(cdata: Cmd, id: ast::NodeId) -> ty::ItemVariances { @@ -975,9 +931,8 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc, -> Vec>> { let data = cdata.data(); let item = lookup_item(id, data); - let mut result = Vec::new(); - reader::tagged_docs(item, tag_item_trait_item, |mth_id| { + reader::tagged_docs(item, tag_item_trait_item).filter_map(|mth_id| { let did = item_def_id(mth_id, cdata); let mth = lookup_item(did.node, data); @@ -987,13 +942,14 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc, did.node, tcx); if let ty::MethodTraitItem(ref method) = trait_item { - result.push((*method).clone()) + Some((*method).clone()) + } else { + None } + } else { + None } - true - }); - - return result; + }).collect() } pub fn get_associated_consts<'tcx>(intr: Rc, @@ -1003,10 +959,9 @@ pub fn get_associated_consts<'tcx>(intr: Rc, -> Vec>> { let data = cdata.data(); let item = lookup_item(id, data); - let mut result = Vec::new(); - for &tag in &[tag_item_trait_item, tag_item_impl_item] { - reader::tagged_docs(item, tag, |ac_id| { + [tag_item_trait_item, tag_item_impl_item].iter().flat_map(|&tag| { + reader::tagged_docs(item, tag).filter_map(|ac_id| { let did = item_def_id(ac_id, cdata); let ac_doc = lookup_item(did.node, data); @@ -1016,14 +971,15 @@ pub fn get_associated_consts<'tcx>(intr: Rc, did.node, tcx); if let ty::ConstTraitItem(ref ac) = trait_item { - result.push((*ac).clone()) + Some((*ac).clone()) + } else { + None } + } else { + None } - true - }); - } - - return result; + }) + }).collect() } pub fn get_type_name_if_impl(cdata: Cmd, @@ -1033,13 +989,9 @@ pub fn get_type_name_if_impl(cdata: Cmd, return None; } - let mut ret = None; - reader::tagged_docs(item, tag_item_impl_type_basename, |doc| { - ret = Some(token::intern(doc.as_str_slice())); - false - }); - - ret + reader::tagged_docs(item, tag_item_impl_type_basename).nth(0).map(|doc| { + token::intern(doc.as_str_slice()) + }) } pub fn get_methods_if_impl(intr: Rc, @@ -1052,20 +1004,15 @@ pub fn get_methods_if_impl(intr: Rc, } // If this impl implements a trait, don't consider it. - let ret = reader::tagged_docs(item, tag_item_trait_ref, |_doc| { - false - }); - - if !ret { return None } + if reader::tagged_docs(item, tag_item_trait_ref).next().is_some() { + return None; + } - let mut impl_method_ids = Vec::new(); - reader::tagged_docs(item, tag_item_impl_item, |impl_method_doc| { - impl_method_ids.push(item_def_id(impl_method_doc, cdata)); - true - }); + let impl_method_ids = reader::tagged_docs(item, tag_item_impl_item) + .map(|impl_method_doc| item_def_id(impl_method_doc, cdata)); let mut impl_methods = Vec::new(); - for impl_method_id in &impl_method_ids { + for impl_method_id in impl_method_ids { let impl_method_doc = lookup_item(impl_method_id.node, cdata.data()); let family = item_family(impl_method_doc); match family { @@ -1090,12 +1037,9 @@ pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd, -> Option { let item = lookup_item(node_id, cdata.data()); - let mut ret = None; - reader::tagged_docs(item, tag_items_data_item_is_tuple_struct_ctor, |_| { - ret = Some(item_require_parent_item(cdata, item)); - false - }); - ret + reader::tagged_docs(item, tag_items_data_item_is_tuple_struct_ctor).next().map(|_| { + item_require_parent_item(cdata, item) + }) } pub fn get_item_attrs(cdata: Cmd, @@ -1113,14 +1057,11 @@ pub fn get_item_attrs(cdata: Cmd, pub fn get_struct_field_attrs(cdata: Cmd) -> HashMap> { let data = rbml::Doc::new(cdata.data()); let fields = reader::get_doc(data, tag_struct_fields); - let mut map = HashMap::new(); - reader::tagged_docs(fields, tag_struct_field, |field| { + reader::tagged_docs(fields, tag_struct_field).map(|field| { let id = reader::doc_as_u32(reader::get_doc(field, tag_struct_field_id)); let attrs = get_attributes(field); - map.insert(id, attrs); - true - }); - map + (id, attrs) + }).collect() } fn struct_field_family_to_visibility(family: Family) -> ast::Visibility { @@ -1135,81 +1076,69 @@ pub fn get_struct_fields(intr: Rc, cdata: Cmd, id: ast::NodeId) -> Vec { let data = cdata.data(); let item = lookup_item(id, data); - let mut result = Vec::new(); - reader::tagged_docs(item, tag_item_field, |an_item| { + reader::tagged_docs(item, tag_item_field).filter_map(|an_item| { let f = item_family(an_item); if f == PublicField || f == InheritedField { let name = item_name(&*intr, an_item); let did = item_def_id(an_item, cdata); let tagdoc = reader::get_doc(an_item, tag_item_field_origin); let origin_id = translated_def_id(cdata, tagdoc); - result.push(ty::field_ty { + Some(ty::field_ty { name: name, id: did, vis: struct_field_family_to_visibility(f), origin: origin_id, - }); + }) + } else { + None } - true - }); - reader::tagged_docs(item, tag_item_unnamed_field, |an_item| { + }).chain(reader::tagged_docs(item, tag_item_unnamed_field).map(|an_item| { let did = item_def_id(an_item, cdata); let tagdoc = reader::get_doc(an_item, tag_item_field_origin); let f = item_family(an_item); let origin_id = translated_def_id(cdata, tagdoc); - result.push(ty::field_ty { + ty::field_ty { name: special_idents::unnamed_field.name, id: did, vis: struct_field_family_to_visibility(f), origin: origin_id, - }); - true - }); - result + } + })).collect() } fn get_meta_items(md: rbml::Doc) -> Vec> { - let mut items: Vec> = Vec::new(); - reader::tagged_docs(md, tag_meta_item_word, |meta_item_doc| { + reader::tagged_docs(md, tag_meta_item_word).map(|meta_item_doc| { let nd = reader::get_doc(meta_item_doc, tag_meta_item_name); let n = token::intern_and_get_ident(nd.as_str_slice()); - items.push(attr::mk_word_item(n)); - true - }); - reader::tagged_docs(md, tag_meta_item_name_value, |meta_item_doc| { + attr::mk_word_item(n) + }).chain(reader::tagged_docs(md, tag_meta_item_name_value).map(|meta_item_doc| { let nd = reader::get_doc(meta_item_doc, tag_meta_item_name); let vd = reader::get_doc(meta_item_doc, tag_meta_item_value); let n = token::intern_and_get_ident(nd.as_str_slice()); let v = token::intern_and_get_ident(vd.as_str_slice()); // FIXME (#623): Should be able to decode MetaNameValue variants, // but currently the encoder just drops them - items.push(attr::mk_name_value_item_str(n, v)); - true - }); - reader::tagged_docs(md, tag_meta_item_list, |meta_item_doc| { + attr::mk_name_value_item_str(n, v) + })).chain(reader::tagged_docs(md, tag_meta_item_list).map(|meta_item_doc| { let nd = reader::get_doc(meta_item_doc, tag_meta_item_name); let n = token::intern_and_get_ident(nd.as_str_slice()); let subitems = get_meta_items(meta_item_doc); - items.push(attr::mk_list_item(n, subitems.into_iter().collect())); - true - }); - return items; + attr::mk_list_item(n, subitems) + })).collect() } fn get_attributes(md: rbml::Doc) -> Vec { - let mut attrs: Vec = Vec::new(); match reader::maybe_get_doc(md, tag_attributes) { - Some(attrs_d) => { - reader::tagged_docs(attrs_d, tag_attribute, |attr_doc| { - let is_sugared_doc = reader::doc_as_u8( - reader::get_doc(attr_doc, tag_attribute_is_sugared_doc) - ) == 1; - let meta_items = get_meta_items(attr_doc); - // Currently it's only possible to have a single meta item on - // an attribute - assert_eq!(meta_items.len(), 1); - let meta_item = meta_items.into_iter().nth(0).unwrap(); - attrs.push( + Some(attrs_d) => { + reader::tagged_docs(attrs_d, tag_attribute).map(|attr_doc| { + let is_sugared_doc = reader::doc_as_u8( + reader::get_doc(attr_doc, tag_attribute_is_sugared_doc) + ) == 1; + let meta_items = get_meta_items(attr_doc); + // Currently it's only possible to have a single meta item on + // an attribute + assert_eq!(meta_items.len(), 1); + let meta_item = meta_items.into_iter().nth(0).unwrap(); codemap::Spanned { node: ast::Attribute_ { id: attr::mk_attr_id(), @@ -1218,13 +1147,11 @@ fn get_attributes(md: rbml::Doc) -> Vec { is_sugared_doc: is_sugared_doc, }, span: codemap::DUMMY_SP - }); - true - }); - } - None => () + } + }).collect() + }, + None => vec![], } - return attrs; } fn list_crate_attributes(md: rbml::Doc, hash: &Svh, @@ -1251,26 +1178,23 @@ pub struct CrateDep { } pub fn get_crate_deps(data: &[u8]) -> Vec { - let mut deps: Vec = Vec::new(); let cratedoc = rbml::Doc::new(data); let depsdoc = reader::get_doc(cratedoc, tag_crate_deps); - let mut crate_num = 1; + fn docstr(doc: rbml::Doc, tag_: usize) -> String { let d = reader::get_doc(doc, tag_); d.as_str_slice().to_string() } - reader::tagged_docs(depsdoc, tag_crate_dep, |depdoc| { + + reader::tagged_docs(depsdoc, tag_crate_dep).enumerate().map(|(crate_num, depdoc)| { let name = docstr(depdoc, tag_crate_dep_crate_name); let hash = Svh::new(&docstr(depdoc, tag_crate_dep_hash)); - deps.push(CrateDep { - cnum: crate_num, + CrateDep { + cnum: crate_num as u32 + 1, name: name, hash: hash, - }); - crate_num += 1; - true - }); - return deps; + } + }).collect() } fn list_crate_deps(data: &[u8], out: &mut io::Write) -> io::Result<()> { @@ -1362,14 +1286,11 @@ pub fn each_inherent_implementation_for_type(cdata: Cmd, where F: FnMut(ast::DefId), { let item_doc = lookup_item(id, cdata.data()); - reader::tagged_docs(item_doc, - tag_items_data_item_inherent_impl, - |impl_doc| { + for impl_doc in reader::tagged_docs(item_doc, tag_items_data_item_inherent_impl) { if reader::maybe_get_doc(impl_doc, tag_item_trait_ref).is_none() { callback(item_def_id(impl_doc, cdata)); } - true - }); + } } pub fn each_implementation_for_trait(cdata: Cmd, @@ -1379,12 +1300,9 @@ pub fn each_implementation_for_trait(cdata: Cmd, { if cdata.cnum == def_id.krate { let item_doc = lookup_item(def_id.node, cdata.data()); - let _ = reader::tagged_docs(item_doc, - tag_items_data_item_extension_impl, - |impl_doc| { + for impl_doc in reader::tagged_docs(item_doc, tag_items_data_item_extension_impl) { callback(item_def_id(impl_doc, cdata)); - true - }); + } return; } @@ -1394,13 +1312,12 @@ pub fn each_implementation_for_trait(cdata: Cmd, let def_id_u64 = def_to_u64(crate_local_did); let impls_doc = reader::get_doc(rbml::Doc::new(cdata.data()), tag_impls); - let _ = reader::tagged_docs(impls_doc, tag_impls_impl, |impl_doc| { + for impl_doc in reader::tagged_docs(impls_doc, tag_impls_impl) { let impl_trait = reader::get_doc(impl_doc, tag_impls_impl_trait_def_id); if reader::doc_as_u64(impl_trait) == def_id_u64 { callback(item_def_id(impl_doc, cdata)); } - true - }); + } } } @@ -1427,17 +1344,14 @@ pub fn get_native_libraries(cdata: Cmd) -> Vec<(cstore::NativeLibraryKind, String)> { let libraries = reader::get_doc(rbml::Doc::new(cdata.data()), tag_native_libraries); - let mut result = Vec::new(); - reader::tagged_docs(libraries, tag_native_libraries_lib, |lib_doc| { + reader::tagged_docs(libraries, tag_native_libraries_lib).map(|lib_doc| { let kind_doc = reader::get_doc(lib_doc, tag_native_libraries_kind); let name_doc = reader::get_doc(lib_doc, tag_native_libraries_name); let kind: cstore::NativeLibraryKind = cstore::NativeLibraryKind::from_u32(reader::doc_as_u32(kind_doc)).unwrap(); let name = name_doc.as_str().to_string(); - result.push((kind, name)); - true - }); - return result; + (kind, name) + }).collect() } pub fn get_plugin_registrar_fn(data: &[u8]) -> Option { @@ -1449,12 +1363,14 @@ pub fn each_exported_macro(data: &[u8], intr: &IdentInterner, mut f: F) where F: FnMut(ast::Name, Vec, String) -> bool, { let macros = reader::get_doc(rbml::Doc::new(data), tag_macro_defs); - reader::tagged_docs(macros, tag_macro_def, |macro_doc| { + for macro_doc in reader::tagged_docs(macros, tag_macro_def) { let name = item_name(intr, macro_doc); let attrs = get_attributes(macro_doc); let body = reader::get_doc(macro_doc, tag_macro_def_body); - f(name, attrs, body.as_str().to_string()) - }); + if !f(name, attrs, body.as_str().to_string()) { + break; + } + } } pub fn get_dylib_dependency_formats(cdata: Cmd) @@ -1487,43 +1403,32 @@ pub fn get_missing_lang_items(cdata: Cmd) -> Vec { let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_lang_items); - let mut result = Vec::new(); - reader::tagged_docs(items, tag_lang_items_missing, |missing_docs| { - let item: lang_items::LangItem = - lang_items::LangItem::from_u32(reader::doc_as_u32(missing_docs)).unwrap(); - result.push(item); - true - }); - return result; + reader::tagged_docs(items, tag_lang_items_missing).map(|missing_docs| { + lang_items::LangItem::from_u32(reader::doc_as_u32(missing_docs)).unwrap() + }).collect() } pub fn get_method_arg_names(cdata: Cmd, id: ast::NodeId) -> Vec { - let mut ret = Vec::new(); let method_doc = lookup_item(id, cdata.data()); match reader::maybe_get_doc(method_doc, tag_method_argument_names) { Some(args_doc) => { - reader::tagged_docs(args_doc, tag_method_argument_name, |name_doc| { - ret.push(name_doc.as_str_slice().to_string()); - true - }); - } - None => {} + reader::tagged_docs(args_doc, tag_method_argument_name).map(|name_doc| { + name_doc.as_str_slice().to_string() + }).collect() + }, + None => vec![], } - return ret; } pub fn get_reachable_extern_fns(cdata: Cmd) -> Vec { - let mut ret = Vec::new(); let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_reachable_extern_fns); - reader::tagged_docs(items, tag_reachable_extern_fn_id, |doc| { - ret.push(ast::DefId { + reader::tagged_docs(items, tag_reachable_extern_fn_id).map(|doc| { + ast::DefId { krate: cdata.cnum, node: reader::doc_as_u32(doc), - }); - true - }); - return ret; + } + }).collect() } pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool { @@ -1559,16 +1464,15 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc, let doc = reader::get_doc(base_doc, tag); let mut types = subst::VecPerParamSpace::empty(); - reader::tagged_docs(doc, tag_type_param_def, |p| { + for p in reader::tagged_docs(doc, tag_type_param_def) { let bd = parse_type_param_def_data( p.data, p.start, cdata.cnum, tcx, |_, did| translate_def_id(cdata, did)); types.push(bd.space, bd); - true - }); + } let mut regions = subst::VecPerParamSpace::empty(); - reader::tagged_docs(doc, tag_region_param_def, |rp_doc| { + for rp_doc in reader::tagged_docs(doc, tag_region_param_def) { let ident_str_doc = reader::get_doc(rp_doc, tag_region_param_def_ident); let name = item_name(&*token::get_ident_interner(), ident_str_doc); @@ -1582,23 +1486,17 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc, let doc = reader::get_doc(rp_doc, tag_region_param_def_index); let index = reader::doc_as_u64(doc) as u32; - let mut bounds = Vec::new(); - reader::tagged_docs(rp_doc, tag_items_data_region, |p| { - bounds.push( - parse_region_data( - p.data, cdata.cnum, p.start, tcx, - |_, did| translate_def_id(cdata, did))); - true - }); + let bounds = reader::tagged_docs(rp_doc, tag_items_data_region).map(|p| { + parse_region_data(p.data, cdata.cnum, p.start, tcx, + |_, did| translate_def_id(cdata, did)) + }).collect(); regions.push(space, ty::RegionParameterDef { name: name, def_id: def_id, space: space, index: index, bounds: bounds }); - - true - }); + } ty::Generics { types: types, regions: regions } } @@ -1612,7 +1510,7 @@ fn doc_predicates<'tcx>(base_doc: rbml::Doc, let doc = reader::get_doc(base_doc, tag); let mut predicates = subst::VecPerParamSpace::empty(); - reader::tagged_docs(doc, tag_predicate, |predicate_doc| { + for predicate_doc in reader::tagged_docs(doc, tag_predicate) { let space_doc = reader::get_doc(predicate_doc, tag_predicate_space); let space = subst::ParamSpace::from_uint(reader::doc_as_u8(space_doc) as usize); @@ -1621,8 +1519,7 @@ fn doc_predicates<'tcx>(base_doc: rbml::Doc, |_, did| translate_def_id(cdata, did)); predicates.push(space, data); - true - }); + } ty::GenericPredicates { predicates: predicates } } @@ -1643,14 +1540,8 @@ pub fn get_imported_filemaps(metadata: &[u8]) -> Vec { let crate_doc = rbml::Doc::new(metadata); let cm_doc = reader::get_doc(crate_doc, tag_codemap); - let mut filemaps = vec![]; - - reader::tagged_docs(cm_doc, tag_codemap_filemap, |filemap_doc| { + reader::tagged_docs(cm_doc, tag_codemap_filemap).map(|filemap_doc| { let mut decoder = reader::Decoder::new(filemap_doc); - let filemap: codemap::FileMap = Decodable::decode(&mut decoder).unwrap(); - filemaps.push(filemap); - true - }); - - return filemaps; + Decodable::decode(&mut decoder).unwrap() + }).collect() } diff --git a/src/test/run-pass/enum-discrim-manual-sizing-2.rs b/src/test/run-pass/enum-discrim-manual-sizing-2.rs new file mode 100644 index 0000000000000..0470a9e19d580 --- /dev/null +++ b/src/test/run-pass/enum-discrim-manual-sizing-2.rs @@ -0,0 +1,107 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that explicit discriminant sizing inhibits the non-nullable pointer +// optimization in enum layout. + +use std::mem::size_of; + +#[repr(i8)] +enum Ei8 { + _None, + _Some(T), +} + +#[repr(u8)] +enum Eu8 { + _None, + _Some(T), +} + +#[repr(i16)] +enum Ei16 { + _None, + _Some(T), +} + +#[repr(u16)] +enum Eu16 { + _None, + _Some(T), +} + +#[repr(i32)] +enum Ei32 { + _None, + _Some(T), +} + +#[repr(u32)] +enum Eu32 { + _None, + _Some(T), +} + +#[repr(i64)] +enum Ei64 { + _None, + _Some(T), +} + +#[repr(u64)] +enum Eu64 { + _None, + _Some(T), +} + +#[repr(isize)] +enum Eint { + _None, + _Some(T), +} + +#[repr(usize)] +enum Euint { + _None, + _Some(T), +} + +#[repr(C)] +enum EC { + _None, + _Some(T), +} + +pub fn main() { + assert_eq!(size_of::>(), 1); + assert_eq!(size_of::>(), 1); + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 4); + assert_eq!(size_of::>(), 4); + assert_eq!(size_of::>(), 8); + assert_eq!(size_of::>(), 8); + assert_eq!(size_of::>(), size_of::()); + assert_eq!(size_of::>(), size_of::()); + + let ptrsize = size_of::<&i32>(); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + + assert!(size_of::>() > ptrsize); +}