diff --git a/src/doc/book/lifetimes.md b/src/doc/book/lifetimes.md index f7d9c94bc454f..e865609f217f0 100644 --- a/src/doc/book/lifetimes.md +++ b/src/doc/book/lifetimes.md @@ -56,8 +56,12 @@ To fix this, we have to make sure that step four never happens after step three. The ownership system in Rust does this through a concept called lifetimes, which describe the scope that a reference is valid for. -When we have a function that takes an argument by reference, we can be -implicit or explicit about the lifetime of the reference: +**Note** It's important to understand that lifetime annotations are +_descriptive_, not _prescriptive_. This means that how long a reference is valid +is determined by the code, not by the annotations. The annotations, however, +give information about lifetimes to the compiler that uses them to check the +validity of references. The compiler can do so without annotations in simple +cases, but needs the programmers support in complex scenarios. ```rust // implicit diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs index b095b8131b644..883417e9f4ec7 100644 --- a/src/libcollections/fmt.rs +++ b/src/libcollections/fmt.rs @@ -327,7 +327,7 @@ //! format := '{' [ argument ] [ ':' format_spec ] '}' //! argument := integer | identifier //! -//! format_spec := [[fill]align][sign]['#'][0][width]['.' precision][type] +//! format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type] //! fill := character //! align := '<' | '^' | '>' //! sign := '+' | '-' diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 609eb28348e21..48a74bdecbbef 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -1789,4 +1789,24 @@ impl str { String::from_utf8_unchecked(slice.into_vec()) } } + + /// Create a [`String`] by repeating a string `n` times. + /// + /// [`String`]: string/struct.String.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(repeat_str)] + /// + /// assert_eq!("abc".repeat(4), String::from("abcabcabcabc")); + /// ``` + #[unstable(feature = "repeat_str", issue = "37079")] + pub fn repeat(&self, n: usize) -> String { + let mut s = String::with_capacity(self.len() * n); + s.extend((0..n).map(|_| self)); + s + } } diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 119828ea43c61..7a61451b900c0 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -14,12 +14,11 @@ //! [`ToString`]s, and several error types that may result from working with //! [`String`]s. //! -//! [`String`]: struct.String.html //! [`ToString`]: trait.ToString.html //! //! # Examples //! -//! There are multiple ways to create a new `String` from a string literal: +//! There are multiple ways to create a new [`String`] from a string literal: //! //! ``` //! let s = "Hello".to_string(); @@ -28,9 +27,11 @@ //! let s: String = "also this".into(); //! ``` //! -//! You can create a new `String` from an existing one by concatenating with +//! You can create a new [`String`] from an existing one by concatenating with //! `+`: //! +//! [`String`]: struct.String.html +//! //! ``` //! let s = "Hello".to_string(); //! diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs index 950e6ee2e9ef0..c2b34647c3279 100644 --- a/src/libcollectionstest/lib.rs +++ b/src/libcollectionstest/lib.rs @@ -19,6 +19,7 @@ #![feature(enumset)] #![feature(pattern)] #![feature(rand)] +#![feature(repeat_str)] #![feature(step_by)] #![feature(str_escape)] #![feature(str_replacen)] diff --git a/src/libcollectionstest/str.rs b/src/libcollectionstest/str.rs index 560895f721bbf..cc56bbf4890aa 100644 --- a/src/libcollectionstest/str.rs +++ b/src/libcollectionstest/str.rs @@ -1286,6 +1286,13 @@ fn test_cow_from() { } } +#[test] +fn test_repeat() { + assert_eq!("".repeat(3), ""); + assert_eq!("abc".repeat(0), ""); + assert_eq!("α".repeat(3), "ααα"); +} + mod pattern { use std::str::pattern::Pattern; use std::str::pattern::{Searcher, ReverseSearcher}; diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 2bd4a4d302936..9281d8aa44a56 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -1238,8 +1238,10 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for AtBindingPatternVisitor<'a, 'b, 'tcx> { match pat.node { PatKind::Binding(.., ref subpat) => { if !self.bindings_allowed { - span_err!(self.cx.tcx.sess, pat.span, E0303, - "pattern bindings are not allowed after an `@`"); + struct_span_err!(self.cx.tcx.sess, pat.span, E0303, + "pattern bindings are not allowed after an `@`") + .span_label(pat.span, &format!("not allowed after `@`")) + .emit(); } if subpat.is_some() { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 3f7f01a9a3b51..625acce27bd64 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -42,7 +42,7 @@ pub struct UnsafetySpace(pub hir::Unsafety); #[derive(Copy, Clone)] pub struct ConstnessSpace(pub hir::Constness); /// Wrapper struct for properly emitting a method declaration. -pub struct Method<'a>(pub &'a clean::FnDecl); +pub struct Method<'a>(pub &'a clean::FnDecl, pub &'a str); /// Similar to VisSpace, but used for mutability #[derive(Copy, Clone)] pub struct MutableSpace(pub clean::Mutability); @@ -84,7 +84,7 @@ impl<'a, T: fmt::Display> fmt::Display for CommaSep<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for (i, item) in self.0.iter().enumerate() { if i != 0 { write!(f, ", ")?; } - write!(f, "{}", item)?; + fmt::Display::fmt(item, f)?; } Ok(()) } @@ -97,7 +97,7 @@ impl<'a> fmt::Display for TyParamBounds<'a> { if i > 0 { f.write_str(" + ")?; } - write!(f, "{}", *bound)?; + fmt::Display::fmt(bound, f)?; } Ok(()) } @@ -106,35 +106,51 @@ impl<'a> fmt::Display for TyParamBounds<'a> { impl fmt::Display for clean::Generics { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.lifetimes.is_empty() && self.type_params.is_empty() { return Ok(()) } - f.write_str("<")?; + if f.alternate() { + f.write_str("<")?; + } else { + f.write_str("<")?; + } for (i, life) in self.lifetimes.iter().enumerate() { if i > 0 { - f.write_str(", ")?; + f.write_str(", ")?; } write!(f, "{}", *life)?; } if !self.type_params.is_empty() { if !self.lifetimes.is_empty() { - f.write_str(", ")?; + f.write_str(", ")?; } for (i, tp) in self.type_params.iter().enumerate() { if i > 0 { - f.write_str(", ")? + f.write_str(", ")? } f.write_str(&tp.name)?; if !tp.bounds.is_empty() { - write!(f, ": {}", TyParamBounds(&tp.bounds))?; + if f.alternate() { + write!(f, ": {:#}", TyParamBounds(&tp.bounds))?; + } else { + write!(f, ": {}", TyParamBounds(&tp.bounds))?; + } } if let Some(ref ty) = tp.default { - write!(f, " = {}", ty)?; + if f.alternate() { + write!(f, " = {:#}", ty)?; + } else { + write!(f, " = {}", ty)?; + } }; } } - f.write_str(">")?; + if f.alternate() { + f.write_str(">")?; + } else { + f.write_str(">")?; + } Ok(()) } } @@ -145,7 +161,11 @@ impl<'a> fmt::Display for WhereClause<'a> { if gens.where_predicates.is_empty() { return Ok(()); } - f.write_str(" where ")?; + if f.alternate() { + f.write_str(" ")?; + } else { + f.write_str(" where ")?; + } for (i, pred) in gens.where_predicates.iter().enumerate() { if i > 0 { f.write_str(", ")?; @@ -153,7 +173,11 @@ impl<'a> fmt::Display for WhereClause<'a> { match pred { &clean::WherePredicate::BoundPredicate { ref ty, ref bounds } => { let bounds = bounds; - write!(f, "{}: {}", ty, TyParamBounds(bounds))?; + if f.alternate() { + write!(f, "{:#}: {:#}", ty, TyParamBounds(bounds))?; + } else { + write!(f, "{}: {}", ty, TyParamBounds(bounds))?; + } } &clean::WherePredicate::RegionPredicate { ref lifetime, ref bounds } => { @@ -167,11 +191,17 @@ impl<'a> fmt::Display for WhereClause<'a> { } } &clean::WherePredicate::EqPredicate { ref lhs, ref rhs } => { - write!(f, "{} == {}", lhs, rhs)?; + if f.alternate() { + write!(f, "{:#} == {:#}", lhs, rhs)?; + } else { + write!(f, "{} == {}", lhs, rhs)?; + } } } } - f.write_str("")?; + if !f.alternate() { + f.write_str("")?; + } Ok(()) } } @@ -186,16 +216,28 @@ impl fmt::Display for clean::Lifetime { impl fmt::Display for clean::PolyTrait { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if !self.lifetimes.is_empty() { - f.write_str("for<")?; + if f.alternate() { + f.write_str("for<")?; + } else { + f.write_str("for<")?; + } for (i, lt) in self.lifetimes.iter().enumerate() { if i > 0 { f.write_str(", ")?; } write!(f, "{}", lt)?; } - f.write_str("> ")?; + if f.alternate() { + f.write_str("> ")?; + } else { + f.write_str("> ")?; + } + } + if f.alternate() { + write!(f, "{:#}", self.trait_) + } else { + write!(f, "{}", self.trait_) } - write!(f, "{}", self.trait_) } } @@ -210,7 +252,11 @@ impl fmt::Display for clean::TyParamBound { hir::TraitBoundModifier::None => "", hir::TraitBoundModifier::Maybe => "?", }; - write!(f, "{}{}", modifier_str, *ty) + if f.alternate() { + write!(f, "{}{:#}", modifier_str, *ty) + } else { + write!(f, "{}{}", modifier_str, *ty) + } } } } @@ -223,30 +269,46 @@ impl fmt::Display for clean::PathParameters { ref lifetimes, ref types, ref bindings } => { if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() { - f.write_str("<")?; + if f.alternate() { + f.write_str("<")?; + } else { + f.write_str("<")?; + } let mut comma = false; for lifetime in lifetimes { if comma { - f.write_str(", ")?; + f.write_str(", ")?; } comma = true; write!(f, "{}", *lifetime)?; } for ty in types { if comma { - f.write_str(", ")?; + f.write_str(", ")?; } comma = true; - write!(f, "{}", *ty)?; + if f.alternate() { + write!(f, "{:#}", *ty)?; + } else { + write!(f, "{}", *ty)?; + } } for binding in bindings { if comma { - f.write_str(", ")?; + f.write_str(", ")?; } comma = true; - write!(f, "{}", *binding)?; + if f.alternate() { + write!(f, "{:#}", *binding)?; + } else { + write!(f, "{}", *binding)?; + } + } + if f.alternate() { + f.write_str(">")?; + } else { + f.write_str(">")?; } - f.write_str(">")?; } } clean::PathParameters::Parenthesized { ref inputs, ref output } => { @@ -257,12 +319,19 @@ impl fmt::Display for clean::PathParameters { f.write_str(", ")?; } comma = true; - write!(f, "{}", *ty)?; + if f.alternate() { + write!(f, "{:#}", *ty)?; + } else { + write!(f, "{}", *ty)?; + } } f.write_str(")")?; if let Some(ref ty) = *output { - f.write_str(" -> ")?; - write!(f, "{}", ty)?; + if f.alternate() { + write!(f, " -> {:#}", ty)?; + } else { + write!(f, " -> {}", ty)?; + } } } } @@ -273,7 +342,11 @@ impl fmt::Display for clean::PathParameters { impl fmt::Display for clean::PathSegment { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(&self.name)?; - write!(f, "{}", self.params) + if f.alternate() { + write!(f, "{:#}", self.params) + } else { + write!(f, "{}", self.params) + } } } @@ -287,7 +360,11 @@ impl fmt::Display for clean::Path { if i > 0 { f.write_str("::")? } - write!(f, "{}", seg)?; + if f.alternate() { + write!(f, "{:#}", seg)?; + } else { + write!(f, "{}", seg)?; + } } Ok(()) } @@ -349,7 +426,7 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path, match rel_root { Some(mut root) => { for seg in &path.segments[..amt] { - if "super" == seg.name || "self" == seg.name { + if "super" == seg.name || "self" == seg.name || w.alternate() { write!(w, "{}::", seg.name)?; } else { root.push_str(&seg.name); @@ -368,7 +445,11 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path, } } } - write!(w, "{}{}", HRef::new(did, &last.name), last.params)?; + if w.alternate() { + write!(w, "{:#}{:#}", HRef::new(did, &last.name), last.params)?; + } else { + write!(w, "{}{}", HRef::new(did, &last.name), last.params)?; + } Ok(()) } @@ -377,33 +458,35 @@ fn primitive_link(f: &mut fmt::Formatter, name: &str) -> fmt::Result { let m = cache(); let mut needs_termination = false; - match m.primitive_locations.get(&prim) { - Some(&LOCAL_CRATE) => { - let len = CURRENT_LOCATION_KEY.with(|s| s.borrow().len()); - let len = if len == 0 {0} else {len - 1}; - write!(f, "", - repeat("../").take(len).collect::(), - prim.to_url_str())?; - needs_termination = true; - } - Some(&cnum) => { - let loc = match m.extern_locations[&cnum] { - (ref cname, render::Remote(ref s)) => Some((cname, s.to_string())), - (ref cname, render::Local) => { - let len = CURRENT_LOCATION_KEY.with(|s| s.borrow().len()); - Some((cname, repeat("../").take(len).collect::())) - } - (_, render::Unknown) => None, - }; - if let Some((cname, root)) = loc { - write!(f, "", - root, - cname, + if !f.alternate() { + match m.primitive_locations.get(&prim) { + Some(&LOCAL_CRATE) => { + let len = CURRENT_LOCATION_KEY.with(|s| s.borrow().len()); + let len = if len == 0 {0} else {len - 1}; + write!(f, "", + repeat("../").take(len).collect::(), prim.to_url_str())?; needs_termination = true; } + Some(&cnum) => { + let loc = match m.extern_locations[&cnum] { + (ref cname, render::Remote(ref s)) => Some((cname, s.to_string())), + (ref cname, render::Local) => { + let len = CURRENT_LOCATION_KEY.with(|s| s.borrow().len()); + Some((cname, repeat("../").take(len).collect::())) + } + (_, render::Unknown) => None, + }; + if let Some((cname, root)) = loc { + write!(f, "", + root, + cname, + prim.to_url_str())?; + needs_termination = true; + } + } + None => {} } - None => {} } write!(f, "{}", name)?; if needs_termination { @@ -419,7 +502,7 @@ fn tybounds(w: &mut fmt::Formatter, Some(ref params) => { for param in params { write!(w, " + ")?; - write!(w, "{}", *param)?; + fmt::Display::fmt(param, w)?; } Ok(()) } @@ -436,10 +519,12 @@ impl<'a> HRef<'a> { impl<'a> fmt::Display for HRef<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match href(self.did) { - Some((url, shortty, fqp)) => { + Some((url, shortty, fqp)) => if !f.alternate() { write!(f, "{}", shortty, url, fqp.join("::"), self.text) - } + } else { + write!(f, "{}", self.text) + }, _ => write!(f, "{}", self.text), } } @@ -459,49 +544,68 @@ impl fmt::Display for clean::Type { clean::Infer => write!(f, "_"), clean::Primitive(prim) => primitive_link(f, prim, prim.as_str()), clean::BareFunction(ref decl) => { - write!(f, "{}{}fn{}{}", - UnsafetySpace(decl.unsafety), - AbiSpace(decl.abi), - decl.generics, - decl.decl) + if f.alternate() { + write!(f, "{}{}fn{:#}{:#}", + UnsafetySpace(decl.unsafety), + AbiSpace(decl.abi), + decl.generics, + decl.decl) + } else { + write!(f, "{}{}fn{}{}", + UnsafetySpace(decl.unsafety), + AbiSpace(decl.abi), + decl.generics, + decl.decl) + } } clean::Tuple(ref typs) => { match &typs[..] { &[] => primitive_link(f, PrimitiveType::Tuple, "()"), &[ref one] => { primitive_link(f, PrimitiveType::Tuple, "(")?; - write!(f, "{},", one)?; - primitive_link(f, PrimitiveType::Tuple, ")") + //carry f.alternate() into this display w/o branching manually + fmt::Display::fmt(one, f)?; + primitive_link(f, PrimitiveType::Tuple, ",)") } many => { primitive_link(f, PrimitiveType::Tuple, "(")?; - write!(f, "{}", CommaSep(&many))?; + fmt::Display::fmt(&CommaSep(&many), f)?; primitive_link(f, PrimitiveType::Tuple, ")") } } } clean::Vector(ref t) => { primitive_link(f, PrimitiveType::Slice, &format!("["))?; - write!(f, "{}", t)?; + fmt::Display::fmt(t, f)?; primitive_link(f, PrimitiveType::Slice, &format!("]")) } clean::FixedVector(ref t, ref s) => { primitive_link(f, PrimitiveType::Array, "[")?; - write!(f, "{}", t)?; - primitive_link(f, PrimitiveType::Array, - &format!("; {}]", Escape(s))) + fmt::Display::fmt(t, f)?; + if f.alternate() { + primitive_link(f, PrimitiveType::Array, + &format!("; {}]", s)) + } else { + primitive_link(f, PrimitiveType::Array, + &format!("; {}]", Escape(s))) + } } clean::Never => f.write_str("!"), clean::RawPointer(m, ref t) => { match **t { clean::Generic(_) | clean::ResolvedPath {is_generic: true, ..} => { - primitive_link(f, clean::PrimitiveType::RawPointer, - &format!("*{}{}", RawMutableSpace(m), t)) + if f.alternate() { + primitive_link(f, clean::PrimitiveType::RawPointer, + &format!("*{}{:#}", RawMutableSpace(m), t)) + } else { + primitive_link(f, clean::PrimitiveType::RawPointer, + &format!("*{}{}", RawMutableSpace(m), t)) + } } _ => { primitive_link(f, clean::PrimitiveType::RawPointer, &format!("*{}", RawMutableSpace(m)))?; - write!(f, "{}", t) + fmt::Display::fmt(t, f) } } } @@ -515,18 +619,33 @@ impl fmt::Display for clean::Type { clean::Vector(ref bt) => { // BorrowedRef{ ... Vector(T) } is &[T] match **bt { clean::Generic(_) => - primitive_link(f, PrimitiveType::Slice, - &format!("&{}{}[{}]", lt, m, **bt)), + if f.alternate() { + primitive_link(f, PrimitiveType::Slice, + &format!("&{}{}[{:#}]", lt, m, **bt)) + } else { + primitive_link(f, PrimitiveType::Slice, + &format!("&{}{}[{}]", lt, m, **bt)) + }, _ => { - primitive_link(f, PrimitiveType::Slice, - &format!("&{}{}[", lt, m))?; - write!(f, "{}", **bt)?; + if f.alternate() { + primitive_link(f, PrimitiveType::Slice, + &format!("&{}{}[", lt, m))?; + write!(f, "{:#}", **bt)?; + } else { + primitive_link(f, PrimitiveType::Slice, + &format!("&{}{}[", lt, m))?; + write!(f, "{}", **bt)?; + } primitive_link(f, PrimitiveType::Slice, "]") } } } _ => { - write!(f, "&{}{}{}", lt, m, **ty) + if f.alternate() { + write!(f, "&{}{}{:#}", lt, m, **ty) + } else { + write!(f, "&{}{}{}", lt, m, **ty) + } } } } @@ -535,7 +654,11 @@ impl fmt::Display for clean::Type { if i != 0 { write!(f, " + ")?; } - write!(f, "{}", *bound)?; + if f.alternate() { + write!(f, "{:#}", *bound)?; + } else { + write!(f, "{}", *bound)?; + } } Ok(()) } @@ -545,7 +668,11 @@ impl fmt::Display for clean::Type { if i != 0 { write!(f, " + ")?; } - write!(f, "{}", *bound)?; + if f.alternate() { + write!(f, "{:#}", *bound)?; + } else { + write!(f, "{}", *bound)?; + } } Ok(()) } @@ -564,7 +691,11 @@ impl fmt::Display for clean::Type { ref self_type, trait_: box clean::ResolvedPath { did, ref typarams, .. }, } => { - write!(f, "{}::", self_type)?; + if f.alternate() { + write!(f, "{:#}::", self_type)?; + } else { + write!(f, "{}::", self_type)?; + } let path = clean::Path::singleton(name.clone()); resolved_path(f, did, &path, false)?; @@ -573,7 +704,11 @@ impl fmt::Display for clean::Type { Ok(()) } clean::QPath { ref name, ref self_type, ref trait_ } => { - write!(f, "<{} as {}>::{}", self_type, trait_, name) + if f.alternate() { + write!(f, "<{:#} as {:#}>::{}", self_type, trait_, name) + } else { + write!(f, "<{} as {}>::{}", self_type, trait_, name) + } } clean::Unique(..) => { panic!("should have been cleaned") @@ -583,24 +718,30 @@ impl fmt::Display for clean::Type { } fn fmt_impl(i: &clean::Impl, f: &mut fmt::Formatter, link_trait: bool) -> fmt::Result { - write!(f, "impl{} ", i.generics)?; + if f.alternate() { + write!(f, "impl{:#} ", i.generics)?; + } else { + write!(f, "impl{} ", i.generics)?; + } if let Some(ref ty) = i.trait_ { write!(f, "{}", if i.polarity == Some(clean::ImplPolarity::Negative) { "!" } else { "" })?; if link_trait { - write!(f, "{}", *ty)?; + fmt::Display::fmt(ty, f)?; } else { match *ty { clean::ResolvedPath{ typarams: None, ref path, is_generic: false, .. } => { let last = path.segments.last().unwrap(); - write!(f, "{}{}", last.name, last.params)?; + fmt::Display::fmt(&last.name, f)?; + fmt::Display::fmt(&last.params, f)?; } _ => unreachable!(), } } write!(f, " for ")?; } - write!(f, "{}{}", i.for_, WhereClause(&i.generics))?; + fmt::Display::fmt(&i.for_, f)?; + fmt::Display::fmt(&WhereClause(&i.generics), f)?; Ok(()) } @@ -618,11 +759,15 @@ pub fn fmt_impl_for_trait_page(i: &clean::Impl, f: &mut fmt::Formatter) -> fmt:: impl fmt::Display for clean::Arguments { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for (i, input) in self.values.iter().enumerate() { - if i > 0 { write!(f, ", ")?; } if !input.name.is_empty() { write!(f, "{}: ", input.name)?; } - write!(f, "{}", input.type_)?; + if f.alternate() { + write!(f, "{:#}", input.type_)?; + } else { + write!(f, "{}", input.type_)?; + } + if i + 1 < self.values.len() { write!(f, ", ")?; } } Ok(()) } @@ -632,6 +777,7 @@ impl fmt::Display for clean::FunctionRetTy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { clean::Return(clean::Tuple(ref tys)) if tys.is_empty() => Ok(()), + clean::Return(ref ty) if f.alternate() => write!(f, " -> {:#}", ty), clean::Return(ref ty) => write!(f, " -> {}", ty), clean::DefaultReturn => Ok(()), } @@ -641,9 +787,17 @@ impl fmt::Display for clean::FunctionRetTy { impl fmt::Display for clean::FnDecl { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.variadic { - write!(f, "({args}, ...){arrow}", args = self.inputs, arrow = self.output) + if f.alternate() { + write!(f, "({args:#}, ...){arrow:#}", args = self.inputs, arrow = self.output) + } else { + write!(f, "({args}, ...){arrow}", args = self.inputs, arrow = self.output) + } } else { - write!(f, "({args}){arrow}", args = self.inputs, arrow = self.output) + if f.alternate() { + write!(f, "({args:#}){arrow:#}", args = self.inputs, arrow = self.output) + } else { + write!(f, "({args}){arrow}", args = self.inputs, arrow = self.output) + } } } } @@ -651,30 +805,89 @@ impl fmt::Display for clean::FnDecl { impl<'a> fmt::Display for Method<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let decl = self.0; + let indent = self.1; + let amp = if f.alternate() { "&" } else { "&" }; let mut args = String::new(); + let mut args_plain = String::new(); for (i, input) in decl.inputs.values.iter().enumerate() { - if i > 0 || !args.is_empty() { args.push_str(", "); } if let Some(selfty) = input.to_self() { match selfty { - clean::SelfValue => args.push_str("self"), + clean::SelfValue => { + args.push_str("self"); + args_plain.push_str("self"); + } clean::SelfBorrowed(Some(ref lt), mtbl) => { - args.push_str(&format!("&{} {}self", *lt, MutableSpace(mtbl))); + args.push_str(&format!("{}{} {}self", amp, *lt, MutableSpace(mtbl))); + args_plain.push_str(&format!("&{} {}self", *lt, MutableSpace(mtbl))); } clean::SelfBorrowed(None, mtbl) => { - args.push_str(&format!("&{}self", MutableSpace(mtbl))); + args.push_str(&format!("{}{}self", amp, MutableSpace(mtbl))); + args_plain.push_str(&format!("&{}self", MutableSpace(mtbl))); } clean::SelfExplicit(ref typ) => { - args.push_str(&format!("self: {}", *typ)); + if f.alternate() { + args.push_str(&format!("self: {:#}", *typ)); + } else { + args.push_str(&format!("self: {}", *typ)); + } + args_plain.push_str(&format!("self: {:#}", *typ)); } } } else { + if i > 0 { + args.push_str("
"); + args_plain.push_str(" "); + } if !input.name.is_empty() { args.push_str(&format!("{}: ", input.name)); + args_plain.push_str(&format!("{}: ", input.name)); } - args.push_str(&format!("{}", input.type_)); + + if f.alternate() { + args.push_str(&format!("{:#}", input.type_)); + } else { + args.push_str(&format!("{}", input.type_)); + } + args_plain.push_str(&format!("{:#}", input.type_)); + } + if i + 1 < decl.inputs.values.len() { + args.push_str(","); + args_plain.push_str(","); } } - write!(f, "({args}){arrow}", args = args, arrow = decl.output) + + if decl.variadic { + args.push_str(",
..."); + args_plain.push_str(", ..."); + } + + let arrow_plain = format!("{:#}", decl.output); + let arrow = if f.alternate() { + format!("{:#}", decl.output) + } else { + format!("{}", decl.output) + }; + + let mut output: String; + let plain: String; + if arrow.is_empty() { + output = format!("({})", args); + plain = format!("{}({})", indent.replace(" ", " "), args_plain); + } else { + output = format!("({args})
{arrow}", args = args, arrow = arrow); + plain = format!("{indent}({args}){arrow}", + indent = indent.replace(" ", " "), + args = args_plain, + arrow = arrow_plain); + } + + if plain.len() > 80 { + let pad = format!("
{}", indent); + output = output.replace("
", &pad); + } else { + output = output.replace("
", ""); + } + write!(f, "{}", output) } } @@ -768,7 +981,11 @@ impl fmt::Display for clean::ViewListIdent { impl fmt::Display for clean::TypeBinding { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}={}", self.name, self.ty) + if f.alternate() { + write!(f, "{}={:#}", self.name, self.ty) + } else { + write!(f, "{}={}", self.name, self.ty) + } } } @@ -792,10 +1009,11 @@ impl fmt::Display for RawMutableSpace { impl fmt::Display for AbiSpace { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let quot = if f.alternate() { "\"" } else { """ }; match self.0 { Abi::Rust => Ok(()), Abi::C => write!(f, "extern "), - abi => write!(f, "extern "{}" ", abi.name()), + abi => write!(f, "extern {0}{1}{0} ", quot, abi.name()), } } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 5a6e167188226..d8dba00e7d578 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1967,6 +1967,14 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, UnstableFeatures::Allow => f.constness, _ => hir::Constness::NotConst }; + let prefix = format!("{}{}{}{:#}fn {}{:#}", + VisSpace(&it.visibility), + ConstnessSpace(vis_constness), + UnsafetySpace(f.unsafety), + AbiSpace(f.abi), + it.name.as_ref().unwrap(), + f.generics); + let indent = repeat(" ").take(prefix.len()).collect::(); write!(w, "
{vis}{constness}{unsafety}{abi}fn \
                {name}{generics}{decl}{where_clause}
", vis = VisSpace(&it.visibility), @@ -1976,7 +1984,7 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, name = it.name.as_ref().unwrap(), generics = f.generics, where_clause = WhereClause(&f.generics), - decl = f.decl)?; + decl = Method(&f.decl, &indent))?; document(w, cx, it) } @@ -2246,6 +2254,13 @@ fn render_assoc_item(w: &mut fmt::Formatter, UnstableFeatures::Allow => constness, _ => hir::Constness::NotConst }; + let prefix = format!("{}{}{:#}fn {}{:#}", + ConstnessSpace(vis_constness), + UnsafetySpace(unsafety), + AbiSpace(abi), + name, + *g); + let indent = repeat(" ").take(prefix.len()).collect::(); write!(w, "{}{}{}fn {name}\ {generics}{decl}{where_clause}", ConstnessSpace(vis_constness), @@ -2254,7 +2269,7 @@ fn render_assoc_item(w: &mut fmt::Formatter, href = href, name = name, generics = *g, - decl = Method(d), + decl = Method(d, &indent), where_clause = WhereClause(g)) } match item.inner { diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 32b66da4d96ce..792239e721932 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -125,9 +125,8 @@ impl fmt::Display for Token { } } -fn buf_str(toks: &[Token], szs: &[isize], left: usize, right: usize, lim: usize) -> String { - let n = toks.len(); - assert_eq!(n, szs.len()); +fn buf_str(buf: &[BufEntry], left: usize, right: usize, lim: usize) -> String { + let n = buf.len(); let mut i = left; let mut l = lim; let mut s = String::from("["); @@ -136,7 +135,7 @@ fn buf_str(toks: &[Token], szs: &[isize], left: usize, right: usize, lim: usize) if i != left { s.push_str(", "); } - s.push_str(&format!("{}={}", szs[i], &toks[i])); + s.push_str(&format!("{}={}", buf[i].size, &buf[i].token)); i += 1; i %= n; } @@ -159,13 +158,9 @@ pub struct PrintStackElem { const SIZE_INFINITY: isize = 0xffff; pub fn mk_printer<'a>(out: Box, linewidth: usize) -> Printer<'a> { - // Yes 55, it makes the ring buffers big enough to never - // fall behind. + // Yes 55, it makes the ring buffers big enough to never fall behind. let n: usize = 55 * linewidth; debug!("mk_printer {}", linewidth); - let token = vec![Token::Eof; n]; - let size = vec![0; n]; - let scan_stack = VecDeque::with_capacity(n); Printer { out: out, buf_len: n, @@ -173,11 +168,10 @@ pub fn mk_printer<'a>(out: Box, linewidth: usize) -> Printer<'a> { space: linewidth as isize, left: 0, right: 0, - token: token, - size: size, + buf: vec![BufEntry { token: Token::Eof, size: 0 }; n], left_total: 0, right_total: 0, - scan_stack: scan_stack, + scan_stack: VecDeque::new(), print_stack: Vec::new(), pending_indentation: 0 } @@ -269,10 +263,8 @@ pub struct Printer<'a> { left: usize, /// Index of right side of input stream right: usize, - /// Ring-buffer stream goes through - token: Vec , - /// Ring-buffer of calculated sizes - size: Vec , + /// Ring-buffer of tokens and calculated sizes + buf: Vec, /// Running size of stream "...left" left_total: isize, /// Running size of stream "...right" @@ -283,20 +275,26 @@ pub struct Printer<'a> { /// Begin (if there is any) on top of it. Stuff is flushed off the /// bottom as it becomes irrelevant due to the primary ring-buffer /// advancing. - scan_stack: VecDeque , + scan_stack: VecDeque, /// Stack of blocks-in-progress being flushed by print print_stack: Vec , /// Buffered indentation to avoid writing trailing whitespace pending_indentation: isize, } +#[derive(Clone)] +struct BufEntry { + token: Token, + size: isize, +} + impl<'a> Printer<'a> { pub fn last_token(&mut self) -> Token { - self.token[self.right].clone() + self.buf[self.right].token.clone() } // be very careful with this! pub fn replace_last_token(&mut self, t: Token) { - self.token[self.right] = t; + self.buf[self.right].token = t; } pub fn pretty_print(&mut self, token: Token) -> io::Result<()> { debug!("pp Vec<{},{}>", self.left, self.right); @@ -318,8 +316,7 @@ impl<'a> Printer<'a> { } else { self.advance_right(); } debug!("pp Begin({})/buffer Vec<{},{}>", b.offset, self.left, self.right); - self.token[self.right] = token; - self.size[self.right] = -self.right_total; + self.buf[self.right] = BufEntry { token: token, size: -self.right_total }; let right = self.right; self.scan_push(right); Ok(()) @@ -331,8 +328,7 @@ impl<'a> Printer<'a> { } else { debug!("pp End/buffer Vec<{},{}>", self.left, self.right); self.advance_right(); - self.token[self.right] = token; - self.size[self.right] = -1; + self.buf[self.right] = BufEntry { token: token, size: -1 }; let right = self.right; self.scan_push(right); Ok(()) @@ -350,8 +346,7 @@ impl<'a> Printer<'a> { self.check_stack(0); let right = self.right; self.scan_push(right); - self.token[self.right] = token; - self.size[self.right] = -self.right_total; + self.buf[self.right] = BufEntry { token: token, size: -self.right_total }; self.right_total += b.blank_space; Ok(()) } @@ -364,8 +359,7 @@ impl<'a> Printer<'a> { debug!("pp String('{}')/buffer Vec<{},{}>", s, self.left, self.right); self.advance_right(); - self.token[self.right] = Token::String(s, len); - self.size[self.right] = len; + self.buf[self.right] = BufEntry { token: Token::String(s, len), size: len }; self.right_total += len; self.check_stream() } @@ -381,7 +375,7 @@ impl<'a> Printer<'a> { if Some(&self.left) == self.scan_stack.back() { debug!("setting {} to infinity and popping", self.left); let scanned = self.scan_pop_bottom(); - self.size[scanned] = SIZE_INFINITY; + self.buf[scanned].size = SIZE_INFINITY; } self.advance_left()?; if self.left != self.right { @@ -410,12 +404,12 @@ impl<'a> Printer<'a> { } pub fn advance_left(&mut self) -> io::Result<()> { debug!("advance_left Vec<{},{}>, sizeof({})={}", self.left, self.right, - self.left, self.size[self.left]); + self.left, self.buf[self.left].size); - let mut left_size = self.size[self.left]; + let mut left_size = self.buf[self.left].size; while left_size >= 0 { - let left = self.token[self.left].clone(); + let left = self.buf[self.left].token.clone(); let len = match left { Token::Break(b) => b.blank_space, @@ -437,7 +431,7 @@ impl<'a> Printer<'a> { self.left += 1; self.left %= self.buf_len; - left_size = self.size[self.left]; + left_size = self.buf[self.left].size; } Ok(()) @@ -445,23 +439,23 @@ impl<'a> Printer<'a> { pub fn check_stack(&mut self, k: isize) { if !self.scan_stack.is_empty() { let x = self.scan_top(); - match self.token[x] { + match self.buf[x].token { Token::Begin(_) => { if k > 0 { let popped = self.scan_pop(); - self.size[popped] = self.size[x] + self.right_total; + self.buf[popped].size = self.buf[x].size + self.right_total; self.check_stack(k - 1); } } Token::End => { // paper says + not =, but that makes no sense. let popped = self.scan_pop(); - self.size[popped] = 1; + self.buf[popped].size = 1; self.check_stack(k + 1); } _ => { let popped = self.scan_pop(); - self.size[popped] = self.size[x] + self.right_total; + self.buf[popped].size = self.buf[x].size + self.right_total; if k > 0 { self.check_stack(k); } @@ -499,8 +493,7 @@ impl<'a> Printer<'a> { pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> { debug!("print {} {} (remaining line space={})", token, l, self.space); - debug!("{}", buf_str(&self.token, - &self.size, + debug!("{}", buf_str(&self.buf, self.left, self.right, 6)); diff --git a/src/test/compile-fail/E0007.rs b/src/test/compile-fail/E0007.rs index 4be115b8afdac..b72b5e3b2808b 100644 --- a/src/test/compile-fail/E0007.rs +++ b/src/test/compile-fail/E0007.rs @@ -15,6 +15,7 @@ fn main() { //~^ ERROR E0007 //~| NOTE binds an already bound by-move value by moving it //~| ERROR E0303 + //~| NOTE not allowed after `@` None => {}, } } diff --git a/src/test/compile-fail/E0303.rs b/src/test/compile-fail/E0303.rs index 67947fd087c05..e631fe2a8a7cc 100644 --- a/src/test/compile-fail/E0303.rs +++ b/src/test/compile-fail/E0303.rs @@ -10,8 +10,12 @@ fn main() { match Some("hi".to_string()) { - ref op_string_ref @ Some(s) => {}, //~ ERROR E0303 - //~^ ERROR E0009 + ref op_string_ref @ Some(s) => {}, + //~^ ERROR pattern bindings are not allowed after an `@` [E0303] + //~| NOTE not allowed after `@` + //~| ERROR E0009 + //~| NOTE by-move pattern here + //~| NOTE both by-ref and by-move used None => {}, } } diff --git a/src/test/incremental/hashes/consts.rs b/src/test/incremental/hashes/consts.rs new file mode 100644 index 0000000000000..10c02d84b385e --- /dev/null +++ b/src/test/incremental/hashes/consts.rs @@ -0,0 +1,132 @@ +// 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 consts. + +// 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. + +// must-compile-successfully +// revisions: cfail1 cfail2 cfail3 +// compile-flags: -Z query-dep-graph + +#![allow(warnings)] +#![feature(rustc_attrs)] +#![crate_type="rlib"] + + +// Change const visibility --------------------------------------------------- +#[cfg(cfail1)] +const CONST_VISIBILITY: u8 = 0; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +pub const CONST_VISIBILITY: u8 = 0; + + +// Change type from i32 to u32 ------------------------------------------------ +#[cfg(cfail1)] +const CONST_CHANGE_TYPE_1: i32 = 0; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +const CONST_CHANGE_TYPE_1: u32 = 0; + + +// Change type from Option to Option -------------------------------- +#[cfg(cfail1)] +const CONST_CHANGE_TYPE_2: Option = None; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +const CONST_CHANGE_TYPE_2: Option = None; + + +// Change value between simple literals --------------------------------------- +#[cfg(cfail1)] +const CONST_CHANGE_VALUE_1: i16 = 1; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +const CONST_CHANGE_VALUE_1: i16 = 2; + + +// Change value between expressions ------------------------------------------- +#[cfg(cfail1)] +const CONST_CHANGE_VALUE_2: i16 = 1 + 1; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +const CONST_CHANGE_VALUE_2: i16 = 1 + 2; + + +#[cfg(cfail1)] +const CONST_CHANGE_VALUE_3: i16 = 2 + 3; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +const CONST_CHANGE_VALUE_3: i16 = 2 * 3; + + +#[cfg(cfail1)] +const CONST_CHANGE_VALUE_4: i16 = 1 + 2 * 3; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +const CONST_CHANGE_VALUE_4: i16 = 1 + 2 * 4; + + +// Change type indirectly ----------------------------------------------------- +struct ReferencedType1; +struct ReferencedType2; + +mod const_change_type_indirectly { + #[cfg(cfail1)] + use super::ReferencedType1 as Type; + + #[cfg(not(cfail1))] + use super::ReferencedType2 as Type; + + #[rustc_dirty(label="Hir", cfg="cfail2")] + #[rustc_clean(label="Hir", cfg="cfail3")] + #[rustc_metadata_dirty(cfg="cfail2")] + #[rustc_metadata_clean(cfg="cfail3")] + const CONST_CHANGE_TYPE_INDIRECTLY_1: Type = Type; + + #[rustc_dirty(label="Hir", cfg="cfail2")] + #[rustc_clean(label="Hir", cfg="cfail3")] + #[rustc_metadata_dirty(cfg="cfail2")] + #[rustc_metadata_clean(cfg="cfail3")] + const CONST_CHANGE_TYPE_INDIRECTLY_2: Option = None; +} diff --git a/src/test/incremental/hashes/statics.rs b/src/test/incremental/hashes/statics.rs new file mode 100644 index 0000000000000..ac67e4349013a --- /dev/null +++ b/src/test/incremental/hashes/statics.rs @@ -0,0 +1,185 @@ +// 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 statics. + +// 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. + +// must-compile-successfully +// revisions: cfail1 cfail2 cfail3 +// compile-flags: -Z query-dep-graph + +#![allow(warnings)] +#![feature(rustc_attrs)] +#![feature(linkage)] +#![feature(thread_local)] +#![crate_type="rlib"] + + +// Change static visibility --------------------------------------------------- +#[cfg(cfail1)] +static STATIC_VISIBILITY: u8 = 0; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +pub static STATIC_VISIBILITY: u8 = 0; + + +// Change static mutability --------------------------------------------------- +#[cfg(cfail1)] +static STATIC_MUTABILITY: u8 = 0; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +static mut STATIC_MUTABILITY: u8 = 0; + + +// Add linkage attribute ------------------------------------------------------ +#[cfg(cfail1)] +static STATIC_LINKAGE: u8 = 0; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +#[linkage="weak_odr"] +static STATIC_LINKAGE: u8 = 0; + + +// Add no_mangle attribute ---------------------------------------------------- +#[cfg(cfail1)] +static STATIC_NO_MANGLE: u8 = 0; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +#[no_mangle] +static STATIC_NO_MANGLE: u8 = 0; + + +// Add thread_local attribute ------------------------------------------------- +#[cfg(cfail1)] +static STATIC_THREAD_LOCAL: u8 = 0; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +#[thread_local] +static STATIC_THREAD_LOCAL: u8 = 0; + + +// Change type from i16 to u64 ------------------------------------------------ +#[cfg(cfail1)] +static STATIC_CHANGE_TYPE_1: i16 = 0; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +static STATIC_CHANGE_TYPE_1: u64 = 0; + + +// Change type from Option to Option --------------------------------- +#[cfg(cfail1)] +static STATIC_CHANGE_TYPE_2: Option = None; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +static STATIC_CHANGE_TYPE_2: Option = None; + + +// Change value between simple literals --------------------------------------- +#[cfg(cfail1)] +static STATIC_CHANGE_VALUE_1: i16 = 1; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +static STATIC_CHANGE_VALUE_1: i16 = 2; + + +// Change value between expressions ------------------------------------------- +#[cfg(cfail1)] +static STATIC_CHANGE_VALUE_2: i16 = 1 + 1; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +static STATIC_CHANGE_VALUE_2: i16 = 1 + 2; + + +#[cfg(cfail1)] +static STATIC_CHANGE_VALUE_3: i16 = 2 + 3; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +static STATIC_CHANGE_VALUE_3: i16 = 2 * 3; + + +#[cfg(cfail1)] +static STATIC_CHANGE_VALUE_4: i16 = 1 + 2 * 3; + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +static STATIC_CHANGE_VALUE_4: i16 = 1 + 2 * 4; + + +// Change type indirectly ----------------------------------------------------- +struct ReferencedType1; +struct ReferencedType2; + +mod static_change_type_indirectly { + #[cfg(cfail1)] + use super::ReferencedType1 as Type; + + #[cfg(not(cfail1))] + use super::ReferencedType2 as Type; + + #[rustc_dirty(label="Hir", cfg="cfail2")] + #[rustc_clean(label="Hir", cfg="cfail3")] + #[rustc_metadata_dirty(cfg="cfail2")] + #[rustc_metadata_clean(cfg="cfail3")] + static STATIC_CHANGE_TYPE_INDIRECTLY_1: Type = Type; + + #[rustc_dirty(label="Hir", cfg="cfail2")] + #[rustc_clean(label="Hir", cfg="cfail3")] + #[rustc_metadata_dirty(cfg="cfail2")] + #[rustc_metadata_clean(cfg="cfail3")] + static STATIC_CHANGE_TYPE_INDIRECTLY_2: Option = None; +} diff --git a/src/test/incremental/hashes/trait_defs.rs b/src/test/incremental/hashes/trait_defs.rs index 58fbdabf87216..937f053e320f6 100644 --- a/src/test/incremental/hashes/trait_defs.rs +++ b/src/test/incremental/hashes/trait_defs.rs @@ -46,16 +46,15 @@ pub trait TraitVisibility { } // Change trait unsafety ---------------------------------------------------------- -// FIXME: this should work but doesn't yet. -// #[cfg(cfail1)] -// trait TraitUnsafety { } +#[cfg(cfail1)] +trait TraitUnsafety { } -// #[cfg(not(cfail1))] -// #[rustc_dirty(label="Hir", cfg="cfail2")] -// #[rustc_clean(label="Hir", cfg="cfail3")] -// #[rustc_metadata_dirty(cfg="cfail2")] -// #[rustc_metadata_clean(cfg="cfail3")] -// unsafe trait TraitUnsafety { } +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +unsafe trait TraitUnsafety { } @@ -178,20 +177,19 @@ trait TraitChangeMethodParameterType { // Change type of method parameter (&i32 => &mut i32) ----------------------------- -// FIXME: this should work but doesn't yet. -// #[cfg(cfail1)] -// trait TraitChangeMethodParameterTypeRef { -// fn method(a: &i32); -// } +#[cfg(cfail1)] +trait TraitChangeMethodParameterTypeRef { + fn method(a: &i32); +} -// #[cfg(not(cfail1))] -// #[rustc_dirty(label="Hir", cfg="cfail2")] -// #[rustc_clean(label="Hir", cfg="cfail3")] -// #[rustc_metadata_dirty(cfg="cfail2")] -// #[rustc_metadata_clean(cfg="cfail3")] -// trait TraitChangeMethodParameterTypeRef { -// fn method(a: &mut i32); -// } +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +trait TraitChangeMethodParameterTypeRef { + fn method(a: &mut i32); +} @@ -249,35 +247,35 @@ trait TraitChangeOrderOfMethods { // Change mode of self parameter -------------------------------------------------- -// FIXME: this should work but doesn't yet. -// #[cfg(cfail1)] -// trait TraitChangeModeSelfRefToMut { -// fn method(&self); -// } - -// #[cfg(not(cfail1))] -// #[rustc_dirty(label="Hir", cfg="cfail2")] -// #[rustc_clean(label="Hir", cfg="cfail3")] -// #[rustc_metadata_dirty(cfg="cfail2")] -// #[rustc_metadata_clean(cfg="cfail3")] -// trait TraitChangeModeSelfRefToMut { -// fn method(&mut self); -// } - -// FIXME: this should work but doesn't yet. -// #[cfg(cfail1)] -// trait TraitChangeModeSelfOwnToMut { -// fn method(self); -// } - -// #[cfg(not(cfail1))] -// #[rustc_dirty(label="Hir", cfg="cfail2")] -// #[rustc_clean(label="Hir", cfg="cfail3")] -// #[rustc_metadata_dirty(cfg="cfail2")] -// #[rustc_metadata_clean(cfg="cfail3")] -// trait TraitChangeModeSelfOwnToMut { -// fn method(mut self); -// } +#[cfg(cfail1)] +trait TraitChangeModeSelfRefToMut { + fn method(&self); +} + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +trait TraitChangeModeSelfRefToMut { + fn method(&mut self); +} + + + +#[cfg(cfail1)] +trait TraitChangeModeSelfOwnToMut { + fn method(self); +} + +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +trait TraitChangeModeSelfOwnToMut { + fn method(mut self); +} @@ -298,56 +296,53 @@ trait TraitChangeModeSelfOwnToRef { // Add unsafe modifier to method -------------------------------------------------- -// FIXME: this should work but doesn't yet. -// #[cfg(cfail1)] -// trait TraitAddUnsafeModifier { -// fn method(); -// } +#[cfg(cfail1)] +trait TraitAddUnsafeModifier { + fn method(); +} -// #[cfg(not(cfail1))] -// #[rustc_dirty(label="Hir", cfg="cfail2")] -// #[rustc_clean(label="Hir", cfg="cfail3")] -// #[rustc_metadata_dirty(cfg="cfail2")] -// #[rustc_metadata_clean(cfg="cfail3")] -// trait TraitAddUnsafeModifier { -// unsafe fn method(); -// } +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +trait TraitAddUnsafeModifier { + unsafe fn method(); +} // Add extern modifier to method -------------------------------------------------- -// FIXME: this should work but doesn't yet. -// #[cfg(cfail1)] -// trait TraitAddExternModifier { -// fn method(); -// } +#[cfg(cfail1)] +trait TraitAddExternModifier { + fn method(); +} -// #[cfg(not(cfail1))] -// #[rustc_dirty(label="Hir", cfg="cfail2")] -// #[rustc_clean(label="Hir", cfg="cfail3")] -// #[rustc_metadata_dirty(cfg="cfail2")] -// #[rustc_metadata_clean(cfg="cfail3")] -// trait TraitAddExternModifier { -// extern fn method(); -// } +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +trait TraitAddExternModifier { + extern fn method(); +} // Change extern "C" to extern "rust-intrinsic" ----------------------------------- -// FIXME: this should work but doesn't yet. -// #[cfg(cfail1)] -// trait TraitChangeExternCToRustIntrinsic { -// extern "C" fn method(); -// } +#[cfg(cfail1)] +trait TraitChangeExternCToRustIntrinsic { + extern "C" fn method(); +} -// #[cfg(not(cfail1))] -// #[rustc_dirty(label="Hir", cfg="cfail2")] -// #[rustc_clean(label="Hir", cfg="cfail3")] -// #[rustc_metadata_dirty(cfg="cfail2")] -// #[rustc_metadata_clean(cfg="cfail3")] -// trait TraitChangeExternCToRustIntrinsic { -// extern "rust-intrinsic" fn method(); -// } +#[cfg(not(cfail1))] +#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_metadata_clean(cfg="cfail3")] +trait TraitChangeExternCToRustIntrinsic { + extern "rust-intrinsic" fn method(); +} @@ -1118,4 +1113,3 @@ mod change_method_type_parameter_bound_indirectly_where { fn method(a: T); } } - diff --git a/src/test/rustdoc/line-breaks.rs b/src/test/rustdoc/line-breaks.rs new file mode 100644 index 0000000000000..cc608a2447574 --- /dev/null +++ b/src/test/rustdoc/line-breaks.rs @@ -0,0 +1,21 @@ +// 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. + +#![crate_name = "foo"] + +//@count foo/fn.function_with_a_really_long_name.html //pre/br 2 +pub fn function_with_a_really_long_name(parameter_one: i32, + parameter_two: i32) + -> Option { + Some(parameter_one + parameter_two) +} + +//@count foo/fn.short_name.html //pre/br 0 +pub fn short_name(param: i32) -> i32 { param + 1 }