diff --git a/src/doc/book/testing.md b/src/doc/book/testing.md index 0f48f579864..14a05102b9a 100644 --- a/src/doc/book/testing.md +++ b/src/doc/book/testing.md @@ -586,3 +586,45 @@ you add more examples. We haven’t covered all of the details with writing documentation tests. For more, please see the [Documentation chapter](documentation.html). + +# Testing and concurrency + +One thing that is important to note when writing tests are run concurrently +using threads. For this reason you should take care that your tests are written +in such a way as to not depend on each-other, or on any shared state. "Shared +state" can also include the environment, such as the current working directory, +or environment variables. + +If this is an issue it is possible to control this concurrency, either by +setting the environment variable `RUST_TEST_THREADS`, or by passing the argument +`--test-threads` to the tests: + +```bash +$ RUST_TEST_THREADS=1 cargo test # Run tests with no concurrency +... +$ cargo test -- --test-threads=1 # Same as above +... +``` + +# Test output + +By default Rust's test library captures and discards output to standard +out/error, e.g. output from `println!()`. This too can be controlled using the +environment or a switch: + + +```bash +$ RUST_TEST_NOCAPTURE=1 cargo test # Preserve stdout/stderr +... +$ cargo test -- --nocapture # Same as above +... +``` + +However a better method avoiding capture is to use logging rather than raw +output. Rust has a [standard logging API][log], which provides a frontend to +multiple logging implementations. This can be used in conjunction with the +default [env_logger] to output any debugging information in a manner that can be +controlled at runtime. + +[log]: https://crates.io/crates/log +[env_logger]: https://crates.io/crates/env_logger diff --git a/src/librustc_const_eval/diagnostics.rs b/src/librustc_const_eval/diagnostics.rs index db72057636a..83b0d9dec6d 100644 --- a/src/librustc_const_eval/diagnostics.rs +++ b/src/librustc_const_eval/diagnostics.rs @@ -40,7 +40,9 @@ arms. "##, -/*E0002: r##" +E0002: r##" +## Note: this error code is no longer emitted by the compiler. + This error indicates that an empty match expression is invalid because the type it is matching on is non-empty (there exist values of this type). In safe code it is impossible to create an instance of an empty type, so empty match @@ -68,10 +70,11 @@ fn foo(x: Option) { } } ``` -"##,*/ +"##, +E0003: r##" +## Note: this error code is no longer emitted by the compiler. -/*E0003: r##" Not-a-Number (NaN) values cannot be compared for equality and hence can never match the input to a match expression. So, the following will not compile: @@ -98,7 +101,6 @@ fn foo(x: Option) { } ``` "##, -*/ E0004: r##" This error indicates that the compiler cannot guarantee a matching pattern for diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 0cb8cf2a588..d15795730a8 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -308,7 +308,7 @@ fn suggest_traits_to_import(&self, let limit = if candidates.len() == 5 { 5 } else { 4 }; for (i, trait_did) in candidates.iter().take(limit).enumerate() { - err.help(&format!("candidate #{}: `use {}`", + err.help(&format!("candidate #{}: `use {};`", i + 1, self.tcx.item_path_str(*trait_did))); } diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index b5aba512a66..df3a79f09bd 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -14,7 +14,7 @@ use hir::def_id::DefId; use rustc::traits::{self, Reveal}; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::{self, TyCtxt, TypeFoldable}; use syntax::ast; use rustc::dep_graph::DepNode; use rustc::hir; @@ -134,6 +134,12 @@ fn visit_item(&mut self, item: &'v hir::Item) { let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); let trait_def_id = trait_ref.def_id; + if trait_ref.references_error() { + debug!("coherence: skipping impl {:?} with error {:?}", + impl_def_id, trait_ref); + return + } + let _task = self.tcx.dep_graph.in_task(DepNode::CoherenceOverlapCheck(trait_def_id)); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 2761ab76607..7395cc42ac5 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -874,12 +874,12 @@ fn extern_location(e: &clean::ExternalCrate, dst: &Path) -> ExternalLocation { impl<'a> DocFolder for SourceCollector<'a> { fn fold_item(&mut self, item: clean::Item) -> Option { // If we're including source files, and we haven't seen this file yet, - // then we need to render it out to the filesystem + // then we need to render it out to the filesystem. if self.scx.include_sources // skip all invalid spans && item.source.filename != "" - // macros from other libraries get special filenames which we can - // safely ignore + // Macros from other libraries get special filenames which we can + // safely ignore. && !(item.source.filename.starts_with("<") && item.source.filename.ends_with("macros>")) { @@ -974,13 +974,13 @@ fn fold_item(&mut self, item: clean::Item) -> Option { }; // Register any generics to their corresponding string. This is used - // when pretty-printing types + // when pretty-printing types. if let Some(generics) = item.inner.generics() { self.generics(generics); } - // Propagate a trait methods' documentation to all implementors of the - // trait + // Propagate a trait method's documentation to all implementors of the + // trait. if let clean::TraitItem(ref t) = item.inner { self.traits.entry(item.def_id).or_insert_with(|| t.clone()); } @@ -996,7 +996,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option { } } - // Index this method for searching later on + // Index this method for searching later on. if let Some(ref s) = item.name { let (parent, is_inherent_impl_item) = match item.inner { clean::StrippedItem(..) => ((None, None), false), @@ -1097,8 +1097,8 @@ fn fold_item(&mut self, item: clean::Item) -> Option { (self.stack.clone(), item.type_())); } } - // link variants to their parent enum because pages aren't emitted - // for each variant + // Link variants to their parent enum because pages aren't emitted + // for each variant. clean::VariantItem(..) if !self.stripped_mod => { let mut stack = self.stack.clone(); stack.pop(); @@ -1144,8 +1144,8 @@ fn fold_item(&mut self, item: clean::Item) -> Option { _ => false }; - // Once we've recursively found all the generics, then hoard off all the - // implementations elsewhere + // Once we've recursively found all the generics, hoard off all the + // implementations elsewhere. let ret = self.fold_item_recur(item).and_then(|item| { if let clean::Item { inner: clean::ImplItem(_), .. } = item { // Figure out the id of this impl. This may map to a @@ -1206,7 +1206,7 @@ fn root_path(&self) -> String { } /// Recurse in the directory structure and change the "root path" to make - /// sure it always points to the top (relatively) + /// sure it always points to the top (relatively). fn recurse(&mut self, s: String, f: F) -> T where F: FnOnce(&mut Context) -> T, { @@ -1237,11 +1237,11 @@ fn recurse(&mut self, s: String, f: F) -> T where fn krate(self, mut krate: clean::Crate) -> Result<(), Error> { let mut item = match krate.module.take() { Some(i) => i, - None => return Ok(()) + None => return Ok(()), }; item.name = Some(krate.name); - // render the crate documentation + // Render the crate documentation let mut work = vec![(self, item)]; while let Some((mut cx, item)) = work.pop() { @@ -2987,7 +2987,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let it = self.item; let parentlen = cx.current.len() - if it.is_mod() {1} else {0}; - // the sidebar is designed to display sibling functions, modules and + // The sidebar is designed to display sibling functions, modules and // other miscellaneous information. since there are lots of sibling // items (and that causes quadratic growth in large modules), // we refactor common parts into a shared JavaScript file per module. @@ -3006,7 +3006,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { } write!(fmt, "

")?; - // sidebar refers to the enclosing module, not this module + // Sidebar refers to the enclosing module, not this module. let relpath = if it.is_mod() { "../" } else { "" }; write!(fmt, "", diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 49080680fac..7b7be6e2eee 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -154,6 +154,14 @@ impl Ipv4Addr { /// Creates a new IPv4 address from four eight-bit octets. /// /// The result will represent the IP address `a`.`b`.`c`.`d`. + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// let addr = Ipv4Addr::new(127, 0, 0, 1); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { Ipv4Addr { @@ -167,6 +175,15 @@ pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { } /// Returns the four eight-bit integers that make up this address. + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// let addr = Ipv4Addr::new(127, 0, 0, 1); + /// assert_eq!(addr.octets(), [127, 0, 0, 1]); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn octets(&self) -> [u8; 4] { let bits = ntoh(self.inner.s_addr); @@ -176,8 +193,18 @@ pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { /// Returns true for the special 'unspecified' address (0.0.0.0). /// /// This property is defined in _UNIX Network Programming, Second Edition_, - /// W. Richard Stevens, p. 891; see also [ip7] - /// [ip7][http://man7.org/linux/man-pages/man7/ip.7.html] + /// W. Richard Stevens, p. 891; see also [ip7]. + /// + /// [ip7]: http://man7.org/linux/man-pages/man7/ip.7.html + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// assert_eq!(Ipv4Addr::new(0, 0, 0, 0).is_unspecified(), true); + /// assert_eq!(Ipv4Addr::new(45, 22, 13, 197).is_unspecified(), false); + /// ``` #[stable(feature = "ip_shared", since = "1.12.0")] pub fn is_unspecified(&self) -> bool { self.inner.s_addr == 0 @@ -186,7 +213,17 @@ pub fn is_unspecified(&self) -> bool { /// Returns true if this is a loopback address (127.0.0.0/8). /// /// This property is defined by [RFC 1122]. + /// /// [RFC 1122]: https://tools.ietf.org/html/rfc1122 + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// assert_eq!(Ipv4Addr::new(127, 0, 0, 1).is_loopback(), true); + /// assert_eq!(Ipv4Addr::new(45, 22, 13, 197).is_loopback(), false); + /// ``` #[stable(since = "1.7.0", feature = "ip_17")] pub fn is_loopback(&self) -> bool { self.octets()[0] == 127 @@ -195,11 +232,26 @@ pub fn is_loopback(&self) -> bool { /// Returns true if this is a private address. /// /// The private address ranges are defined in [RFC 1918] and include: - /// [RFC 1918]: https://tools.ietf.org/html/rfc1918 /// /// - 10.0.0.0/8 /// - 172.16.0.0/12 /// - 192.168.0.0/16 + /// + /// [RFC 1918]: https://tools.ietf.org/html/rfc1918 + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// assert_eq!(Ipv4Addr::new(10, 0, 0, 1).is_private(), true); + /// assert_eq!(Ipv4Addr::new(10, 10, 10, 10).is_private(), true); + /// assert_eq!(Ipv4Addr::new(172, 16, 10, 10).is_private(), true); + /// assert_eq!(Ipv4Addr::new(172, 29, 45, 14).is_private(), true); + /// assert_eq!(Ipv4Addr::new(172, 32, 0, 2).is_private(), false); + /// assert_eq!(Ipv4Addr::new(192, 168, 0, 2).is_private(), true); + /// assert_eq!(Ipv4Addr::new(192, 169, 0, 2).is_private(), false); + /// ``` #[stable(since = "1.7.0", feature = "ip_17")] pub fn is_private(&self) -> bool { match (self.octets()[0], self.octets()[1]) { @@ -213,7 +265,18 @@ pub fn is_private(&self) -> bool { /// Returns true if the address is link-local (169.254.0.0/16). /// /// This property is defined by [RFC 3927]. + /// /// [RFC 3927]: https://tools.ietf.org/html/rfc3927 + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// assert_eq!(Ipv4Addr::new(169, 254, 0, 0).is_link_local(), true); + /// assert_eq!(Ipv4Addr::new(169, 254, 10, 65).is_link_local(), true); + /// assert_eq!(Ipv4Addr::new(16, 89, 10, 65).is_link_local(), false); + /// ``` #[stable(since = "1.7.0", feature = "ip_17")] pub fn is_link_local(&self) -> bool { self.octets()[0] == 169 && self.octets()[1] == 254 @@ -221,7 +284,6 @@ pub fn is_link_local(&self) -> bool { /// Returns true if the address appears to be globally routable. /// See [iana-ipv4-special-registry][ipv4-sr]. - /// [ipv4-sr]: http://goo.gl/RaZ7lg /// /// The following return false: /// @@ -231,6 +293,24 @@ pub fn is_link_local(&self) -> bool { /// - the broadcast address (255.255.255.255/32) /// - test addresses used for documentation (192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24) /// - the unspecified address (0.0.0.0) + /// + /// [ipv4-sr]: http://goo.gl/RaZ7lg + /// + /// # Examples + /// + /// ``` + /// #![feature(ip)] + /// + /// use std::net::Ipv4Addr; + /// + /// fn main() { + /// assert_eq!(Ipv4Addr::new(10, 254, 0, 0).is_global(), false); + /// assert_eq!(Ipv4Addr::new(192, 168, 10, 65).is_global(), false); + /// assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_global(), false); + /// assert_eq!(Ipv4Addr::new(0, 0, 0, 0).is_global(), false); + /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true); + /// } + /// ``` pub fn is_global(&self) -> bool { !self.is_private() && !self.is_loopback() && !self.is_link_local() && !self.is_broadcast() && !self.is_documentation() && !self.is_unspecified() @@ -240,7 +320,18 @@ pub fn is_global(&self) -> bool { /// /// Multicast addresses have a most significant octet between 224 and 239, /// and is defined by [RFC 5771]. + /// /// [RFC 5771]: https://tools.ietf.org/html/rfc5771 + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// assert_eq!(Ipv4Addr::new(224, 254, 0, 0).is_multicast(), true); + /// assert_eq!(Ipv4Addr::new(236, 168, 10, 65).is_multicast(), true); + /// assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_multicast(), false); + /// ``` #[stable(since = "1.7.0", feature = "ip_17")] pub fn is_multicast(&self) -> bool { self.octets()[0] >= 224 && self.octets()[0] <= 239 @@ -249,7 +340,17 @@ pub fn is_multicast(&self) -> bool { /// Returns true if this is a broadcast address (255.255.255.255). /// /// A broadcast address has all octets set to 255 as defined in [RFC 919]. + /// /// [RFC 919]: https://tools.ietf.org/html/rfc919 + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_broadcast(), true); + /// assert_eq!(Ipv4Addr::new(236, 168, 10, 65).is_broadcast(), false); + /// ``` #[stable(since = "1.7.0", feature = "ip_17")] pub fn is_broadcast(&self) -> bool { self.octets()[0] == 255 && self.octets()[1] == 255 && @@ -259,11 +360,23 @@ pub fn is_broadcast(&self) -> bool { /// Returns true if this address is in a range designated for documentation. /// /// This is defined in [RFC 5737]: - /// [RFC 5737]: https://tools.ietf.org/html/rfc5737 /// /// - 192.0.2.0/24 (TEST-NET-1) /// - 198.51.100.0/24 (TEST-NET-2) /// - 203.0.113.0/24 (TEST-NET-3) + /// + /// [RFC 5737]: https://tools.ietf.org/html/rfc5737 + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).is_documentation(), true); + /// assert_eq!(Ipv4Addr::new(198, 51, 100, 65).is_documentation(), true); + /// assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_documentation(), true); + /// assert_eq!(Ipv4Addr::new(193, 34, 17, 19).is_documentation(), false); + /// ``` #[stable(since = "1.7.0", feature = "ip_17")] pub fn is_documentation(&self) -> bool { match(self.octets()[0], self.octets()[1], self.octets()[2], self.octets()[3]) { @@ -277,6 +390,15 @@ pub fn is_documentation(&self) -> bool { /// Converts this address to an IPv4-compatible IPv6 address. /// /// a.b.c.d becomes ::a.b.c.d + /// + /// # Examples + /// + /// ``` + /// use std::net::{Ipv4Addr, Ipv6Addr}; + /// + /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).to_ipv6_compatible(), + /// Ipv6Addr::new(0, 0, 0, 0, 0, 0, 49152, 767)); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn to_ipv6_compatible(&self) -> Ipv6Addr { Ipv6Addr::new(0, 0, 0, 0, 0, 0, @@ -287,6 +409,15 @@ pub fn to_ipv6_compatible(&self) -> Ipv6Addr { /// Converts this address to an IPv4-mapped IPv6 address. /// /// a.b.c.d becomes ::ffff:a.b.c.d + /// + /// # Examples + /// + /// ``` + /// use std::net::{Ipv4Addr, Ipv6Addr}; + /// + /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).to_ipv6_mapped(), + /// Ipv6Addr::new(0, 0, 0, 0, 0, 65535, 49152, 767)); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn to_ipv6_mapped(&self) -> Ipv6Addr { Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, @@ -425,6 +556,7 @@ pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, /// Returns true for the special 'unspecified' address (::). /// /// This property is defined in [RFC 4291]. + /// /// [RFC 4291]: https://tools.ietf.org/html/rfc4291 #[stable(since = "1.7.0", feature = "ip_17")] pub fn is_unspecified(&self) -> bool { @@ -434,6 +566,7 @@ pub fn is_unspecified(&self) -> bool { /// Returns true if this is a loopback address (::1). /// /// This property is defined in [RFC 4291]. + /// /// [RFC 4291]: https://tools.ietf.org/html/rfc4291 #[stable(since = "1.7.0", feature = "ip_17")] pub fn is_loopback(&self) -> bool { @@ -458,6 +591,7 @@ pub fn is_global(&self) -> bool { /// Returns true if this is a unique local address (fc00::/7). /// /// This property is defined in [RFC 4193]. + /// /// [RFC 4193]: https://tools.ietf.org/html/rfc4193 pub fn is_unique_local(&self) -> bool { (self.segments()[0] & 0xfe00) == 0xfc00 @@ -466,6 +600,7 @@ pub fn is_unique_local(&self) -> bool { /// Returns true if the address is unicast and link-local (fe80::/10). /// /// This property is defined in [RFC 4291]. + /// /// [RFC 4291]: https://tools.ietf.org/html/rfc4291 pub fn is_unicast_link_local(&self) -> bool { (self.segments()[0] & 0xffc0) == 0xfe80 @@ -481,6 +616,7 @@ pub fn is_unicast_site_local(&self) -> bool { /// (2001:db8::/32). /// /// This property is defined in [RFC 3849]. + /// /// [RFC 3849]: https://tools.ietf.org/html/rfc3849 pub fn is_documentation(&self) -> bool { (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8) @@ -524,6 +660,7 @@ pub fn multicast_scope(&self) -> Option { /// Returns true if this is a multicast address (ff00::/8). /// /// This property is defined by [RFC 4291]. + /// /// [RFC 4291]: https://tools.ietf.org/html/rfc4291 #[stable(since = "1.7.0", feature = "ip_17")] pub fn is_multicast(&self) -> bool { diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 0e7c5b06713..159aa997b27 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -67,11 +67,12 @@ /// An infinite iterator over the connections from a `TcpListener`. /// -/// This iterator will infinitely yield `Some` of the accepted connections. It +/// This iterator will infinitely yield [`Some`] of the accepted connections. It /// is equivalent to calling `accept` in a loop. /// /// This `struct` is created by the [`incoming`] method on [`TcpListener`]. /// +/// [`Some`]: ../../std/option/enum.Option.html#variant.Some /// [`incoming`]: struct.TcpListener.html#method.incoming /// [`TcpListener`]: struct.TcpListener.html #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/test/compile-fail/coherence-error-suppression.rs b/src/test/compile-fail/coherence-error-suppression.rs new file mode 100644 index 00000000000..b33f27fbc8a --- /dev/null +++ b/src/test/compile-fail/coherence-error-suppression.rs @@ -0,0 +1,25 @@ +// Copyright 2016 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. + +// check that error types in coherence do not cause error cascades. + +trait Foo {} + +impl Foo for i8 {} +impl Foo for i16 {} +impl Foo for i32 {} +impl Foo for i64 {} +impl Foo for DoesNotExist {} //~ ERROR `DoesNotExist` is undefined +impl Foo for u8 {} +impl Foo for u16 {} +impl Foo for u32 {} +impl Foo for u64 {} + +fn main() {} diff --git a/src/test/compile-fail/no-method-suggested-traits.rs b/src/test/compile-fail/no-method-suggested-traits.rs index 9ccc7cc75ad..ea8796d38f9 100644 --- a/src/test/compile-fail/no-method-suggested-traits.rs +++ b/src/test/compile-fail/no-method-suggested-traits.rs @@ -34,31 +34,31 @@ fn main() { 1u32.method(); //~^ HELP following traits are implemented but not in scope, perhaps add a `use` for one of them //~^^ ERROR no method named - //~^^^ HELP `use foo::Bar` - //~^^^^ HELP `use no_method_suggested_traits::foo::PubPub` + //~^^^ HELP `use foo::Bar;` + //~^^^^ HELP `use no_method_suggested_traits::foo::PubPub;` std::rc::Rc::new(&mut Box::new(&1u32)).method(); //~^ HELP following traits are implemented but not in scope, perhaps add a `use` for one of them //~^^ ERROR no method named - //~^^^ HELP `use foo::Bar` - //~^^^^ HELP `use no_method_suggested_traits::foo::PubPub` + //~^^^ HELP `use foo::Bar;` + //~^^^^ HELP `use no_method_suggested_traits::foo::PubPub;` 'a'.method(); //~^ ERROR no method named //~^^ HELP the following trait is implemented but not in scope, perhaps add a `use` for it: - //~^^^ HELP `use foo::Bar` + //~^^^ HELP `use foo::Bar;` std::rc::Rc::new(&mut Box::new(&'a')).method(); //~^ ERROR no method named //~^^ HELP the following trait is implemented but not in scope, perhaps add a `use` for it: - //~^^^ HELP `use foo::Bar` + //~^^^ HELP `use foo::Bar;` 1i32.method(); //~^ ERROR no method named //~^^ HELP the following trait is implemented but not in scope, perhaps add a `use` for it: - //~^^^ HELP `use no_method_suggested_traits::foo::PubPub` + //~^^^ HELP `use no_method_suggested_traits::foo::PubPub;` std::rc::Rc::new(&mut Box::new(&1i32)).method(); //~^ ERROR no method named //~^^ HELP the following trait is implemented but not in scope, perhaps add a `use` for it: - //~^^^ HELP `use no_method_suggested_traits::foo::PubPub` + //~^^^ HELP `use no_method_suggested_traits::foo::PubPub;` Foo.method(); //~^ ERROR no method named diff --git a/src/test/incremental/hashes/type_defs.rs b/src/test/incremental/hashes/type_defs.rs new file mode 100644 index 00000000000..35fb583cd4e --- /dev/null +++ b/src/test/incremental/hashes/type_defs.rs @@ -0,0 +1,249 @@ +// Copyright 2016 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. + + +// This test case tests the incremental compilation hash (ICH) implementation +// for `type` definitions. + +// The general pattern followed here is: Change one thing between rev1 and rev2 +// and make sure that the hash has changed, then change nothing between rev2 and +// rev3 and make sure that the hash has not changed. + +// We also test the ICH for `type` definitions exported in metadata. Same as +// above, we want to make sure that the change between rev1 and rev2 also +// results in a change of the ICH for the enum's metadata, and that it stays +// the same between rev2 and rev3. + +// must-compile-successfully +// revisions: cfail1 cfail2 cfail3 +// compile-flags: -Z query-dep-graph + +#![allow(warnings)] +#![feature(rustc_attrs)] +#![crate_type="rlib"] + + +// Change type (primitive) ----------------------------------------------------- +#[cfg(cfail1)] +type ChangePrimitiveType = i32; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail3")] +type ChangePrimitiveType = i64; + + + +// Change mutability ----------------------------------------------------------- +#[cfg(cfail1)] +type ChangeMutability = &'static i32; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail3")] +type ChangeMutability = &'static mut i32; + + + +// Change mutability ----------------------------------------------------------- +#[cfg(cfail1)] +type ChangeLifetime<'a> = (&'static i32, &'a i32); + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail3")] +type ChangeLifetime<'a> = (&'a i32, &'a i32); + + + +// Change type (struct) ----------------------------------------------------------- +struct Struct1; +struct Struct2; + +#[cfg(cfail1)] +type ChangeTypeStruct = Struct1; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail3")] +type ChangeTypeStruct = Struct2; + + + +// Change type (tuple) --------------------------------------------------------- +#[cfg(cfail1)] +type ChangeTypeTuple = (u32, u64); + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail3")] +type ChangeTypeTuple = (u32, i64); + + + +// Change type (enum) ---------------------------------------------------------- +enum Enum1 { + Var1, + Var2, +} +enum Enum2 { + Var1, + Var2, +} + +#[cfg(cfail1)] +type ChangeTypeEnum = Enum1; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail3")] +type ChangeTypeEnum = Enum2; + + + +// Add tuple field ------------------------------------------------------------- +#[cfg(cfail1)] +type AddTupleField = (i32, i64); + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail3")] +type AddTupleField = (i32, i64, i16); + + + +// Change nested tuple field --------------------------------------------------- +#[cfg(cfail1)] +type ChangeNestedTupleField = (i32, (i64, i16)); + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail3")] +type ChangeNestedTupleField = (i32, (i64, i8)); + + + +// Add type param -------------------------------------------------------------- +#[cfg(cfail1)] +type AddTypeParam = (T1, T1); + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail3")] +type AddTypeParam = (T1, T2); + + + +// Add type param bound -------------------------------------------------------- +#[cfg(cfail1)] +type AddTypeParamBound = (T1, u32); + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail3")] +type AddTypeParamBound = (T1, u32); + + + +// Add type param bound in where clause ---------------------------------------- +#[cfg(cfail1)] +type AddTypeParamBoundWhereClause where T1: Clone = (T1, u32); + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail3")] +type AddTypeParamBoundWhereClause where T1: Clone+Copy = (T1, u32); + + + +// Add lifetime param ---------------------------------------------------------- +#[cfg(cfail1)] +type AddLifetimeParam<'a> = (&'a u32, &'a u32); + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail3")] +type AddLifetimeParam<'a, 'b> = (&'a u32, &'b u32); + + + +// Add lifetime param bound ---------------------------------------------------- +#[cfg(cfail1)] +type AddLifetimeParamBound<'a, 'b> = (&'a u32, &'b u32); + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail3")] +type AddLifetimeParamBound<'a, 'b: 'a> = (&'a u32, &'b u32); + + + +// Add lifetime param bound in where clause ------------------------------------ +#[cfg(cfail1)] +type AddLifetimeParamBoundWhereClause<'a, 'b, 'c> +where 'b: 'a + = (&'a u32, &'b u32, &'c u32); + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail3")] +type AddLifetimeParamBoundWhereClause<'a, 'b, 'c> +where 'b: 'a, + 'c: 'a + = (&'a u32, &'b u32, &'c u32); + + + +// Change Trait Bound Indirectly ----------------------------------------------- +trait ReferencedTrait1 {} +trait ReferencedTrait2 {} + +mod change_trait_bound_indirectly { + #[cfg(cfail1)] + use super::ReferencedTrait1 as Trait; + #[cfg(not(cfail1))] + use super::ReferencedTrait2 as Trait; + + #[rustc_dirty(label="Hir", cfg="cfail2")] + #[rustc_clean(label="Hir", cfg="cfail3")] + #[rustc_metadata_dirty(cfg="cfail2")] + #[rustc_metadata_clean(cfg="cfail3")] + type ChangeTraitBoundIndirectly = (T, u32); +} + + + +// Change Trait Bound Indirectly In Where Clause ------------------------------- +mod change_trait_bound_indirectly_in_where_clause { + #[cfg(cfail1)] + use super::ReferencedTrait1 as Trait; + #[cfg(not(cfail1))] + use super::ReferencedTrait2 as Trait; + + #[rustc_dirty(label="Hir", cfg="cfail2")] + #[rustc_clean(label="Hir", cfg="cfail3")] + #[rustc_metadata_dirty(cfg="cfail2")] + #[rustc_metadata_clean(cfg="cfail3")] + type ChangeTraitBoundIndirectly where T : Trait = (T, u32); +} diff --git a/src/test/run-pass/path-lookahead.rs b/src/test/run-pass/path-lookahead.rs new file mode 100644 index 00000000000..017259af190 --- /dev/null +++ b/src/test/run-pass/path-lookahead.rs @@ -0,0 +1,23 @@ +// Copyright 2016 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. + +// Parser test for #37765 + +fn with_parens(arg: T) -> String { //~WARN dead_code + return (::to_string(&arg)); //~WARN unused_parens +} + +fn no_parens(arg: T) -> String { //~WARN dead_code + return ::to_string(&arg); +} + +fn main() { + +}