diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index a84d43d3deede..7546d7fd4f07a 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -136,7 +136,7 @@ To learn more about a subcommand, run `./x.py -h`"); None => { // No subcommand -- show the general usage and subcommand help println!("{}\n", subcommand_help); - process::exit(0); + process::exit(1); } }; diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 55358f2ffcb73..84a9e56b644c8 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -123,7 +123,6 @@ extern crate build_helper; extern crate serde_derive; #[macro_use] extern crate lazy_static; -extern crate serde; extern crate serde_json; extern crate cmake; extern crate filetime; diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index d798e8de3dffa..e759f1a3e6f85 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -198,7 +198,7 @@ tool!( Linkchecker, "src/tools/linkchecker", "linkchecker", Mode::Libstd; CargoTest, "src/tools/cargotest", "cargotest", Mode::Libstd; Compiletest, "src/tools/compiletest", "compiletest", Mode::Libtest; - BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::Librustc; + BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::Libstd; RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::Libstd; RustInstaller, "src/tools/rust-installer", "rust-installer", Mode::Libstd; ); diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 431bd8ee88f70..a6fe5e0b5c1aa 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -13,6 +13,7 @@ use hir::def_id::{DefId, LOCAL_CRATE}; use syntax_pos::DUMMY_SP; use traits::{self, Normalized, SelectionContext, Obligation, ObligationCause, Reveal}; +use traits::select::IntercrateAmbiguityCause; use ty::{self, Ty, TyCtxt}; use ty::subst::Subst; @@ -21,12 +22,17 @@ use infer::{InferCtxt, InferOk}; #[derive(Copy, Clone)] struct InferIsLocal(bool); +pub struct OverlapResult<'tcx> { + pub impl_header: ty::ImplHeader<'tcx>, + pub intercrate_ambiguity_causes: Vec, +} + /// If there are types that satisfy both impls, returns a suitably-freshened /// `ImplHeader` with those types substituted pub fn overlapping_impls<'cx, 'gcx, 'tcx>(infcx: &InferCtxt<'cx, 'gcx, 'tcx>, impl1_def_id: DefId, impl2_def_id: DefId) - -> Option> + -> Option> { debug!("impl_can_satisfy(\ impl1_def_id={:?}, \ @@ -65,7 +71,7 @@ fn with_fresh_ty_vars<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, ' fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>, a_def_id: DefId, b_def_id: DefId) - -> Option> + -> Option> { debug!("overlap(a_def_id={:?}, b_def_id={:?})", a_def_id, @@ -113,7 +119,10 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>, return None } - Some(selcx.infcx().resolve_type_vars_if_possible(&a_impl_header)) + Some(OverlapResult { + impl_header: selcx.infcx().resolve_type_vars_if_possible(&a_impl_header), + intercrate_ambiguity_causes: selcx.intercrate_ambiguity_causes().to_vec(), + }) } pub fn trait_ref_is_knowable<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, @@ -131,10 +140,7 @@ pub fn trait_ref_is_knowable<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, // if the trait is not marked fundamental, then it's always possible that // an ancestor crate will impl this in the future, if they haven't // already - if - trait_ref.def_id.krate != LOCAL_CRATE && - !tcx.has_attr(trait_ref.def_id, "fundamental") - { + if !trait_ref_is_local_or_fundamental(tcx, trait_ref) { debug!("trait_ref_is_knowable: trait is neither local nor fundamental"); return false; } @@ -148,6 +154,11 @@ pub fn trait_ref_is_knowable<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, orphan_check_trait_ref(tcx, trait_ref, InferIsLocal(true)).is_err() } +pub fn trait_ref_is_local_or_fundamental<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, + trait_ref: &ty::TraitRef<'tcx>) { + trait_ref.def_id.krate == LOCAL_CRATE || tcx.has_attr(trait_ref.def_id, "fundamental") +} + pub enum OrphanCheckErr<'tcx> { NoLocalInputType, UncoveredTy(Ty<'tcx>), diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 228c9761756a8..c706c939060c6 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -28,9 +28,7 @@ use std::rc::Rc; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; -pub use self::coherence::orphan_check; -pub use self::coherence::overlapping_impls; -pub use self::coherence::OrphanCheckErr; +pub use self::coherence::{orphan_check, overlapping_impls, OrphanCheckErr, OverlapResult}; pub use self::fulfill::{FulfillmentContext, RegionObligation}; pub use self::project::MismatchedProjectionTypes; pub use self::project::{normalize, normalize_projection_type, Normalized}; @@ -38,6 +36,7 @@ pub use self::project::{ProjectionCache, ProjectionCacheSnapshot, Reveal}; pub use self::object_safety::ObjectSafetyViolation; pub use self::object_safety::MethodViolationCode; pub use self::select::{EvaluationCache, SelectionContext, SelectionCache}; +pub use self::select::IntercrateAmbiguityCause; pub use self::specialize::{OverlapError, specialization_graph, specializes, translate_substs}; pub use self::specialize::{SpecializesCache, find_associated_item}; pub use self::util::elaborate_predicates; diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 44b8af3c1df98..b6e8912099464 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -31,7 +31,7 @@ use super::{VtableImplData, VtableObjectData, VtableBuiltinData, VtableGenerator use super::util; use dep_graph::{DepNodeIndex, DepKind}; -use hir::def_id::DefId; +use hir::def_id::{DefId, LOCAL_CRATE}; use infer; use infer::{InferCtxt, InferOk, TypeFreshener}; use ty::subst::{Kind, Subst, Substs}; @@ -91,6 +91,45 @@ pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> { intercrate: bool, inferred_obligations: SnapshotVec>, + + intercrate_ambiguity_causes: Vec, +} + +#[derive(Clone)] +pub enum IntercrateAmbiguityCause { + DownstreamCrate { + trait_desc: String, + self_desc: Option, + }, + UpstreamCrateUpdate { + trait_desc: String, + self_desc: Option, + }, +} + +impl IntercrateAmbiguityCause { + /// Emits notes when the overlap is caused by complex intercrate ambiguities. + /// See #23980 for details. + pub fn add_intercrate_ambiguity_hint<'a, 'tcx>(&self, + err: &mut ::errors::DiagnosticBuilder) { + match self { + &IntercrateAmbiguityCause::DownstreamCrate { ref trait_desc, ref self_desc } => { + let self_desc = if let &Some(ref ty) = self_desc { + format!(" for type `{}`", ty) + } else { "".to_string() }; + err.note(&format!("downstream crates may implement trait `{}`{}", + trait_desc, self_desc)); + } + &IntercrateAmbiguityCause::UpstreamCrateUpdate { ref trait_desc, ref self_desc } => { + let self_desc = if let &Some(ref ty) = self_desc { + format!(" for type `{}`", ty) + } else { "".to_string() }; + err.note(&format!("upstream crates may add new impl of trait `{}`{} \ + in future versions", + trait_desc, self_desc)); + } + } + } } // A stack that walks back up the stack frame. @@ -390,6 +429,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { freshener: infcx.freshener(), intercrate: false, inferred_obligations: SnapshotVec::new(), + intercrate_ambiguity_causes: Vec::new(), } } @@ -399,6 +439,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { freshener: infcx.freshener(), intercrate: true, inferred_obligations: SnapshotVec::new(), + intercrate_ambiguity_causes: Vec::new(), } } @@ -414,6 +455,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.infcx } + pub fn intercrate_ambiguity_causes(&self) -> &[IntercrateAmbiguityCause] { + &self.intercrate_ambiguity_causes + } + /// Wraps the inference context's in_snapshot s.t. snapshot handling is only from the selection /// context's self. fn in_snapshot(&mut self, f: F) -> R @@ -767,6 +812,22 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { if unbound_input_types && self.intercrate { debug!("evaluate_stack({:?}) --> unbound argument, intercrate --> ambiguous", stack.fresh_trait_ref); + // Heuristics: show the diagnostics when there are no candidates in crate. + if let Ok(candidate_set) = self.assemble_candidates(stack) { + if !candidate_set.ambiguous && candidate_set.vec.is_empty() { + let trait_ref = stack.obligation.predicate.skip_binder().trait_ref; + let self_ty = trait_ref.self_ty(); + let cause = IntercrateAmbiguityCause::DownstreamCrate { + trait_desc: trait_ref.to_string(), + self_desc: if self_ty.has_concrete_skeleton() { + Some(self_ty.to_string()) + } else { + None + }, + }; + self.intercrate_ambiguity_causes.push(cause); + } + } return EvaluatedToAmbig; } if unbound_input_types && @@ -1021,6 +1082,25 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { if !self.is_knowable(stack) { debug!("coherence stage: not knowable"); + // Heuristics: show the diagnostics when there are no candidates in crate. + let candidate_set = self.assemble_candidates(stack)?; + if !candidate_set.ambiguous && candidate_set.vec.is_empty() { + let trait_ref = stack.obligation.predicate.skip_binder().trait_ref; + let self_ty = trait_ref.self_ty(); + let trait_desc = trait_ref.to_string(); + let self_desc = if self_ty.has_concrete_skeleton() { + Some(self_ty.to_string()) + } else { + None + }; + let cause = if !coherence::trait_ref_is_local_or_fundamental(self.tcx(), + trait_ref) { + IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc } + } else { + IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc } + }; + self.intercrate_ambiguity_causes.push(cause); + } return Ok(None); } diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 7c916e162a4ff..324061f0035b4 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -25,6 +25,7 @@ use hir::def_id::DefId; use infer::{InferCtxt, InferOk}; use ty::subst::{Subst, Substs}; use traits::{self, Reveal, ObligationCause}; +use traits::select::IntercrateAmbiguityCause; use ty::{self, TyCtxt, TypeFoldable}; use syntax_pos::DUMMY_SP; use std::rc::Rc; @@ -36,6 +37,7 @@ pub struct OverlapError { pub with_impl: DefId, pub trait_desc: String, pub self_desc: Option, + pub intercrate_ambiguity_causes: Vec, } /// Given a subst for the requested impl, translate it to a subst @@ -343,6 +345,10 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx } } + for cause in &overlap.intercrate_ambiguity_causes { + cause.add_intercrate_ambiguity_hint(&mut err); + } + err.emit(); } } else { diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index 8b31cb599e45d..779881b619515 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -113,7 +113,7 @@ impl<'a, 'gcx, 'tcx> Children { let overlap = traits::overlapping_impls(&infcx, possible_sibling, impl_def_id); - if let Some(impl_header) = overlap { + if let Some(overlap) = overlap { if tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) { return Ok((false, false)); } @@ -123,7 +123,7 @@ impl<'a, 'gcx, 'tcx> Children { if le == ge { // overlap, but no specialization; error out - let trait_ref = impl_header.trait_ref.unwrap(); + let trait_ref = overlap.impl_header.trait_ref.unwrap(); let self_ty = trait_ref.self_ty(); Err(OverlapError { with_impl: possible_sibling, @@ -135,7 +135,8 @@ impl<'a, 'gcx, 'tcx> Children { Some(self_ty.to_string()) } else { None - } + }, + intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes, }) } else { Ok((le, ge)) diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index cbc4ebe90fd09..e8de6c36ba18d 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -182,7 +182,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { } if !(ty_warned || fn_warned) { - cx.span_lint(UNUSED_RESULTS, s.span, "unused result"); + match t.sty { + // Historically, booleans have not been considered unused + // results. (See Issue #44119.) + ty::TyBool => return, + _ => { + cx.span_lint(UNUSED_RESULTS, s.span, "unused result"); + } + } } fn check_must_use(cx: &LateContext, def_id: DefId, sp: Span, describe_path: &str) -> bool { diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs index 078ae34bc524c..76dcfe36e4fcd 100644 --- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs +++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs @@ -26,7 +26,8 @@ struct InherentOverlapChecker<'a, 'tcx: 'a> { } impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> { - fn check_for_common_items_in_impls(&self, impl1: DefId, impl2: DefId) { + fn check_for_common_items_in_impls(&self, impl1: DefId, impl2: DefId, + overlap: traits::OverlapResult) { #[derive(Copy, Clone, PartialEq)] enum Namespace { Type, @@ -50,16 +51,22 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> { for &item2 in &impl_items2[..] { if (name, namespace) == name_and_namespace(item2) { - struct_span_err!(self.tcx.sess, - self.tcx.span_of_impl(item1).unwrap(), - E0592, - "duplicate definitions with name `{}`", - name) - .span_label(self.tcx.span_of_impl(item1).unwrap(), - format!("duplicate definitions for `{}`", name)) - .span_label(self.tcx.span_of_impl(item2).unwrap(), - format!("other definition for `{}`", name)) - .emit(); + let mut err = struct_span_err!(self.tcx.sess, + self.tcx.span_of_impl(item1).unwrap(), + E0592, + "duplicate definitions with name `{}`", + name); + + err.span_label(self.tcx.span_of_impl(item1).unwrap(), + format!("duplicate definitions for `{}`", name)); + err.span_label(self.tcx.span_of_impl(item2).unwrap(), + format!("other definition for `{}`", name)); + + for cause in &overlap.intercrate_ambiguity_causes { + cause.add_intercrate_ambiguity_hint(&mut err); + } + + err.emit(); } } } @@ -71,8 +78,9 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> { for (i, &impl1_def_id) in impls.iter().enumerate() { for &impl2_def_id in &impls[(i + 1)..] { self.tcx.infer_ctxt().enter(|infcx| { - if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id).is_some() { - self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id) + if let Some(overlap) = + traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id) { + self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap) } }); } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 988890ffedcdd..10a3878073e97 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -228,7 +228,7 @@ impl<'a> fmt::Display for WhereClause<'a> { } if end_newline { - //add a space so stripping
tags and breaking spaces still renders properly + // add a space so stripping
tags and breaking spaces still renders properly if f.alternate() { clause.push(' '); } else { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 5457f69cb6dab..5b8c7503a791d 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1523,8 +1523,7 @@ impl<'a> fmt::Display for Item<'a> { } else { write!(fmt, "Module ")?; }, - clean::FunctionItem(..) | clean::ForeignFunctionItem(..) => - write!(fmt, "Function ")?, + clean::FunctionItem(..) | clean::ForeignFunctionItem(..) => write!(fmt, "Function ")?, clean::TraitItem(..) => write!(fmt, "Trait ")?, clean::StructItem(..) => write!(fmt, "Struct ")?, clean::UnionItem(..) => write!(fmt, "Union ")?, @@ -1532,8 +1531,7 @@ impl<'a> fmt::Display for Item<'a> { clean::TypedefItem(..) => write!(fmt, "Type Definition ")?, clean::MacroItem(..) => write!(fmt, "Macro ")?, clean::PrimitiveItem(..) => write!(fmt, "Primitive Type ")?, - clean::StaticItem(..) | clean::ForeignStaticItem(..) => - write!(fmt, "Static ")?, + clean::StaticItem(..) | clean::ForeignStaticItem(..) => write!(fmt, "Static ")?, clean::ConstantItem(..) => write!(fmt, "Constant ")?, _ => { // We don't generate pages for any other type. diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 4a3286b421ae9..312dfce8d39c2 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -329,6 +329,10 @@ h4 > code, h3 > code, .invisible > code { display: inline-block; } +.in-band > code { + display: inline-block; +} + #main { position: relative; } #main > .since { top: inherit; @@ -447,7 +451,8 @@ a { } .in-band:hover > .anchor { - display: initial; + display: inline-block; + position: absolute; } .anchor { display: none; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 61a8165d26af1..0816a9facc166 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -267,6 +267,9 @@ pub fn main_args(args: &[String]) -> isize { // Check for unstable options. nightly_options::check_nightly_options(&matches, &opts()); + // check for deprecated options + check_deprecated_options(&matches); + if matches.opt_present("h") || matches.opt_present("help") { usage("rustdoc"); return 0; @@ -538,3 +541,16 @@ where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R { }); rx.recv().unwrap() } + +/// Prints deprecation warnings for deprecated options +fn check_deprecated_options(matches: &getopts::Matches) { + if matches.opt_present("input-format") || + matches.opt_present("output-format") || + matches.opt_present("plugin-path") || + matches.opt_present("plugins") || + matches.opt_present("no-defaults") || + matches.opt_present("passes") { + eprintln!("WARNING: this flag is considered deprecated"); + eprintln!("WARNING: please see https://github.com/rust-lang/rust/issues/44136"); + } +} diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 36c06dc0b58d0..9ef19cd64b386 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -705,30 +705,74 @@ impl hash::Hash for SocketAddrV6 { /// /// # Examples /// +/// Creating a [`SocketAddr`] iterator that yields one item: +/// +/// ``` +/// use std::net::{ToSocketAddrs, SocketAddr}; +/// +/// let addr = SocketAddr::from(([127, 0, 0, 1], 443)); +/// let mut addrs_iter = addr.to_socket_addrs().unwrap(); +/// +/// assert_eq!(Some(addr), addrs_iter.next()); +/// assert!(addrs_iter.next().is_none()); +/// ``` +/// +/// Creating a [`SocketAddr`] iterator from a hostname: +/// /// ```no_run -/// use std::net::{SocketAddrV4, TcpStream, UdpSocket, TcpListener, Ipv4Addr}; -/// -/// fn main() { -/// let ip = Ipv4Addr::new(127, 0, 0, 1); -/// let port = 12345; -/// -/// // The following lines are equivalent modulo possible "localhost" name -/// // resolution differences -/// let tcp_s = TcpStream::connect(SocketAddrV4::new(ip, port)); -/// let tcp_s = TcpStream::connect((ip, port)); -/// let tcp_s = TcpStream::connect(("127.0.0.1", port)); -/// let tcp_s = TcpStream::connect(("localhost", port)); -/// let tcp_s = TcpStream::connect("127.0.0.1:12345"); -/// let tcp_s = TcpStream::connect("localhost:12345"); -/// -/// // TcpListener::bind(), UdpSocket::bind() and UdpSocket::send_to() -/// // behave similarly -/// let tcp_l = TcpListener::bind("localhost:12345"); -/// -/// let mut udp_s = UdpSocket::bind(("127.0.0.1", port)).unwrap(); -/// udp_s.send_to(&[7], (ip, 23451)).unwrap(); -/// } +/// use std::net::{SocketAddr, ToSocketAddrs}; +/// +/// // assuming 'localhost' resolves to 127.0.0.1 +/// let mut addrs_iter = "localhost:443".to_socket_addrs().unwrap(); +/// assert_eq!(addrs_iter.next(), Some(SocketAddr::from(([127, 0, 0, 1], 443)))); +/// assert!(addrs_iter.next().is_none()); +/// +/// // assuming 'foo' does not resolve +/// assert!("foo:443".to_socket_addrs().is_err()); /// ``` +/// +/// Creating a [`SocketAddr`] iterator that yields multiple items: +/// +/// ``` +/// use std::net::{SocketAddr, ToSocketAddrs}; +/// +/// let addr1 = SocketAddr::from(([0, 0, 0, 0], 80)); +/// let addr2 = SocketAddr::from(([127, 0, 0, 1], 443)); +/// let addrs = vec![addr1, addr2]; +/// +/// let mut addrs_iter = (&addrs[..]).to_socket_addrs().unwrap(); +/// +/// assert_eq!(Some(addr1), addrs_iter.next()); +/// assert_eq!(Some(addr2), addrs_iter.next()); +/// assert!(addrs_iter.next().is_none()); +/// ``` +/// +/// Attempting to create a [`SocketAddr`] iterator from an improperly formatted +/// socket address `&str` (missing the port): +/// +/// ``` +/// use std::io; +/// use std::net::ToSocketAddrs; +/// +/// let err = "127.0.0.1".to_socket_addrs().unwrap_err(); +/// assert_eq!(err.kind(), io::ErrorKind::InvalidInput); +/// ``` +/// +/// [`TcpStream::connect`] is an example of an function that utilizes +/// `ToSocketsAddr` as a trait bound on its parameter in order to accept +/// different types: +/// +/// ```no_run +/// use std::net::{TcpStream, Ipv4Addr}; +/// +/// let stream = TcpStream::connect(("127.0.0.1", 443)); +/// // or +/// let stream = TcpStream::connect("127.0.0.1.443"); +/// // or +/// let stream = TcpStream::connect((Ipv4Addr::new(127, 0, 0, 1), 443)); +/// ``` +/// +/// [`TcpStream::connect`]: ../../std/net/struct.TcpStream.html#method.connect #[stable(feature = "rust1", since = "1.0.0")] pub trait ToSocketAddrs { /// Returned iterator over socket addresses which this type may correspond diff --git a/src/test/compile-fail/coherence-overlap-downstream-inherent.rs b/src/test/compile-fail/coherence-overlap-downstream-inherent.rs new file mode 100644 index 0000000000000..66068b535556c --- /dev/null +++ b/src/test/compile-fail/coherence-overlap-downstream-inherent.rs @@ -0,0 +1,32 @@ +// Copyright 2017 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. + +// Tests that we consider `T: Sugar + Fruit` to be ambiguous, even +// though no impls are found. + +struct Sweet(X); +pub trait Sugar {} +pub trait Fruit {} +impl Sweet { fn dummy(&self) { } } +//~^ ERROR E0592 +//~| NOTE duplicate definitions for `dummy` +impl Sweet { fn dummy(&self) { } } +//~^ NOTE other definition for `dummy` + +trait Bar {} +struct A(T, X); +impl A where T: Bar { fn f(&self) {} } +//~^ ERROR E0592 +//~| NOTE duplicate definitions for `f` +//~| NOTE downstream crates may implement trait `Bar<_>` for type `i32` +impl A { fn f(&self) {} } +//~^ NOTE other definition for `f` + +fn main() {} diff --git a/src/test/compile-fail/coherence-overlap-downstream.rs b/src/test/compile-fail/coherence-overlap-downstream.rs new file mode 100644 index 0000000000000..1df02737dec58 --- /dev/null +++ b/src/test/compile-fail/coherence-overlap-downstream.rs @@ -0,0 +1,32 @@ +// Copyright 2017 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. + +// Tests that we consider `T: Sugar + Fruit` to be ambiguous, even +// though no impls are found. + +pub trait Sugar {} +pub trait Fruit {} +pub trait Sweet {} +impl Sweet for T { } +//~^ NOTE first implementation here +impl Sweet for T { } +//~^ ERROR E0119 +//~| NOTE conflicting implementation + +pub trait Foo {} +pub trait Bar {} +impl Foo for T where T: Bar {} +//~^ NOTE first implementation here +impl Foo for i32 {} +//~^ ERROR E0119 +//~| NOTE conflicting implementation for `i32` +//~| NOTE downstream crates may implement trait `Bar<_>` for type `i32` + +fn main() { } diff --git a/src/test/compile-fail/coherence-overlap-issue-23516-inherent.rs b/src/test/compile-fail/coherence-overlap-issue-23516-inherent.rs new file mode 100644 index 0000000000000..355af60710a9b --- /dev/null +++ b/src/test/compile-fail/coherence-overlap-issue-23516-inherent.rs @@ -0,0 +1,26 @@ +// Copyright 2015 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. + +// Tests that we consider `Box: !Sugar` to be ambiguous, even +// though we see no impl of `Sugar` for `Box`. Therefore, an overlap +// error is reported for the following pair of impls (#23516). + +pub trait Sugar {} + +struct Cake(X); + +impl Cake { fn dummy(&self) { } } +//~^ ERROR E0592 +//~| NOTE duplicate definitions for `dummy` +//~| NOTE downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>` +impl Cake> { fn dummy(&self) { } } +//~^ NOTE other definition for `dummy` + +fn main() { } diff --git a/src/test/compile-fail/coherence-overlap-issue-23516.rs b/src/test/compile-fail/coherence-overlap-issue-23516.rs index 51d7c3e8b4cb1..ffef5bf10871a 100644 --- a/src/test/compile-fail/coherence-overlap-issue-23516.rs +++ b/src/test/compile-fail/coherence-overlap-issue-23516.rs @@ -15,5 +15,10 @@ pub trait Sugar { fn dummy(&self) { } } pub trait Sweet { fn dummy(&self) { } } impl Sweet for T { } -impl Sweet for Box { } //~ ERROR E0119 +//~^ NOTE first implementation here +impl Sweet for Box { } +//~^ ERROR E0119 +//~| NOTE conflicting implementation for `std::boxed::Box<_>` +//~| NOTE downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>` + fn main() { } diff --git a/src/test/compile-fail/coherence-overlap-upstream-inherent.rs b/src/test/compile-fail/coherence-overlap-upstream-inherent.rs new file mode 100644 index 0000000000000..1d0c63110cecd --- /dev/null +++ b/src/test/compile-fail/coherence-overlap-upstream-inherent.rs @@ -0,0 +1,28 @@ +// Copyright 2015 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. + +// Tests that we consider `i16: Remote` to be ambiguous, even +// though the upstream crate doesn't implement it for now. + +// aux-build:coherence_lib.rs + +extern crate coherence_lib; + +use coherence_lib::Remote; + +struct A(X); +impl A where T: Remote { fn dummy(&self) { } } +//~^ ERROR E0592 +//~| NOTE duplicate definitions for `dummy` +//~| NOTE upstream crates may add new impl of trait `coherence_lib::Remote` for type `i16` +impl A { fn dummy(&self) { } } +//~^ NOTE other definition for `dummy` + +fn main() {} diff --git a/src/test/compile-fail/coherence-overlap-upstream.rs b/src/test/compile-fail/coherence-overlap-upstream.rs new file mode 100644 index 0000000000000..e978143a067c5 --- /dev/null +++ b/src/test/compile-fail/coherence-overlap-upstream.rs @@ -0,0 +1,28 @@ +// Copyright 2015 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. + +// Tests that we consider `i16: Remote` to be ambiguous, even +// though the upstream crate doesn't implement it for now. + +// aux-build:coherence_lib.rs + +extern crate coherence_lib; + +use coherence_lib::Remote; + +trait Foo {} +impl Foo for T where T: Remote {} +//~^ NOTE first implementation here +impl Foo for i16 {} +//~^ ERROR E0119 +//~| NOTE conflicting implementation for `i16` +//~| NOTE upstream crates may add new impl of trait `coherence_lib::Remote` for type `i16` + +fn main() {} diff --git a/src/test/compile-fail/unused-result.rs b/src/test/compile-fail/unused-result.rs index 0c6c7fc5a0d75..c0417e6e997ca 100644 --- a/src/test/compile-fail/unused-result.rs +++ b/src/test/compile-fail/unused-result.rs @@ -42,6 +42,9 @@ fn main() { foo::(); //~ ERROR: unused `MustUse` which must be used foo::(); //~ ERROR: unused `MustUseMsg` which must be used: some message + // as an exceptional case, booleans are not considered unused + foo::(); + let _ = foo::(); let _ = foo::(); let _ = foo::(); diff --git a/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr b/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr index de8a24cf33f44..eaf42cde22f76 100644 --- a/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr +++ b/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr @@ -24,6 +24,8 @@ error[E0592]: duplicate definitions with name `baz` ... 43 | fn baz(&self) {} | ---------------- other definition for `baz` + | + = note: upstream crates may add new impl of trait `std::marker::Copy` for type `std::vec::Vec<_>` in future versions error: aborting due to 3 previous errors diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 0d6b350a1d431..cee7e52c7f3c6 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -83,117 +83,117 @@ impl fmt::Display for Mode { #[derive(Clone)] pub struct Config { - // The library paths required for running the compiler + /// The library paths required for running the compiler pub compile_lib_path: PathBuf, - // The library paths required for running compiled programs + /// The library paths required for running compiled programs pub run_lib_path: PathBuf, - // The rustc executable + /// The rustc executable pub rustc_path: PathBuf, - // The rustdoc executable + /// The rustdoc executable pub rustdoc_path: Option, - // The python executable to use for LLDB + /// The python executable to use for LLDB pub lldb_python: String, - // The python executable to use for htmldocck + /// The python executable to use for htmldocck pub docck_python: String, - // The llvm FileCheck binary path + /// The llvm FileCheck binary path pub llvm_filecheck: Option, - // The valgrind path + /// The valgrind path pub valgrind_path: Option, - // Whether to fail if we can't run run-pass-valgrind tests under valgrind - // (or, alternatively, to silently run them like regular run-pass tests). + /// Whether to fail if we can't run run-pass-valgrind tests under valgrind + /// (or, alternatively, to silently run them like regular run-pass tests). pub force_valgrind: bool, - // The directory containing the tests to run + /// The directory containing the tests to run pub src_base: PathBuf, - // The directory where programs should be built + /// The directory where programs should be built pub build_base: PathBuf, - // The name of the stage being built (stage1, etc) + /// The name of the stage being built (stage1, etc) pub stage_id: String, - // The test mode, compile-fail, run-fail, run-pass + /// The test mode, compile-fail, run-fail, run-pass pub mode: Mode, - // Run ignored tests + /// Run ignored tests pub run_ignored: bool, - // Only run tests that match this filter + /// Only run tests that match this filter pub filter: Option, - // Exactly match the filter, rather than a substring + /// Exactly match the filter, rather than a substring pub filter_exact: bool, - // Write out a parseable log of tests that were run + /// Write out a parseable log of tests that were run pub logfile: Option, - // A command line to prefix program execution with, - // for running under valgrind + /// A command line to prefix program execution with, + /// for running under valgrind pub runtool: Option, - // Flags to pass to the compiler when building for the host + /// Flags to pass to the compiler when building for the host pub host_rustcflags: Option, - // Flags to pass to the compiler when building for the target + /// Flags to pass to the compiler when building for the target pub target_rustcflags: Option, - // Target system to be tested + /// Target system to be tested pub target: String, - // Host triple for the compiler being invoked + /// Host triple for the compiler being invoked pub host: String, - // Path to / name of the GDB executable + /// Path to / name of the GDB executable pub gdb: Option, - // Version of GDB, encoded as ((major * 1000) + minor) * 1000 + patch + /// Version of GDB, encoded as ((major * 1000) + minor) * 1000 + patch pub gdb_version: Option, - // Whether GDB has native rust support + /// Whether GDB has native rust support pub gdb_native_rust: bool, - // Version of LLDB + /// Version of LLDB pub lldb_version: Option, - // Version of LLVM + /// Version of LLVM pub llvm_version: Option, - // Is LLVM a system LLVM + /// Is LLVM a system LLVM pub system_llvm: bool, - // Path to the android tools + /// Path to the android tools pub android_cross_path: PathBuf, - // Extra parameter to run adb on arm-linux-androideabi + /// Extra parameter to run adb on arm-linux-androideabi pub adb_path: String, - // Extra parameter to run test suite on arm-linux-androideabi + /// Extra parameter to run test suite on arm-linux-androideabi pub adb_test_dir: String, - // status whether android device available or not + /// status whether android device available or not pub adb_device_status: bool, - // the path containing LLDB's Python module + /// the path containing LLDB's Python module pub lldb_python_dir: Option, - // Explain what's going on + /// Explain what's going on pub verbose: bool, - // Print one character per test instead of one line + /// Print one character per test instead of one line pub quiet: bool, - // Whether to use colors in test. + /// Whether to use colors in test. pub color: ColorConfig, - // where to find the remote test client process, if we're using it + /// where to find the remote test client process, if we're using it pub remote_test_client: Option, // Configuration for various run-make tests frobbing things like C compilers