summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-02-07 17:51:52 +0000
committerbors <bors@rust-lang.org>2018-02-07 17:51:52 +0000
commit29c8276cee4a0eab7e0634ff25c6b47bd9f87c6c (patch)
treeaabb7278f081c3c90cea9e0337779739805408a9 /src
parentfee39ba8bd98f5b93c60de51336830fa7f0b9d97 (diff)
parent732c83007c9069c6dd33a5dc98e62337dca014bd (diff)
downloadrust-29c8276cee4a0eab7e0634ff25c6b47bd9f87c6c.tar.gz
Auto merge of #48053 - Manishearth:rollup, r=Manishearth
Rollup of 10 pull requests - Successful merges: #47613, #47631, #47810, #47883, #47922, #47944, #48014, #48018, #48020, #48028 - Failed merges:
Diffstat (limited to 'src')
-rw-r--r--src/libcore/fmt/mod.rs17
-rw-r--r--src/libcore/iter/iterator.rs9
-rw-r--r--src/libcore/iter/mod.rs3
-rw-r--r--src/libcore/iter/range.rs3
-rw-r--r--src/libcore/iter/sources.rs3
-rw-r--r--src/libcore/iter/traits.rs6
-rw-r--r--src/libcore/ops/arith.rs40
-rw-r--r--src/libcore/ops/bit.rs30
-rw-r--r--src/libcore/ptr.rs87
-rw-r--r--src/libcore/tests/iter.rs43
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/middle/liveness.rs63
-rw-r--r--src/librustc/session/config.rs45
-rw-r--r--src/librustc/session/mod.rs7
-rw-r--r--src/librustc/traits/error_reporting.rs34
-rw-r--r--src/librustc/traits/on_unimplemented.rs37
-rw-r--r--src/librustc/util/nodemap.rs4
-rw-r--r--src/librustc_binaryen/BinaryenWrapper.cpp34
-rw-r--r--src/librustc_binaryen/lib.rs22
-rw-r--r--src/librustc_mir/transform/promote_consts.rs19
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs45
-rw-r--r--src/librustc_trans/back/write.rs18
-rw-r--r--src/librustc_typeck/check/method/probe.rs18
-rw-r--r--src/librustc_typeck/check/mod.rs2
-rw-r--r--src/librustc_typeck/collect.rs36
-rw-r--r--src/librustc_typeck/diagnostics.rs49
-rw-r--r--src/librustdoc/html/static/main.js26
-rw-r--r--src/librustdoc/html/static/rustdoc.css31
-rw-r--r--src/librustdoc/html/static/themes/dark.css2
-rw-r--r--src/libstd/panic.rs2
-rw-r--r--src/libsyntax/parse/parser.rs31
-rw-r--r--src/test/codegen/repeat-trusted-len.rs23
-rw-r--r--src/test/compile-fail/const-eval-overflow-4b.rs2
-rw-r--r--src/test/compile-fail/dst-bad-assign-3.rs2
-rw-r--r--src/test/compile-fail/epoch-raw-pointer-method-2015.rs23
-rw-r--r--src/test/compile-fail/epoch-raw-pointer-method-2018.rs22
-rw-r--r--src/test/compile-fail/private-in-public-warn.rs2
-rw-r--r--src/test/compile-fail/rustc-args-required-const.rs36
-rw-r--r--src/test/compile-fail/ufcs-qpath-self-mismatch.rs2
-rw-r--r--src/test/ui/impl-trait/equality.rs2
-rw-r--r--src/test/ui/impl-trait/equality.stderr2
-rw-r--r--src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs34
-rw-r--r--src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr40
-rw-r--r--src/test/ui/mismatched_types/binops.rs8
-rw-r--r--src/test/ui/mismatched_types/binops.stderr16
-rw-r--r--src/test/ui/on-unimplemented/auxiliary/no_debug.rs14
-rw-r--r--src/test/ui/on-unimplemented/no-debug.rs27
-rw-r--r--src/test/ui/on-unimplemented/no-debug.stderr38
-rw-r--r--src/test/ui/param-bounds-ignored.rs33
-rw-r--r--src/test/ui/param-bounds-ignored.stderr18
-rw-r--r--src/test/ui/span/issue-24690.stderr3
-rw-r--r--src/test/ui/span/issue-42234-unknown-receiver-type.rs27
-rw-r--r--src/test/ui/span/issue-42234-unknown-receiver-type.stderr15
-rw-r--r--src/test/ui/span/multiline-span-simple.rs2
-rw-r--r--src/test/ui/span/multiline-span-simple.stderr4
-rw-r--r--src/test/ui/suggestions/for-c-in-str.stderr2
56 files changed, 983 insertions, 181 deletions
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 6c8a1c3062b..8ad5a9861a0 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -530,9 +530,12 @@ impl<'a> Display for Arguments<'a> {
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is \
- defined in your crate, add `#[derive(Debug)]` or \
- manually implement it"]
+#[rustc_on_unimplemented(
+ on(crate_local, label="`{Self}` cannot be formatted using `:?`; \
+ add `#[derive(Debug)]` or manually implement `{Debug}`"),
+ message="`{Self}` doesn't implement `{Debug}`",
+ label="`{Self}` cannot be formatted using `:?` because it doesn't implement `{Debug}`",
+)]
#[lang = "debug_trait"]
pub trait Debug {
/// Formats the value using the given formatter.
@@ -593,9 +596,11 @@ pub trait Debug {
///
/// println!("The origin is: {}", origin);
/// ```
-#[rustc_on_unimplemented = "`{Self}` cannot be formatted with the default \
- formatter; try using `:?` instead if you are using \
- a format string"]
+#[rustc_on_unimplemented(
+ message="`{Self}` doesn't implement `{Display}`",
+ label="`{Self}` cannot be formatted with the default formatter; \
+ try using `:?` instead if you are using a format string",
+)]
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Display {
/// Formats the value using the given formatter.
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index 35cd7441c66..296fb8733ba 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -28,8 +28,13 @@ fn _assert_is_object_safe(_: &Iterator<Item=()>) {}
/// [module-level documentation]: index.html
/// [impl]: index.html#implementing-iterator
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \
- `.iter()` or a similar method"]
+#[rustc_on_unimplemented(
+ on(
+ _Self="&str",
+ label="`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
+ ),
+ label="`{Self}` is not an iterator; maybe try calling `.iter()` or a similar method"
+)]
#[doc(spotlight)]
pub trait Iterator {
/// The type of the elements being iterated over.
diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index 7314fac282b..bf8367d85fd 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -2322,6 +2322,9 @@ impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}
#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Take<I> where I: FusedIterator {}
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<I: TrustedLen> TrustedLen for Take<I> {}
+
/// An iterator to maintain state while iterating another iterator.
///
/// This `struct` is created by the [`scan`] method on [`Iterator`]. See its
diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs
index 3b034efcce1..5b4dc9b2c9a 100644
--- a/src/libcore/iter/range.rs
+++ b/src/libcore/iter/range.rs
@@ -325,6 +325,9 @@ impl<A: Step> Iterator for ops::RangeFrom<A> {
#[unstable(feature = "fused", issue = "35602")]
impl<A: Step> FusedIterator for ops::RangeFrom<A> {}
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<A: Step> TrustedLen for ops::RangeFrom<A> {}
+
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<A: Step> Iterator for ops::RangeInclusive<A> {
type Item = A;
diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs
index b405f35d5e4..b05a893e661 100644
--- a/src/libcore/iter/sources.rs
+++ b/src/libcore/iter/sources.rs
@@ -44,6 +44,9 @@ impl<A: Clone> DoubleEndedIterator for Repeat<A> {
#[unstable(feature = "fused", issue = "35602")]
impl<A: Clone> FusedIterator for Repeat<A> {}
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<A: Clone> TrustedLen for Repeat<A> {}
+
/// Creates a new iterator that endlessly repeats a single element.
///
/// The `repeat()` function repeats a single value over and over and over and
diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs
index 11e668d228c..be4889f2487 100644
--- a/src/libcore/iter/traits.rs
+++ b/src/libcore/iter/traits.rs
@@ -970,9 +970,11 @@ impl<'a, I: FusedIterator + ?Sized> FusedIterator for &'a mut I {}
/// The iterator reports a size hint where it is either exact
/// (lower bound is equal to upper bound), or the upper bound is [`None`].
/// The upper bound must only be [`None`] if the actual iterator length is
-/// larger than [`usize::MAX`].
+/// larger than [`usize::MAX`]. In that case, the lower bound must be
+/// [`usize::MAX`], resulting in a [`.size_hint`] of `(usize::MAX, None)`.
///
-/// The iterator must produce exactly the number of elements it reported.
+/// The iterator must produce exactly the number of elements it reported
+/// or diverge before reaching the end.
///
/// # Safety
///
diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs
index 8b3d662a6db..d0d0c09869e 100644
--- a/src/libcore/ops/arith.rs
+++ b/src/libcore/ops/arith.rs
@@ -75,7 +75,18 @@
/// ```
#[lang = "add"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} + {RHS}`"]
+#[rustc_on_unimplemented(
+ on(
+ all(_Self="{integer}", RHS="{float}"),
+ message="cannot add a float to an integer",
+ ),
+ on(
+ all(_Self="{float}", RHS="{integer}"),
+ message="cannot add an integer to a float",
+ ),
+ message="cannot add `{RHS}` to `{Self}`",
+ label="no implementation for `{Self} + {RHS}`",
+)]
pub trait Add<RHS=Self> {
/// The resulting type after applying the `+` operator.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -170,7 +181,8 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
/// ```
#[lang = "sub"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} - {RHS}`"]
+#[rustc_on_unimplemented(message="cannot substract `{RHS}` from `{Self}`",
+ label="no implementation for `{Self} - {RHS}`")]
pub trait Sub<RHS=Self> {
/// The resulting type after applying the `-` operator.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -287,7 +299,8 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
/// ```
#[lang = "mul"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} * {RHS}`"]
+#[rustc_on_unimplemented(message="cannot multiply `{RHS}` to `{Self}`",
+ label="no implementation for `{Self} * {RHS}`")]
pub trait Mul<RHS=Self> {
/// The resulting type after applying the `*` operator.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -408,7 +421,8 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
/// ```
#[lang = "div"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} / {RHS}`"]
+#[rustc_on_unimplemented(message="cannot divide `{Self}` by `{RHS}`",
+ label="no implementation for `{Self} / {RHS}`")]
pub trait Div<RHS=Self> {
/// The resulting type after applying the `/` operator.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -490,7 +504,8 @@ div_impl_float! { f32 f64 }
/// ```
#[lang = "rem"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} % {RHS}`"]
+#[rustc_on_unimplemented(message="cannot mod `{Self}` by `{RHS}`",
+ label="no implementation for `{Self} % {RHS}`")]
pub trait Rem<RHS=Self> {
/// The resulting type after applying the `%` operator.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -647,7 +662,8 @@ neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 }
/// ```
#[lang = "add_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} += {Rhs}`"]
+#[rustc_on_unimplemented(message="cannot add-assign `{Rhs}` to `{Self}`",
+ label="no implementation for `{Self} += {Rhs}`")]
pub trait AddAssign<Rhs=Self> {
/// Performs the `+=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -700,7 +716,8 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
/// ```
#[lang = "sub_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} -= {Rhs}`"]
+#[rustc_on_unimplemented(message="cannot substract-assign `{Rhs}` from `{Self}`",
+ label="no implementation for `{Self} -= {Rhs}`")]
pub trait SubAssign<Rhs=Self> {
/// Performs the `-=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -744,7 +761,8 @@ sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
/// ```
#[lang = "mul_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} *= {Rhs}`"]
+#[rustc_on_unimplemented(message="cannot multiply-assign `{Rhs}` to `{Self}`",
+ label="no implementation for `{Self} *= {Rhs}`")]
pub trait MulAssign<Rhs=Self> {
/// Performs the `*=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -788,7 +806,8 @@ mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
/// ```
#[lang = "div_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} /= {Rhs}`"]
+#[rustc_on_unimplemented(message="cannot divide-assign `{Self}` by `{Rhs}`",
+ label="no implementation for `{Self} /= {Rhs}`")]
pub trait DivAssign<Rhs=Self> {
/// Performs the `/=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -835,7 +854,8 @@ div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
/// ```
#[lang = "rem_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} %= {Rhs}`"]
+#[rustc_on_unimplemented(message="cannot mod-assign `{Self}` by `{Rhs}``",
+ label="no implementation for `{Self} %= {Rhs}`")]
pub trait RemAssign<Rhs=Self> {
/// Performs the `%=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
diff --git a/src/libcore/ops/bit.rs b/src/libcore/ops/bit.rs
index 7ac5fc4debf..a0ecd6cf75c 100644
--- a/src/libcore/ops/bit.rs
+++ b/src/libcore/ops/bit.rs
@@ -120,7 +120,8 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
/// ```
#[lang = "bitand"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} & {RHS}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} & {RHS}`",
+ label="no implementation for `{Self} & {RHS}`")]
pub trait BitAnd<RHS=Self> {
/// The resulting type after applying the `&` operator.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -201,7 +202,8 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
/// ```
#[lang = "bitor"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} | {RHS}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} | {RHS}`",
+ label="no implementation for `{Self} | {RHS}`")]
pub trait BitOr<RHS=Self> {
/// The resulting type after applying the `|` operator.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -285,7 +287,8 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
/// ```
#[lang = "bitxor"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} ^ {RHS}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} ^ {RHS}`",
+ label="no implementation for `{Self} ^ {RHS}`")]
pub trait BitXor<RHS=Self> {
/// The resulting type after applying the `^` operator.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -365,7 +368,8 @@ bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
/// ```
#[lang = "shl"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} << {RHS}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} << {RHS}`",
+ label="no implementation for `{Self} << {RHS}`")]
pub trait Shl<RHS> {
/// The resulting type after applying the `<<` operator.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -466,7 +470,8 @@ shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 }
/// ```
#[lang = "shr"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} >> {RHS}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} >> {RHS}`",
+ label="no implementation for `{Self} >> {RHS}`")]
pub trait Shr<RHS> {
/// The resulting type after applying the `>>` operator.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -579,7 +584,8 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
/// ```
#[lang = "bitand_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} &= {Rhs}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} &= {Rhs}`",
+ label="no implementation for `{Self} &= {Rhs}`")]
pub trait BitAndAssign<Rhs=Self> {
/// Performs the `&=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -626,7 +632,8 @@ bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
/// ```
#[lang = "bitor_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} |= {Rhs}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} |= {Rhs}`",
+ label="no implementation for `{Self} |= {Rhs}`")]
pub trait BitOrAssign<Rhs=Self> {
/// Performs the `|=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -673,7 +680,8 @@ bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
/// ```
#[lang = "bitxor_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} ^= {Rhs}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} ^= {Rhs}`",
+ label="no implementation for `{Self} ^= {Rhs}`")]
pub trait BitXorAssign<Rhs=Self> {
/// Performs the `^=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -718,7 +726,8 @@ bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
/// ```
#[lang = "shl_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} <<= {Rhs}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} <<= {Rhs}`",
+ label="no implementation for `{Self} <<= {Rhs}`")]
pub trait ShlAssign<Rhs> {
/// Performs the `<<=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -784,7 +793,8 @@ shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
/// ```
#[lang = "shr_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
-#[rustc_on_unimplemented = "no implementation for `{Self} >>= {Rhs}`"]
+#[rustc_on_unimplemented(message="no implementation for `{Self} >>= {Rhs}`",
+ label="no implementation for `{Self} >>= {Rhs}`")]
pub trait ShrAssign<Rhs=Self> {
/// Performs the `>>=` operation.
#[stable(feature = "op_assign_traits", since = "1.8.0")]
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index fab5832d905..3d84e910fe6 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -2461,7 +2461,7 @@ impl<'a, T: ?Sized> From<NonNull<T>> for Unique<T> {
}
/// Previous name of `NonNull`.
-#[rustc_deprecated(since = "1.24", reason = "renamed to `NonNull`")]
+#[rustc_deprecated(since = "1.25.0", reason = "renamed to `NonNull`")]
#[unstable(feature = "shared", issue = "27730")]
pub type Shared<T> = NonNull<T>;
@@ -2482,26 +2482,19 @@ pub type Shared<T> = NonNull<T>;
/// Usually this won't be necessary; covariance is correct for most safe abstractions,
/// such as Box, Rc, Arc, Vec, and LinkedList. This is the case because they
/// provide a public API that follows the normal shared XOR mutable rules of Rust.
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
pub struct NonNull<T: ?Sized> {
pointer: NonZero<*const T>,
}
-#[stable(feature = "nonnull", since = "1.24.0")]
-impl<T: ?Sized> fmt::Debug for NonNull<T> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Pointer::fmt(&self.as_ptr(), f)
- }
-}
-
/// `NonNull` pointers are not `Send` because the data they reference may be aliased.
// NB: This impl is unnecessary, but should provide better error messages.
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
impl<T: ?Sized> !Send for NonNull<T> { }
/// `NonNull` pointers are not `Sync` because the data they reference may be aliased.
// NB: This impl is unnecessary, but should provide better error messages.
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
impl<T: ?Sized> !Sync for NonNull<T> { }
impl<T: Sized> NonNull<T> {
@@ -2509,7 +2502,7 @@ impl<T: Sized> NonNull<T> {
///
/// This is useful for initializing types which lazily allocate, like
/// `Vec::new` does.
- #[stable(feature = "nonnull", since = "1.24.0")]
+ #[stable(feature = "nonnull", since = "1.25.0")]
pub fn dangling() -> Self {
unsafe {
let ptr = mem::align_of::<T>() as *mut T;
@@ -2524,19 +2517,19 @@ impl<T: ?Sized> NonNull<T> {
/// # Safety
///
/// `ptr` must be non-null.
- #[stable(feature = "nonnull", since = "1.24.0")]
+ #[stable(feature = "nonnull", since = "1.25.0")]
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
NonNull { pointer: NonZero::new_unchecked(ptr) }
}
/// Creates a new `NonNull` if `ptr` is non-null.
- #[stable(feature = "nonnull", since = "1.24.0")]
+ #[stable(feature = "nonnull", since = "1.25.0")]
pub fn new(ptr: *mut T) -> Option<Self> {
NonZero::new(ptr as *const T).map(|nz| NonNull { pointer: nz })
}
/// Acquires the underlying `*mut` pointer.
- #[stable(feature = "nonnull", since = "1.24.0")]
+ #[stable(feature = "nonnull", since = "1.25.0")]
pub fn as_ptr(self) -> *mut T {
self.pointer.get() as *mut T
}
@@ -2546,7 +2539,7 @@ impl<T: ?Sized> NonNull<T> {
/// The resulting lifetime is bound to self so this behaves "as if"
/// it were actually an instance of T that is getting borrowed. If a longer
/// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
- #[stable(feature = "nonnull", since = "1.24.0")]
+ #[stable(feature = "nonnull", since = "1.25.0")]
pub unsafe fn as_ref(&self) -> &T {
&*self.as_ptr()
}
@@ -2556,47 +2549,93 @@ impl<T: ?Sized> NonNull<T> {
/// The resulting lifetime is bound to self so this behaves "as if"
/// it were actually an instance of T that is getting borrowed. If a longer
/// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
- #[stable(feature = "nonnull", since = "1.24.0")]
+ #[stable(feature = "nonnull", since = "1.25.0")]
pub unsafe fn as_mut(&mut self) -> &mut T {
&mut *self.as_ptr()
}
+
+ /// Cast to a pointer of another type
+ #[unstable(feature = "nonnull_cast", issue = "47653")]
+ pub fn cast<U>(self) -> NonNull<U> {
+ unsafe {
+ NonNull::new_unchecked(self.as_ptr() as *mut U)
+ }
+ }
}
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
impl<T: ?Sized> Clone for NonNull<T> {
fn clone(&self) -> Self {
*self
}
}
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
impl<T: ?Sized> Copy for NonNull<T> { }
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> { }
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> fmt::Debug for NonNull<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Pointer::fmt(&self.as_ptr(), f)
+ }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
impl<T: ?Sized> fmt::Pointer for NonNull<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Pointer::fmt(&self.as_ptr(), f)
}
}
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> Eq for NonNull<T> {}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> PartialEq for NonNull<T> {
+ fn eq(&self, other: &Self) -> bool {
+ self.as_ptr() == other.as_ptr()
+ }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> Ord for NonNull<T> {
+ fn cmp(&self, other: &Self) -> Ordering {
+ self.as_ptr().cmp(&other.as_ptr())
+ }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> PartialOrd for NonNull<T> {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ self.as_ptr().partial_cmp(&other.as_ptr())
+ }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> hash::Hash for NonNull<T> {
+ fn hash<H: hash::Hasher>(&self, state: &mut H) {
+ self.as_ptr().hash(state)
+ }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
fn from(unique: Unique<T>) -> Self {
NonNull { pointer: unique.pointer }
}
}
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> {
fn from(reference: &'a mut T) -> Self {
NonNull { pointer: NonZero::from(reference) }
}
}
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
impl<'a, T: ?Sized> From<&'a T> for NonNull<T> {
fn from(reference: &'a T) -> Self {
NonNull { pointer: NonZero::from(reference) }
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index dc866d180bf..0373c8922b2 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -1371,6 +1371,29 @@ fn test_range_from_nth() {
assert_eq!(r, 16..);
assert_eq!(r.nth(10), Some(26));
assert_eq!(r, 27..);
+
+ assert_eq!((0..).size_hint(), (usize::MAX, None));
+}
+
+fn is_trusted_len<I: TrustedLen>(_: I) {}
+
+#[test]
+fn test_range_from_take() {
+ let mut it = (0..).take(3);
+ assert_eq!(it.next(), Some(0));
+ assert_eq!(it.next(), Some(1));
+ assert_eq!(it.next(), Some(2));
+ assert_eq!(it.next(), None);
+ is_trusted_len((0..).take(3));
+ assert_eq!((0..).take(3).size_hint(), (3, Some(3)));
+ assert_eq!((0..).take(0).size_hint(), (0, Some(0)));
+ assert_eq!((0..).take(usize::MAX).size_hint(), (usize::MAX, Some(usize::MAX)));
+}
+
+#[test]
+fn test_range_from_take_collect() {
+ let v: Vec<_> = (0..).take(3).collect();
+ assert_eq!(v, vec![0, 1, 2]);
}
#[test]
@@ -1485,6 +1508,26 @@ fn test_repeat() {
assert_eq!(it.next(), Some(42));
assert_eq!(it.next(), Some(42));
assert_eq!(it.next(), Some(42));
+ assert_eq!(repeat(42).size_hint(), (usize::MAX, None));
+}
+
+#[test]
+fn test_repeat_take() {
+ let mut it = repeat(42).take(3);
+ assert_eq!(it.next(), Some(42));
+ assert_eq!(it.next(), Some(42));
+ assert_eq!(it.next(), Some(42));
+ assert_eq!(it.next(), None);
+ is_trusted_len(repeat(42).take(3));
+ assert_eq!(repeat(42).take(3).size_hint(), (3, Some(3)));
+ assert_eq!(repeat(42).take(0).size_hint(), (0, Some(0)));
+ assert_eq!(repeat(42).take(usize::MAX).size_hint(), (usize::MAX, Some(usize::MAX)));
+}
+
+#[test]
+fn test_repeat_take_collect() {
+ let v: Vec<_> = repeat(42).take(3).collect();
+ assert_eq!(v, vec![42, 42, 42]);
}
#[test]
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index db6863d6dad..a7a26195059 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -58,6 +58,7 @@
#![feature(macro_vis_matcher)]
#![feature(match_default_bindings)]
#![feature(never_type)]
+#![feature(non_exhaustive)]
#![feature(nonzero)]
#![feature(quote)]
#![feature(refcell_replace_swap)]
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 297586f140e..10497c95e27 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -109,7 +109,7 @@ use self::VarKind::*;
use hir::def::*;
use ty::{self, TyCtxt};
use lint;
-use util::nodemap::NodeMap;
+use util::nodemap::{NodeMap, NodeSet};
use std::{fmt, usize};
use std::io::prelude::*;
@@ -244,7 +244,8 @@ struct CaptureInfo {
#[derive(Copy, Clone, Debug)]
struct LocalInfo {
id: NodeId,
- name: ast::Name
+ name: ast::Name,
+ is_shorthand: bool,
}
#[derive(Copy, Clone, Debug)]
@@ -333,6 +334,13 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
}
}
+ fn variable_is_shorthand(&self, var: Variable) -> bool {
+ match self.var_kinds[var.get()] {
+ Local(LocalInfo { is_shorthand, .. }) => is_shorthand,
+ Arg(..) | CleanExit => false
+ }
+ }
+
fn set_captures(&mut self, node_id: NodeId, cs: Vec<CaptureInfo>) {
self.capture_info_map.insert(node_id, Rc::new(cs));
}
@@ -384,8 +392,9 @@ fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
let name = path1.node;
ir.add_live_node_for_node(p_id, VarDefNode(sp));
ir.add_variable(Local(LocalInfo {
- id: p_id,
- name,
+ id: p_id,
+ name,
+ is_shorthand: false,
}));
});
intravisit::walk_local(ir, local);
@@ -393,6 +402,22 @@ fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
for pat in &arm.pats {
+ // for struct patterns, take note of which fields used shorthand (`x`
+ // rather than `x: x`)
+ //
+ // FIXME: according to the rust-lang-nursery/rustc-guide book and
+ // librustc/README.md, `NodeId`s are to be phased out in favor of
+ // `HirId`s; however, we need to match the signature of `each_binding`,
+ // which uses `NodeIds`.
+ let mut shorthand_field_ids = NodeSet();
+ if let hir::PatKind::Struct(_, ref fields, _) = pat.node {
+ for field in fields {
+ if field.node.is_shorthand {
+ shorthand_field_ids.insert(field.node.pat.id);
+ }
+ }
+ }
+
pat.each_binding(|bm, p_id, sp, path1| {
debug!("adding local variable {} from match with bm {:?}",
p_id, bm);
@@ -400,7 +425,8 @@ fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
ir.add_live_node_for_node(p_id, VarDefNode(sp));
ir.add_variable(Local(LocalInfo {
id: p_id,
- name,
+ name: name,
+ is_shorthand: shorthand_field_ids.contains(&p_id)
}));
})
}
@@ -1483,17 +1509,26 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.assigned_on_exit(ln, var).is_some()
};
+ let suggest_underscore_msg = format!("consider using `_{}` instead",
+ name);
if is_assigned {
- self.ir.tcx.lint_node_note(lint::builtin::UNUSED_VARIABLES, id, sp,
- &format!("variable `{}` is assigned to, but never used",
- name),
- &format!("to avoid this warning, consider using `_{}` instead",
- name));
+ self.ir.tcx
+ .lint_node_note(lint::builtin::UNUSED_VARIABLES, id, sp,
+ &format!("variable `{}` is assigned to, but never used",
+ name),
+ &suggest_underscore_msg);
} else if name != "self" {
- self.ir.tcx.lint_node_note(lint::builtin::UNUSED_VARIABLES, id, sp,
- &format!("unused variable: `{}`", name),
- &format!("to avoid this warning, consider using `_{}` instead",
- name));
+ let msg = format!("unused variable: `{}`", name);
+ let mut err = self.ir.tcx
+ .struct_span_lint_node(lint::builtin::UNUSED_VARIABLES, id, sp, &msg);
+ if self.ir.variable_is_shorthand(var) {
+ err.span_suggestion(sp, "try ignoring the field",
+ format!("{}: _", name));
+ } else {
+ err.span_suggestion_short(sp, &suggest_underscore_msg,
+ format!("_{}", name));
+ }
+ err.emit()
}
}
true
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index c56575f432d..8b9a08dda87 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -112,6 +112,31 @@ pub enum OutputType {
DepInfo,
}
+/// The epoch of the compiler (RFC 2052)
+#[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq)]
+#[non_exhaustive]
+pub enum Epoch {
+ // epochs must be kept in order, newest to oldest
+
+ /// The 2015 epoch
+ Epoch2015,
+ /// The 2018 epoch
+ Epoch2018,
+
+ // when adding new epochs, be sure to update:
+ //
+ // - the list in the `parse_epoch` static
+ // - the match in the `parse_epoch` function
+ // - add a `rust_####()` function to the session
+ // - update the enum in Cargo's sources as well
+ //
+ // When -Zepoch becomes --epoch, there will
+ // also be a check for the epoch being nightly-only
+ // somewhere. That will need to be updated
+ // whenever we're stabilizing/introducing a new epoch
+ // as well as changing the default Cargo template.
+}
+
impl_stable_hash_for!(enum self::OutputType {
Bitcode,
Assembly,
@@ -783,11 +808,13 @@ macro_rules! options {
Some("`string` or `string=string`");
pub const parse_lto: Option<&'static str> =
Some("one of `thin`, `fat`, or omitted");
+ pub const parse_epoch: Option<&'static str> =
+ Some("one of: `2015`, `2018`");
}
#[allow(dead_code)]
mod $mod_set {
- use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto};
+ use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto, Epoch};
use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel};
use std::path::PathBuf;
@@ -991,6 +1018,15 @@ macro_rules! options {
};
true
}
+
+ fn parse_epoch(slot: &mut Epoch, v: Option<&str>) -> bool {
+ match v {
+ Some("2015") => *slot = Epoch::Epoch2015,
+ Some("2018") => *slot = Epoch::Epoch2018,
+ _ => return false,
+ }
+ true
+ }
}
) }
@@ -1278,6 +1314,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
`everybody_loops` (all function bodies replaced with `loop {}`),
`hir` (the HIR), `hir,identified`, or
`hir,typed` (HIR with types for each node)."),
+ epoch: Epoch = (Epoch::Epoch2015, parse_epoch, [TRACKED],
+ "The epoch to build Rust with. Newer epochs may include features
+ that require breaking changes. The default epoch is 2015 (the first
+ epoch). Crates compiled with different epochs can be linked together."),
}
pub fn default_lib_output() -> CrateType {
@@ -2069,7 +2109,7 @@ mod dep_tracking {
use std::path::PathBuf;
use std::collections::hash_map::DefaultHasher;
use super::{Passes, CrateType, OptLevel, DebugInfoLevel, Lto,
- OutputTypes, Externs, ErrorOutputType, Sanitizer};
+ OutputTypes, Externs, ErrorOutputType, Sanitizer, Epoch};
use syntax::feature_gate::UnstableFeatures;
use rustc_back::{PanicStrategy, RelroLevel};
@@ -2131,6 +2171,7 @@ mod dep_tracking {
impl_dep_tracking_hash_via_hash!(cstore::NativeLibraryKind);
impl_dep_tracking_hash_via_hash!(Sanitizer);
impl_dep_tracking_hash_via_hash!(Option<Sanitizer>);
+ impl_dep_tracking_hash_via_hash!(Epoch);
impl_dep_tracking_hash_for_sortable_vec_of!(String);
impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index f4a00a43d8d..9d7a9acc3d5 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -19,7 +19,7 @@ use lint;
use middle::allocator::AllocatorKind;
use middle::dependency_format;
use session::search_paths::PathKind;
-use session::config::{BorrowckMode, DebugInfoLevel, OutputType};
+use session::config::{BorrowckMode, DebugInfoLevel, OutputType, Epoch};
use ty::tls;
use util::nodemap::{FxHashMap, FxHashSet};
use util::common::{duration_to_secs_str, ErrorReported};
@@ -864,6 +864,11 @@ impl Session {
pub fn teach(&self, code: &DiagnosticId) -> bool {
self.opts.debugging_opts.teach && !self.parse_sess.span_diagnostic.code_emitted(code)
}
+
+ /// Are we allowed to use features from the Rust 2018 epoch?
+ pub fn rust_2018(&self) -> bool {
+ self.opts.debugging_opts.epoch >= Epoch::Epoch2018
+ }
}
pub fn build_session(sopts: config::Options,
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 7b86791026b..d4bcf00be80 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -348,7 +348,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
if direct {
// this is a "direct", user-specified, rather than derived,
// obligation.
- flags.push(("direct", None));
+ flags.push(("direct".to_string(), None));
}
if let ObligationCauseCode::ItemObligation(item) = obligation.cause.code {
@@ -359,21 +359,37 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// Currently I'm leaving it for what I need for `try`.
if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) {
method = self.tcx.item_name(item);
- flags.push(("from_method", None));
- flags.push(("from_method", Some(&*method)));
+ flags.push(("from_method".to_string(), None));
+ flags.push(("from_method".to_string(), Some(method.to_string())));
}
}
if let Some(k) = obligation.cause.span.compiler_desugaring_kind() {
desugaring = k.as_symbol().as_str();
- flags.push(("from_desugaring", None));
- flags.push(("from_desugaring", Some(&*desugaring)));
+ flags.push(("from_desugaring".to_string(), None));
+ flags.push(("from_desugaring".to_string(), Some(desugaring.to_string())));
+ }
+ let generics = self.tcx.generics_of(def_id);
+ let self_ty = trait_ref.self_ty();
+ let self_ty_str = self_ty.to_string();
+ flags.push(("_Self".to_string(), Some(self_ty_str.clone())));
+
+ for param in generics.types.iter() {
+ let name = param.name.as_str().to_string();
+ let ty = trait_ref.substs.type_for_def(param);
+ let ty_str = ty.to_string();
+ flags.push((name.clone(),
+ Some(ty_str.clone())));
+ }
+
+ if let Some(true) = self_ty.ty_to_def_id().map(|def_id| def_id.is_local()) {
+ flags.push(("crate_local".to_string(), None));
}
if let Ok(Some(command)) = OnUnimplementedDirective::of_item(
self.tcx, trait_ref.def_id, def_id
) {
- command.evaluate(self.tcx, trait_ref, &flags)
+ command.evaluate(self.tcx, trait_ref, &flags[..])
} else {
OnUnimplementedNote::empty()
}
@@ -549,7 +565,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
.map(|t| (format!(" in `{}`", t), format!("within `{}`, ", t)))
.unwrap_or((String::new(), String::new()));
- let OnUnimplementedNote { message, label }
+ let OnUnimplementedNote { message, label, note }
= self.on_unimplemented_note(trait_ref, obligation);
let have_alt_message = message.is_some() || label.is_some();
@@ -578,6 +594,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
trait_ref,
trait_ref.self_ty()));
}
+ if let Some(ref s) = note {
+ // If it has a custom "#[rustc_on_unimplemented]" note, let's display it
+ err.note(s.as_str());
+ }
self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err);
diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs
index 757b078086d..8c2c1cfa454 100644
--- a/src/librustc/traits/on_unimplemented.rs
+++ b/src/librustc/traits/on_unimplemented.rs
@@ -29,16 +29,18 @@ pub struct OnUnimplementedDirective {
pub subcommands: Vec<OnUnimplementedDirective>,
pub message: Option<OnUnimplementedFormatString>,
pub label: Option<OnUnimplementedFormatString>,
+ pub note: Option<OnUnimplementedFormatString>,
}
pub struct OnUnimplementedNote {
pub message: Option<String>,
pub label: Option<String>,
+ pub note: Option<String>,
}
impl OnUnimplementedNote {
pub fn empty() -> Self {
- OnUnimplementedNote { message: None, label: None }
+ OnUnimplementedNote { message: None, label: None, note: None }
}
}
@@ -89,6 +91,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
let mut message = None;
let mut label = None;
+ let mut note = None;
let mut subcommands = vec![];
for item in item_iter {
if item.check_name("message") && message.is_none() {
@@ -103,8 +106,14 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
tcx, trait_def_id, label_.as_str(), span)?);
continue;
}
+ } else if item.check_name("note") && note.is_none() {
+ if let Some(note_) = item.value_str() {
+ note = Some(OnUnimplementedFormatString::try_parse(
+ tcx, trait_def_id, note_.as_str(), span)?);
+ continue;
+ }
} else if item.check_name("on") && is_root &&
- message.is_none() && label.is_none()
+ message.is_none() && label.is_none() && note.is_none()
{
if let Some(items) = item.meta_item_list() {
if let Ok(subcommand) =
@@ -128,7 +137,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
if errored {
Err(ErrorReported)
} else {
- Ok(OnUnimplementedDirective { condition, message, label, subcommands })
+ Ok(OnUnimplementedDirective { condition, message, label, subcommands, note })
}
}
@@ -154,7 +163,8 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
message: None,
subcommands: vec![],
label: Some(OnUnimplementedFormatString::try_parse(
- tcx, trait_def_id, value.as_str(), attr.span)?)
+ tcx, trait_def_id, value.as_str(), attr.span)?),
+ note: None,
}))
} else {
return Err(parse_error(tcx, attr.span,
@@ -169,20 +179,20 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
pub fn evaluate(&self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
trait_ref: ty::TraitRef<'tcx>,
- options: &[(&str, Option<&str>)])
+ options: &[(String, Option<String>)])
-> OnUnimplementedNote
{
let mut message = None;
let mut label = None;
- info!("evaluate({:?}, trait_ref={:?}, options={:?})",
- self, trait_ref, options);
+ let mut note = None;
+ info!("evaluate({:?}, trait_ref={:?}, options={:?})", self, trait_ref, options);
for command in self.subcommands.iter().chain(Some(self)).rev() {
if let Some(ref condition) = command.condition {
if !attr::eval_condition(condition, &tcx.sess.parse_sess, &mut |c| {
- options.contains(&(&c.name().as_str(),
- match c.value_str().map(|s| s.as_str()) {
- Some(ref s) => Some(s),
+ options.contains(&(c.name().as_str().to_string(),
+ match c.value_str().map(|s| s.as_str().to_string()) {
+ Some(s) => Some(s),
None => None
}))
}) {
@@ -198,11 +208,16 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
if let Some(ref label_) = command.label {
label = Some(label_.clone());
}
+
+ if let Some(ref note_) = command.note {
+ note = Some(note_.clone());
+ }
}
OnUnimplementedNote {
label: label.map(|l| l.format(tcx, trait_ref)),
- message: message.map(|m| m.format(tcx, trait_ref))
+ message: message.map(|m| m.format(tcx, trait_ref)),
+ note: note.map(|n| n.format(tcx, trait_ref)),
}
}
}
diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs
index 674f67d5cd2..f98a8f834df 100644
--- a/src/librustc/util/nodemap.rs
+++ b/src/librustc/util/nodemap.rs
@@ -13,7 +13,7 @@
#![allow(non_snake_case)]
use hir::def_id::DefId;
-use hir::ItemLocalId;
+use hir::{HirId, ItemLocalId};
use syntax::ast;
pub use rustc_data_structures::fx::FxHashMap;
@@ -21,10 +21,12 @@ pub use rustc_data_structures::fx::FxHashSet;
pub type NodeMap<T> = FxHashMap<ast::NodeId, T>;
pub type DefIdMap<T> = FxHashMap<DefId, T>;
+pub type HirIdMap<T> = FxHashMap<HirId, T>;
pub type ItemLocalMap<T> = FxHashMap<ItemLocalId, T>;
pub type NodeSet = FxHashSet<ast::NodeId>;
pub type DefIdSet = FxHashSet<DefId>;
+pub type HirIdSet = FxHashSet<HirId>;
pub type ItemLocalSet = FxHashSet<ItemLocalId>;
pub fn NodeMap<T>() -> NodeMap<T> { FxHashMap() }
diff --git a/src/librustc_binaryen/BinaryenWrapper.cpp b/src/librustc_binaryen/BinaryenWrapper.cpp
index d1095a7819d..55f11665f6d 100644
--- a/src/librustc_binaryen/BinaryenWrapper.cpp
+++ b/src/librustc_binaryen/BinaryenWrapper.cpp
@@ -14,6 +14,7 @@
#include <stdint.h>
#include <string>
+#include <sstream>
#include <stdlib.h>
#include "s2wasm.h"
@@ -24,6 +25,7 @@ using namespace wasm;
struct BinaryenRustModule {
BufferWithRandomAccess buffer;
+ std::string sourceMapJSON;
};
struct BinaryenRustModuleOptions {
@@ -36,6 +38,7 @@ struct BinaryenRustModuleOptions {
bool ignoreUnknownSymbols;
bool debugInfo;
std::string startFunction;
+ std::string sourceMapUrl;
BinaryenRustModuleOptions() :
globalBase(0),
@@ -46,7 +49,8 @@ struct BinaryenRustModuleOptions {
importMemory(false),
ignoreUnknownSymbols(false),
debugInfo(false),
- startFunction("")
+ startFunction(""),
+ sourceMapUrl("")
{}
};
@@ -74,6 +78,12 @@ BinaryenRustModuleOptionsSetStart(BinaryenRustModuleOptions *options,
}
extern "C" void
+BinaryenRustModuleOptionsSetSourceMapUrl(BinaryenRustModuleOptions *options,
+ char *sourceMapUrl) {
+ options->sourceMapUrl = sourceMapUrl;
+}
+
+extern "C" void
BinaryenRustModuleOptionsSetStackAllocation(BinaryenRustModuleOptions *options,
uint64_t stack) {
options->stackAllocation = stack;
@@ -106,12 +116,20 @@ BinaryenRustModuleCreate(const BinaryenRustModuleOptions *options,
{
WasmBinaryWriter writer(&linker.getOutput().wasm, ret->buffer, options->debug);
writer.setNamesSection(options->debugInfo);
- // FIXME: support source maps?
- // writer.setSourceMap(sourceMapStream.get(), sourceMapUrl);
+
+ std::unique_ptr<std::ostringstream> sourceMapStream = nullptr;
+ {
+ sourceMapStream = make_unique<std::ostringstream>();
+ writer.setSourceMap(sourceMapStream.get(), options->sourceMapUrl);
+ }
// FIXME: support symbol maps?
// writer.setSymbolMap(symbolMap);
writer.write();
+
+ if (sourceMapStream) {
+ ret->sourceMapJSON = sourceMapStream->str();
+ }
}
return ret.release();
}
@@ -126,6 +144,16 @@ BinaryenRustModuleLen(const BinaryenRustModule *M) {
return M->buffer.size();
}
+extern "C" const char*
+BinaryenRustModuleSourceMapPtr(const BinaryenRustModule *M) {
+ return M->sourceMapJSON.data();
+}
+
+extern "C" size_t
+BinaryenRustModuleSourceMapLen(const BinaryenRustModule *M) {
+ return M->sourceMapJSON.length();
+}
+
extern "C" void
BinaryenRustModuleFree(BinaryenRustModule *M) {
delete M;
diff --git a/src/librustc_binaryen/lib.rs b/src/librustc_binaryen/lib.rs
index 6c7feb6a7a9..36174e11ba0 100644
--- a/src/librustc_binaryen/lib.rs
+++ b/src/librustc_binaryen/lib.rs
@@ -51,6 +51,15 @@ impl Module {
slice::from_raw_parts(ptr, len)
}
}
+
+ /// Returns the data of the source map JSON.
+ pub fn source_map(&self) -> &[u8] {
+ unsafe {
+ let ptr = BinaryenRustModuleSourceMapPtr(self.ptr);
+ let len = BinaryenRustModuleSourceMapLen(self.ptr);
+ slice::from_raw_parts(ptr, len)
+ }
+ }
}
impl Drop for Module {
@@ -94,6 +103,15 @@ impl ModuleOptions {
self
}
+ /// Configures a `sourceMappingURL` custom section value for the module.
+ pub fn source_map_url(&mut self, url: &str) -> &mut Self {
+ let url = CString::new(url).unwrap();
+ unsafe {
+ BinaryenRustModuleOptionsSetSourceMapUrl(self.ptr, url.as_ptr());
+ }
+ self
+ }
+
/// Configures how much stack is initially allocated for the module. 1MB is
/// probably good enough for now.
pub fn stack(&mut self, amt: u64) -> &mut Self {
@@ -130,6 +148,8 @@ extern {
-> *mut BinaryenRustModule;
fn BinaryenRustModulePtr(module: *const BinaryenRustModule) -> *const u8;
fn BinaryenRustModuleLen(module: *const BinaryenRustModule) -> usize;
+ fn BinaryenRustModuleSourceMapPtr(module: *const BinaryenRustModule) -> *const u8;
+ fn BinaryenRustModuleSourceMapLen(module: *const BinaryenRustModule) -> usize;
fn BinaryenRustModuleFree(module: *mut BinaryenRustModule);
fn BinaryenRustModuleOptionsCreate()
@@ -138,6 +158,8 @@ extern {
debuginfo: bool);
fn BinaryenRustModuleOptionsSetStart(module: *mut BinaryenRustModuleOptions,
start: *const libc::c_char);
+ fn BinaryenRustModuleOptionsSetSourceMapUrl(module: *mut BinaryenRustModuleOptions,
+ sourceMapUrl: *const libc::c_char);
fn BinaryenRustModuleOptionsSetStackAllocation(
module: *mut BinaryenRustModuleOptions,
stack: u64,
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 1545040f2da..b732eeb624c 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -71,9 +71,12 @@ pub enum Candidate {
/// Borrow of a constant temporary.
Ref(Location),
- /// Array of indices found in the third argument of
- /// a call to one of the simd_shuffleN intrinsics.
- ShuffleIndices(BasicBlock)
+ /// Currently applied to function calls where the callee has the unstable
+ /// `#[rustc_args_required_const]` attribute as well as the SIMD shuffle
+ /// intrinsic. The intrinsic requires the arguments are indeed constant and
+ /// the attribute currently provides the semantic requirement that arguments
+ /// must be constant.
+ Argument { bb: BasicBlock, index: usize },
}
struct TempCollector<'tcx> {
@@ -303,10 +306,10 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
_ => bug!()
}
}
- Candidate::ShuffleIndices(bb) => {
+ Candidate::Argument { bb, index } => {
match self.source[bb].terminator_mut().kind {
TerminatorKind::Call { ref mut args, .. } => {
- Rvalue::Use(mem::replace(&mut args[2], new_operand))
+ Rvalue::Use(mem::replace(&mut args[index], new_operand))
}
_ => bug!()
}
@@ -359,15 +362,15 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
}
(statement.source_info.span, dest.ty(mir, tcx).to_ty(tcx))
}
- Candidate::ShuffleIndices(bb) => {
+ Candidate::Argument { bb, index } => {
let terminator = mir[bb].terminator();
let ty = match terminator.kind {
TerminatorKind::Call { ref args, .. } => {
- args[2].ty(mir, tcx)
+ args[index].ty(mir, tcx)
}
_ => {
span_bug!(terminator.source_info.span,
- "expected simd_shuffleN call to promote");
+ "expected call argument to promote");
}
};
(terminator.source_info.span, ty)
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index da76adfd48f..297e0e491f6 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -17,6 +17,7 @@
use rustc_data_structures::bitvec::BitVector;
use rustc_data_structures::indexed_set::IdxSetBuf;
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
+use rustc_data_structures::fx::FxHashSet;
use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::middle::const_val::ConstVal;
@@ -30,6 +31,7 @@ use rustc::mir::visit::{PlaceContext, Visitor};
use rustc::middle::lang_items;
use syntax::abi::Abi;
use syntax::attr;
+use syntax::ast::LitKind;
use syntax::feature_gate::UnstableFeatures;
use syntax_pos::{Span, DUMMY_SP};
@@ -407,7 +409,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
_ => {}
}
}
- Candidate::ShuffleIndices(_) => {}
+ Candidate::Argument { .. } => {}
}
}
@@ -730,8 +732,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
self.visit_operand(func, location);
let fn_ty = func.ty(self.mir, self.tcx);
+ let mut callee_def_id = None;
let (mut is_shuffle, mut is_const_fn) = (false, None);
if let ty::TyFnDef(def_id, _) = fn_ty.sty {
+ callee_def_id = Some(def_id);
match self.tcx.fn_sig(def_id).abi() {
Abi::RustIntrinsic |
Abi::PlatformIntrinsic => {
@@ -754,17 +758,39 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
}
}
+ let constant_arguments = callee_def_id.and_then(|id| {
+ args_required_const(self.tcx, id)
+ });
for (i, arg) in args.iter().enumerate() {
self.nest(|this| {
this.visit_operand(arg, location);
- if is_shuffle && i == 2 && this.mode == Mode::Fn {
- let candidate = Candidate::ShuffleIndices(bb);
+ if this.mode != Mode::Fn {
+ return
+ }
+ let candidate = Candidate::Argument { bb, index: i };
+ if is_shuffle && i == 2 {
if this.can_promote() {
this.promotion_candidates.push(candidate);
} else {
span_err!(this.tcx.sess, this.span, E0526,
"shuffle indices are not constant");
}
+ return
+ }
+
+ let constant_arguments = match constant_arguments.as_ref() {
+ Some(s) => s,
+ None => return,
+ };
+ if !constant_arguments.contains(&i) {
+ return
+ }
+ if this.can_promote() {
+ this.promotion_candidates.push(candidate);
+ } else {
+ this.tcx.sess.span_err(this.span,
+ &format!("argument {} is required to be a constant",
+ i + 1));
}
});
}
@@ -1085,3 +1111,16 @@ impl MirPass for QualifyAndPromoteConstants {
}
}
}
+
+fn args_required_const(tcx: TyCtxt, def_id: DefId) -> Option<FxHashSet<usize>> {
+ let attrs = tcx.get_attrs(def_id);
+ let attr = attrs.iter().find(|a| a.check_name("rustc_args_required_const"))?;
+ let mut ret = FxHashSet();
+ for meta in attr.meta_item_list()? {
+ match meta.literal()?.node {
+ LitKind::Int(a, _) => { ret.insert(a as usize); }
+ _ => return None,
+ }
+ }
+ Some(ret)
+}
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 206c73b0174..ded9a296817 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -759,7 +759,10 @@ unsafe fn codegen(cgcx: &CodegenContext,
if asm2wasm && config.emit_obj {
let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
- binaryen_assemble(cgcx, diag_handler, &assembly, &obj_out);
+ let suffix = ".wasm.map"; // FIXME use target suffix
+ let map = cgcx.output_filenames.path(OutputType::Exe)
+ .with_extension(&suffix[1..]);
+ binaryen_assemble(cgcx, diag_handler, &assembly, &obj_out, &map);
timeline.record("binaryen");
if !config.emit_asm {
@@ -814,7 +817,8 @@ unsafe fn codegen(cgcx: &CodegenContext,
fn binaryen_assemble(cgcx: &CodegenContext,
handler: &Handler,
assembly: &Path,
- object: &Path) {
+ object: &Path,
+ map: &Path) {
use rustc_binaryen::{Module, ModuleOptions};
let input = fs::read(&assembly).and_then(|contents| {
@@ -823,6 +827,8 @@ fn binaryen_assemble(cgcx: &CodegenContext,
let mut options = ModuleOptions::new();
if cgcx.debuginfo != config::NoDebugInfo {
options.debuginfo(true);
+ let map_file_name = map.file_name().unwrap();
+ options.source_map_url(map_file_name.to_str().unwrap());
}
options.stack(1024 * 1024);
@@ -832,7 +838,13 @@ fn binaryen_assemble(cgcx: &CodegenContext,
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
});
let err = assembled.and_then(|binary| {
- fs::write(&object, binary.data())
+ fs::write(&object, binary.data()).and_then(|()| {
+ if cgcx.debuginfo != config::NoDebugInfo {
+ fs::write(map, binary.source_map())
+ } else {
+ Ok(())
+ }
+ })
});
if let Err(e) = err {
handler.err(&format!("failed to run binaryen assembler: {}", e));
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index c88bbd03af8..e8c3966f23f 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -326,13 +326,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
if reached_raw_pointer
&& !self.tcx.sess.features.borrow().arbitrary_self_types {
// this case used to be allowed by the compiler,
- // so we do a future-compat lint here
+ // so we do a future-compat lint here for the 2015 epoch
// (see https://github.com/rust-lang/rust/issues/46906)
- self.tcx.lint_node(
- lint::builtin::TYVAR_BEHIND_RAW_POINTER,
- scope_expr_id,
- span,
- &format!("the type of this value must be known in this context"));
+ if self.tcx.sess.rust_2018() {
+ span_err!(self.tcx.sess, span, E0908,
+ "the type of this value must be known \
+ to call a method on a raw pointer on it");
+ } else {
+ self.tcx.lint_node(
+ lint::builtin::TYVAR_BEHIND_RAW_POINTER,
+ scope_expr_id,
+ span,
+ &format!("the type of this value must be known in this context"));
+ }
} else {
let t = self.structurally_resolved_type(span, final_ty);
assert_eq!(t, self.tcx.types.err);
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 363d4a9dc0c..f044b2c711e 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2925,7 +2925,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let rcvr = &args[0];
let rcvr_t = self.check_expr_with_needs(&rcvr, needs);
// no need to check for bot/err -- callee does that
- let rcvr_t = self.structurally_resolved_type(expr.span, rcvr_t);
+ let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t);
let method = match self.lookup_method(rcvr_t,
segment,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 7a91827faef..d5328a18c22 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -355,41 +355,35 @@ fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}
-fn ensure_no_ty_param_bounds(tcx: TyCtxt,
- span: Span,
- generics: &hir::Generics,
- thing: &'static str) {
+fn ensure_no_param_bounds(tcx: TyCtxt,
+ span: Span,
+ generics: &hir::Generics,
+ thing: &'static str) {
let mut warn = false;
for ty_param in generics.ty_params() {
- for bound in ty_param.bounds.iter() {
- match *bound {
- hir::TraitTyParamBound(..) => {
- warn = true;
- }
- hir::RegionTyParamBound(..) => { }
- }
+ if !ty_param.bounds.is_empty() {
+ warn = true;
}
}
- for predicate in generics.where_clause.predicates.iter() {
- match *predicate {
- hir::WherePredicate::BoundPredicate(..) => {
- warn = true;
- }
- hir::WherePredicate::RegionPredicate(..) => { }
- hir::WherePredicate::EqPredicate(..) => { }
+ for lft_param in generics.lifetimes() {
+ if !lft_param.bounds.is_empty() {
+ warn = true;
}
}
+ if !generics.where_clause.predicates.is_empty() {
+ warn = true;
+ }
+
if warn {
// According to accepted RFC #XXX, we should
// eventually accept these, but it will not be
// part of this PR. Still, convert to warning to
// make bootstrapping easier.
span_warn!(tcx.sess, span, E0122,
- "trait bounds are not (yet) enforced \
- in {} definitions",
+ "generic bounds are ignored in {}",
thing);
}
}
@@ -455,7 +449,7 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
}
},
hir::ItemTy(_, ref generics) => {
- ensure_no_ty_param_bounds(tcx, it.span, generics, "type");
+ ensure_no_param_bounds(tcx, it.span, generics, "type aliases");
tcx.generics_of(def_id);
tcx.type_of(def_id);
tcx.predicates_of(def_id);
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index ac7f54250d3..f59948e9fc4 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -4698,6 +4698,55 @@ element type `T`. Also note that the error is conservatively reported even when
the alignment of the zero-sized type is less than or equal to the data field's
alignment.
"##,
+
+
+E0908: r##"
+A method was called on a raw pointer whose inner type wasn't completely known.
+
+For example, you may have done something like:
+
+```compile_fail
+# #![deny(warnings)]
+let foo = &1;
+let bar = foo as *const _;
+if bar.is_null() {
+ // ...
+}
+```
+
+Here, the type of `bar` isn't known; it could be a pointer to anything. Instead,
+specify a type for the pointer (preferably something that makes sense for the
+thing you're pointing to):
+
+```
+let foo = &1;
+let bar = foo as *const i32;
+if bar.is_null() {
+ // ...
+}
+```
+
+Even though `is_null()` exists as a method on any raw pointer, Rust shows this
+error because Rust allows for `self` to have arbitrary types (behind the
+arbitrary_self_types feature flag).
+
+This means that someone can specify such a function:
+
+```ignore (cannot-doctest-feature-doesnt-exist-yet)
+impl Foo {
+ fn is_null(self: *const Self) -> bool {
+ // do something else
+ }
+}
+```
+
+and now when you call `.is_null()` on a raw pointer to `Foo`, there's ambiguity.
+
+Given that we don't know what type the pointer is, and there's potential
+ambiguity for some types, we disallow calling methods on raw pointers when
+the type is unknown.
+"##,
+
}
register_diagnostics! {
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 0f9e7001c15..ba9bcb7af7a 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -47,6 +47,8 @@
// 2 for "In Return Types"
var currentTab = 0;
+ var themesWidth = null;
+
function hasClass(elem, className) {
if (elem && className && elem.className) {
var elemClass = elem.className;
@@ -121,10 +123,25 @@
sidebar.appendChild(div);
}
}
+ var themeChoices = document.getElementById("theme-choices");
+ if (themeChoices) {
+ if (!themesWidth) {
+ var savedState = themeChoices.style.display;
+ themeChoices.style.display = 'block';
+ themesWidth = themeChoices.offsetWidth + 'px';
+ themeChoices.style.display = savedState;
+ }
+ themeChoices.style.position = "fixed";
+ themeChoices.style.width = themesWidth;
+ themeChoices.style.top = '78px';
+ themeChoices.style.left = '250px';
+ }
document.getElementsByTagName("body")[0].style.marginTop = '45px';
var themePicker = document.getElementById("theme-picker");
if (themePicker) {
themePicker.style.position = "fixed";
+ themePicker.style.top = "50px";
+ themePicker.style.left = "250px";
}
}
@@ -143,6 +160,15 @@
var themePicker = document.getElementById("theme-picker");
if (themePicker) {
themePicker.style.position = "absolute";
+ themePicker.style.top = null;
+ themePicker.style.left = null;
+ }
+ var themeChoices = document.getElementById("theme-choices");
+ if (themeChoices) {
+ themeChoices.style.position = 'absolute';
+ themeChoices.style.width = null;
+ themeChoices.style.top = null;
+ themeChoices.style.left = null;
}
}
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 2b1f920bba0..53d57b67230 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -870,6 +870,7 @@ span.since {
display: block;
border-bottom: 1px solid;
border-right: 1px solid;
+ height: 45px;
}
.sidebar-elems {
@@ -889,13 +890,19 @@ span.since {
}
nav.sub {
- margin: 0 auto;
+ width: calc(100% - 32px);
+ float: right;
}
.content {
margin-left: 0px;
}
+ #main {
+ margin-top: 50px;
+ padding: 0;
+ }
+
.content .in-band {
width: 100%;
}
@@ -1042,6 +1049,24 @@ h4 > .important-traits {
.show-it {
display: block;
+ width: 246px;
+ }
+
+ .show-it > .block.items {
+ margin: 8px 0;
+ }
+
+ .show-it > .block.items > ul {
+ margin: 0;
+ }
+
+ .show-it > .block.items > ul > li {
+ text-align: center;
+ margin: 2px 0;
+ }
+
+ .show-it > .block.items > ul > li > a {
+ font-size: 21px;
}
/* Because of ios, we need to actually have a full height sidebar title so the
@@ -1198,8 +1223,8 @@ kbd {
@media (max-width: 700px) {
.theme-picker {
- left: 109px;
- top: 7px;
+ left: 10px;
+ top: 54px;
z-index: 1;
}
}
diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css
index 4c6bcab72b7..907a6e4fcb4 100644
--- a/src/librustdoc/html/static/themes/dark.css
+++ b/src/librustdoc/html/static/themes/dark.css
@@ -383,6 +383,6 @@ kbd {
@media (max-width: 700px) {
#theme-picker {
- background: #353535;
+ background: #f0f0f0;
}
}
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 560876006d3..112e1106093 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -198,7 +198,7 @@ impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *const T {}
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *mut T {}
#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: UnwindSafe + ?Sized> UnwindSafe for Unique<T> {}
-#[stable(feature = "nonnull", since = "1.24.0")]
+#[stable(feature = "nonnull", since = "1.25.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for NonNull<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: ?Sized> UnwindSafe for Mutex<T> {}
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 764b3d0a848..dc3745fc4a3 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -761,6 +761,18 @@ impl<'a> Parser<'a> {
})
}
+ fn expected_ident_found(&self) -> DiagnosticBuilder<'a> {
+ let mut err = self.struct_span_err(self.span,
+ &format!("expected identifier, found {}",
+ self.this_token_descr()));
+ if let Some(token_descr) = self.token_descr() {
+ err.span_label(self.span, format!("expected identifier, found {}", token_descr));
+ } else {
+ err.span_label(self.span, "expected identifier");
+ }
+ err
+ }
+
pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> {
self.parse_ident_common(true)
}
@@ -769,15 +781,7 @@ impl<'a> Parser<'a> {
match self.token {
token::Ident(i) => {
if self.token.is_reserved_ident() {
- let mut err = self.struct_span_err(self.span,
- &format!("expected identifier, found {}",
- self.this_token_descr()));
- if let Some(token_descr) = self.token_descr() {
- err.span_label(self.span, format!("expected identifier, found {}",
- token_descr));
- } else {
- err.span_label(self.span, "expected identifier");
- }
+ let mut err = self.expected_ident_found();
if recover {
err.emit();
} else {
@@ -791,14 +795,7 @@ impl<'a> Parser<'a> {
Err(if self.prev_token_kind == PrevTokenKind::DocComment {
self.span_fatal_err(self.prev_span, Error::UselessDocComment)
} else {
- let mut err = self.fatal(&format!("expected identifier, found `{}`",
- self.this_token_to_string()));
- if let Some(token_descr) = self.token_descr() {
- err.span_label(self.span, format!("expected identifier, found {}",
- token_descr));
- } else {
- err.span_label(self.span, "expected identifier");
- }
+ let mut err = self.expected_ident_found();
if self.token == token::Underscore {
err.note("`_` is a wildcard pattern, not an identifier");
}
diff --git a/src/test/codegen/repeat-trusted-len.rs b/src/test/codegen/repeat-trusted-len.rs
new file mode 100644
index 00000000000..43872f15d51
--- /dev/null
+++ b/src/test/codegen/repeat-trusted-len.rs
@@ -0,0 +1,23 @@
+// Copyright 2018 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -O
+// ignore-tidy-linelength
+
+#![crate_type = "lib"]
+
+use std::iter;
+
+// CHECK-LABEL: @repeat_take_collect
+#[no_mangle]
+pub fn repeat_take_collect() -> Vec<u8> {
+// CHECK: call void @llvm.memset.p0i8
+ iter::repeat(42).take(100000).collect()
+}
diff --git a/src/test/compile-fail/const-eval-overflow-4b.rs b/src/test/compile-fail/const-eval-overflow-4b.rs
index 02072e9a1a1..6028df18839 100644
--- a/src/test/compile-fail/const-eval-overflow-4b.rs
+++ b/src/test/compile-fail/const-eval-overflow-4b.rs
@@ -22,7 +22,7 @@ const A_I8_T
: [u32; (i8::MAX as i8 + 1u8) as usize]
//~^ ERROR mismatched types
//~| expected i8, found u8
- //~| ERROR the trait bound `i8: std::ops::Add<u8>` is not satisfied
+ //~| ERROR cannot add `u8` to `i8`
= [0; (i8::MAX as usize) + 1];
diff --git a/src/test/compile-fail/dst-bad-assign-3.rs b/src/test/compile-fail/dst-bad-assign-3.rs
index 1c3bad5ba56..759da7b2bde 100644
--- a/src/test/compile-fail/dst-bad-assign-3.rs
+++ b/src/test/compile-fail/dst-bad-assign-3.rs
@@ -13,7 +13,7 @@
#![feature(unsized_tuple_coercion)]
type Fat<T: ?Sized> = (isize, &'static str, T);
-//~^ WARNING trait bounds are not (yet) enforced
+//~^ WARNING bounds are ignored
#[derive(PartialEq,Eq)]
struct Bar;
diff --git a/src/test/compile-fail/epoch-raw-pointer-method-2015.rs b/src/test/compile-fail/epoch-raw-pointer-method-2015.rs
new file mode 100644
index 00000000000..a71db040b50
--- /dev/null
+++ b/src/test/compile-fail/epoch-raw-pointer-method-2015.rs
@@ -0,0 +1,23 @@
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-linelength
+// compile-flags: -Zepoch=2015 -Zunstable-options
+
+// tests that epochs work with the tyvar warning-turned-error
+
+#[deny(warnings)]
+fn main() {
+ let x = 0;
+ let y = &x as *const _;
+ let _ = y.is_null();
+ //~^ error: the type of this value must be known in this context [tyvar_behind_raw_pointer]
+ //~^^ warning: this was previously accepted
+}
diff --git a/src/test/compile-fail/epoch-raw-pointer-method-2018.rs b/src/test/compile-fail/epoch-raw-pointer-method-2018.rs
new file mode 100644
index 00000000000..c4815de2306
--- /dev/null
+++ b/src/test/compile-fail/epoch-raw-pointer-method-2018.rs
@@ -0,0 +1,22 @@
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-linelength
+// compile-flags: -Zepoch=2018 -Zunstable-options
+
+// tests that epochs work with the tyvar warning-turned-error
+
+#[deny(warnings)]
+fn main() {
+ let x = 0;
+ let y = &x as *const _;
+ let _ = y.is_null();
+ //~^ error: the type of this value must be known to call a method on a raw pointer on it [E0908]
+}
diff --git a/src/test/compile-fail/private-in-public-warn.rs b/src/test/compile-fail/private-in-public-warn.rs
index dfcf4dc01b8..aa91ce27c37 100644
--- a/src/test/compile-fail/private-in-public-warn.rs
+++ b/src/test/compile-fail/private-in-public-warn.rs
@@ -58,7 +58,7 @@ mod traits {
pub trait PubTr {}
pub type Alias<T: PrivTr> = T; //~ ERROR private trait `traits::PrivTr` in public interface
- //~^ WARN trait bounds are not (yet) enforced in type definitions
+ //~^ WARN bounds are ignored in type aliases
//~| WARNING hard error
pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface
//~^ WARNING hard error
diff --git a/src/test/compile-fail/rustc-args-required-const.rs b/src/test/compile-fail/rustc-args-required-const.rs
new file mode 100644
index 00000000000..aac9299eaaf
--- /dev/null
+++ b/src/test/compile-fail/rustc-args-required-const.rs
@@ -0,0 +1,36 @@
+// Copyright 2018 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(attr_literals, rustc_attrs, const_fn)]
+
+#[rustc_args_required_const(0)]
+fn foo(_a: i32) {
+}
+
+#[rustc_args_required_const(1)]
+fn bar(_a: i32, _b: i32) {
+}
+
+const A: i32 = 3;
+
+const fn baz() -> i32 {
+ 3
+}
+
+fn main() {
+ foo(2);
+ foo(2 + 3);
+ foo(baz());
+ let a = 4;
+ foo(A);
+ foo(a); //~ ERROR: argument 1 is required to be a constant
+ bar(a, 3);
+ bar(a, a); //~ ERROR: argument 2 is required to be a constant
+}
diff --git a/src/test/compile-fail/ufcs-qpath-self-mismatch.rs b/src/test/compile-fail/ufcs-qpath-self-mismatch.rs
index 94a98b1582a..caf510071bd 100644
--- a/src/test/compile-fail/ufcs-qpath-self-mismatch.rs
+++ b/src/test/compile-fail/ufcs-qpath-self-mismatch.rs
@@ -12,7 +12,7 @@ use std::ops::Add;
fn main() {
<i32 as Add<u32>>::add(1, 2);
- //~^ ERROR `i32: std::ops::Add<u32>` is not satisfied
+ //~^ ERROR cannot add `u32` to `i32`
<i32 as Add<i32>>::add(1u32, 2);
//~^ ERROR mismatched types
<i32 as Add<i32>>::add(1, 2u32);
diff --git a/src/test/ui/impl-trait/equality.rs b/src/test/ui/impl-trait/equality.rs
index 36df4f0eb4d..9d9d4cef311 100644
--- a/src/test/ui/impl-trait/equality.rs
+++ b/src/test/ui/impl-trait/equality.rs
@@ -32,7 +32,7 @@ fn sum_to(n: u32) -> impl Foo {
0
} else {
n + sum_to(n - 1)
- //~^ ERROR the trait bound `u32: std::ops::Add<impl Foo>` is not satisfied
+ //~^ ERROR cannot add `impl Foo` to `u32`
}
}
diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr
index 3fc08a0900f..8ec81903803 100644
--- a/src/test/ui/impl-trait/equality.stderr
+++ b/src/test/ui/impl-trait/equality.stderr
@@ -7,7 +7,7 @@ error[E0308]: mismatched types
= note: expected type `i32`
found type `u32`
-error[E0277]: the trait bound `u32: std::ops::Add<impl Foo>` is not satisfied
+error[E0277]: cannot add `impl Foo` to `u32`
--> $DIR/equality.rs:34:11
|
34 | n + sum_to(n - 1)
diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
new file mode 100644
index 00000000000..a68b4f76352
--- /dev/null
+++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
@@ -0,0 +1,34 @@
+// Copyright 2018 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// must-compile-successfully
+
+#![warn(unused)] // UI tests pass `-A unused` (#43896)
+
+struct SoulHistory {
+ corridors_of_light: usize,
+ hours_are_suns: bool,
+ endless_and_singing: bool
+}
+
+fn main() {
+ let i_think_continually = 2;
+ let who_from_the_womb_remembered = SoulHistory {
+ corridors_of_light: 5,
+ hours_are_suns: true,
+ endless_and_singing: true
+ };
+
+ if let SoulHistory { corridors_of_light,
+ mut hours_are_suns,
+ endless_and_singing: true } = who_from_the_womb_remembered {
+ hours_are_suns = false;
+ }
+}
diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
new file mode 100644
index 00000000000..694fe69e016
--- /dev/null
+++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
@@ -0,0 +1,40 @@
+warning: unused variable: `i_think_continually`
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:22:9
+ |
+22 | let i_think_continually = 2;
+ | ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead
+ |
+note: lint level defined here
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:13:9
+ |
+13 | #![warn(unused)] // UI tests pass `-A unused` (#43896)
+ | ^^^^^^
+ = note: #[warn(unused_variables)] implied by #[warn(unused)]
+
+warning: unused variable: `corridors_of_light`
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:29:26
+ |
+29 | if let SoulHistory { corridors_of_light,
+ | ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _`
+
+warning: variable `hours_are_suns` is assigned to, but never used
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:30:26
+ |
+30 | mut hours_are_suns,
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = note: consider using `_hours_are_suns` instead
+
+warning: value assigned to `hours_are_suns` is never read
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:32:9
+ |
+32 | hours_are_suns = false;
+ | ^^^^^^^^^^^^^^
+ |
+note: lint level defined here
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:13:9
+ |
+13 | #![warn(unused)] // UI tests pass `-A unused` (#43896)
+ | ^^^^^^
+ = note: #[warn(unused_assignments)] implied by #[warn(unused)]
+
diff --git a/src/test/ui/mismatched_types/binops.rs b/src/test/ui/mismatched_types/binops.rs
index e45616cd67a..5144b59955c 100644
--- a/src/test/ui/mismatched_types/binops.rs
+++ b/src/test/ui/mismatched_types/binops.rs
@@ -9,10 +9,10 @@
// except according to those terms.
fn main() {
- 1 + Some(1); //~ ERROR is not satisfied
- 2 as usize - Some(1); //~ ERROR is not satisfied
- 3 * (); //~ ERROR is not satisfied
- 4 / ""; //~ ERROR is not satisfied
+ 1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}`
+ 2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize`
+ 3 * (); //~ ERROR cannot multiply `()` to `{integer}`
+ 4 / ""; //~ ERROR cannot divide `{integer}` by `&str`
5 < String::new(); //~ ERROR is not satisfied
6 == Ok(1); //~ ERROR is not satisfied
}
diff --git a/src/test/ui/mismatched_types/binops.stderr b/src/test/ui/mismatched_types/binops.stderr
index 8541ad52e01..1b7fba05063 100644
--- a/src/test/ui/mismatched_types/binops.stderr
+++ b/src/test/ui/mismatched_types/binops.stderr
@@ -1,31 +1,31 @@
-error[E0277]: the trait bound `{integer}: std::ops::Add<std::option::Option<{integer}>>` is not satisfied
+error[E0277]: cannot add `std::option::Option<{integer}>` to `{integer}`
--> $DIR/binops.rs:12:7
|
-12 | 1 + Some(1); //~ ERROR is not satisfied
+12 | 1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}`
| ^ no implementation for `{integer} + std::option::Option<{integer}>`
|
= help: the trait `std::ops::Add<std::option::Option<{integer}>>` is not implemented for `{integer}`
-error[E0277]: the trait bound `usize: std::ops::Sub<std::option::Option<{integer}>>` is not satisfied
+error[E0277]: cannot substract `std::option::Option<{integer}>` from `usize`
--> $DIR/binops.rs:13:16
|
-13 | 2 as usize - Some(1); //~ ERROR is not satisfied
+13 | 2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize`
| ^ no implementation for `usize - std::option::Option<{integer}>`
|
= help: the trait `std::ops::Sub<std::option::Option<{integer}>>` is not implemented for `usize`
-error[E0277]: the trait bound `{integer}: std::ops::Mul<()>` is not satisfied
+error[E0277]: cannot multiply `()` to `{integer}`
--> $DIR/binops.rs:14:7
|
-14 | 3 * (); //~ ERROR is not satisfied
+14 | 3 * (); //~ ERROR cannot multiply `()` to `{integer}`
| ^ no implementation for `{integer} * ()`
|
= help: the trait `std::ops::Mul<()>` is not implemented for `{integer}`
-error[E0277]: the trait bound `{integer}: std::ops::Div<&str>` is not satisfied
+error[E0277]: cannot divide `{integer}` by `&str`
--> $DIR/binops.rs:15:7
|
-15 | 4 / ""; //~ ERROR is not satisfied
+15 | 4 / ""; //~ ERROR cannot divide `{integer}` by `&str`
| ^ no implementation for `{integer} / &str`
|
= help: the trait `std::ops::Div<&str>` is not implemented for `{integer}`
diff --git a/src/test/ui/on-unimplemented/auxiliary/no_debug.rs b/src/test/ui/on-unimplemented/auxiliary/no_debug.rs
new file mode 100644
index 00000000000..0f833c62637
--- /dev/null
+++ b/src/test/ui/on-unimplemented/auxiliary/no_debug.rs
@@ -0,0 +1,14 @@
+// Copyright 2018 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+// ignore-tidy-linelength
+
+#![crate_type = "lib"]
+
+pub struct Bar;
diff --git a/src/test/ui/on-unimplemented/no-debug.rs b/src/test/ui/on-unimplemented/no-debug.rs
new file mode 100644
index 00000000000..fff6122c6b3
--- /dev/null
+++ b/src/test/ui/on-unimplemented/no-debug.rs
@@ -0,0 +1,27 @@
+// Copyright 2018 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:no_debug.rs
+
+extern crate no_debug;
+
+use no_debug::Bar;
+
+struct Foo;
+
+fn main() {
+ println!("{:?} {:?}", Foo, Bar);
+ println!("{} {}", Foo, Bar);
+}
+//~^^^ ERROR `Foo` doesn't implement `std::fmt::Debug`
+//~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Debug`
+//~^^^^ ERROR `Foo` doesn't implement `std::fmt::Display`
+//~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Display`
+
diff --git a/src/test/ui/on-unimplemented/no-debug.stderr b/src/test/ui/on-unimplemented/no-debug.stderr
new file mode 100644
index 00000000000..af5b1e91211
--- /dev/null
+++ b/src/test/ui/on-unimplemented/no-debug.stderr
@@ -0,0 +1,38 @@
+error[E0277]: `Foo` doesn't implement `std::fmt::Debug`
+ --> $DIR/no-debug.rs:20:27
+ |
+20 | println!("{:?} {:?}", Foo, Bar);
+ | ^^^ `Foo` cannot be formatted using `:?`; add `#[derive(Debug)]` or manually implement `std::fmt::Debug`
+ |
+ = help: the trait `std::fmt::Debug` is not implemented for `Foo`
+ = note: required by `std::fmt::Debug::fmt`
+
+error[E0277]: `no_debug::Bar` doesn't implement `std::fmt::Debug`
+ --> $DIR/no-debug.rs:20:32
+ |
+20 | println!("{:?} {:?}", Foo, Bar);
+ | ^^^ `no_debug::Bar` cannot be formatted using `:?` because it doesn't implement `std::fmt::Debug`
+ |
+ = help: the trait `std::fmt::Debug` is not implemented for `no_debug::Bar`
+ = note: required by `std::fmt::Debug::fmt`
+
+error[E0277]: `Foo` doesn't implement `std::fmt::Display`
+ --> $DIR/no-debug.rs:21:23
+ |
+21 | println!("{} {}", Foo, Bar);
+ | ^^^ `Foo` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string
+ |
+ = help: the trait `std::fmt::Display` is not implemented for `Foo`
+ = note: required by `std::fmt::Display::fmt`
+
+error[E0277]: `no_debug::Bar` doesn't implement `std::fmt::Display`
+ --> $DIR/no-debug.rs:21:28
+ |
+21 | println!("{} {}", Foo, Bar);
+ | ^^^ `no_debug::Bar` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string
+ |
+ = help: the trait `std::fmt::Display` is not implemented for `no_debug::Bar`
+ = note: required by `std::fmt::Display::fmt`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/param-bounds-ignored.rs b/src/test/ui/param-bounds-ignored.rs
new file mode 100644
index 00000000000..9e09102f2d4
--- /dev/null
+++ b/src/test/ui/param-bounds-ignored.rs
@@ -0,0 +1,33 @@
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// must-compile-successfully
+
+use std::rc::Rc;
+
+type SVec<T: Send> = Vec<T>;
+type VVec<'b, 'a: 'b> = Vec<&'a i32>;
+type WVec<'b, T: 'b> = Vec<T>;
+
+fn foo<'a>(y: &'a i32) {
+ // If the bounds above would matter, the code below would be rejected.
+ let mut x : SVec<_> = Vec::new();
+ x.push(Rc::new(42));
+
+ let mut x : VVec<'static, 'a> = Vec::new();
+ x.push(y);
+
+ let mut x : WVec<'static, & 'a i32> = Vec::new();
+ x.push(y);
+}
+
+fn main() {
+ foo(&42);
+}
diff --git a/src/test/ui/param-bounds-ignored.stderr b/src/test/ui/param-bounds-ignored.stderr
new file mode 100644
index 00000000000..19aa9c5d6e5
--- /dev/null
+++ b/src/test/ui/param-bounds-ignored.stderr
@@ -0,0 +1,18 @@
+warning[E0122]: generic bounds are ignored in type aliases
+ --> $DIR/param-bounds-ignored.rs:15:1
+ |
+15 | type SVec<T: Send> = Vec<T>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning[E0122]: generic bounds are ignored in type aliases
+ --> $DIR/param-bounds-ignored.rs:16:1
+ |
+16 | type VVec<'b, 'a: 'b> = Vec<&'a i32>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning[E0122]: generic bounds are ignored in type aliases
+ --> $DIR/param-bounds-ignored.rs:17:1
+ |
+17 | type WVec<'b, T: 'b> = Vec<T>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr
index 7e19c7492ce..31728dbf08d 100644
--- a/src/test/ui/span/issue-24690.stderr
+++ b/src/test/ui/span/issue-24690.stderr
@@ -2,7 +2,7 @@ warning: unused variable: `theOtherTwo`
--> $DIR/issue-24690.rs:23:9
|
23 | let theOtherTwo = 2; //~ WARN should have a snake case name
- | ^^^^^^^^^^^
+ | ^^^^^^^^^^^ help: consider using `_theOtherTwo` instead
|
note: lint level defined here
--> $DIR/issue-24690.rs:18:9
@@ -10,7 +10,6 @@ note: lint level defined here
18 | #![warn(unused)]
| ^^^^^^
= note: #[warn(unused_variables)] implied by #[warn(unused)]
- = note: to avoid this warning, consider using `_theOtherTwo` instead
warning: variable `theTwo` should have a snake case name such as `the_two`
--> $DIR/issue-24690.rs:22:9
diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.rs b/src/test/ui/span/issue-42234-unknown-receiver-type.rs
new file mode 100644
index 00000000000..d9cdd99c245
--- /dev/null
+++ b/src/test/ui/span/issue-42234-unknown-receiver-type.rs
@@ -0,0 +1,27 @@
+// Copyright 2018 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// When the type of a method call's receiver is unknown, the span should point
+// to the receiver (and not the entire call, as was previously the case before
+// the fix of which this tests).
+
+fn shines_a_beacon_through_the_darkness() {
+ let x: Option<_> = None;
+ x.unwrap().method_that_could_exist_on_some_type();
+ //~^ ERROR 17:5: 17:15: the type of this value must be known in this context
+}
+
+fn courier_to_des_moines_and_points_west(data: &[u32]) -> String {
+ data.iter() //~ ERROR 22:5: 23:20: the type of this value must be known in this context
+ .sum::<_>()
+ .to_string()
+}
+
+fn main() {}
diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr
new file mode 100644
index 00000000000..ed756cdc553
--- /dev/null
+++ b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr
@@ -0,0 +1,15 @@
+error[E0619]: the type of this value must be known in this context
+ --> $DIR/issue-42234-unknown-receiver-type.rs:17:5
+ |
+17 | x.unwrap().method_that_could_exist_on_some_type();
+ | ^^^^^^^^^^
+
+error[E0619]: the type of this value must be known in this context
+ --> $DIR/issue-42234-unknown-receiver-type.rs:22:5
+ |
+22 | / data.iter() //~ ERROR 22:5: 23:20: the type of this value must be known in this context
+23 | | .sum::<_>()
+ | |___________________^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/span/multiline-span-simple.rs b/src/test/ui/span/multiline-span-simple.rs
index f8e4cbcbf19..dd09534480e 100644
--- a/src/test/ui/span/multiline-span-simple.rs
+++ b/src/test/ui/span/multiline-span-simple.rs
@@ -20,7 +20,7 @@ fn main() {
let x = 1;
let y = 2;
let z = 3;
- foo(1 as u32 + //~ ERROR not satisfied
+ foo(1 as u32 + //~ ERROR cannot add `()` to `u32`
bar(x,
diff --git a/src/test/ui/span/multiline-span-simple.stderr b/src/test/ui/span/multiline-span-simple.stderr
index b068798630e..a18dfeb31d9 100644
--- a/src/test/ui/span/multiline-span-simple.stderr
+++ b/src/test/ui/span/multiline-span-simple.stderr
@@ -1,7 +1,7 @@
-error[E0277]: the trait bound `u32: std::ops::Add<()>` is not satisfied
+error[E0277]: cannot add `()` to `u32`
--> $DIR/multiline-span-simple.rs:23:18
|
-23 | foo(1 as u32 + //~ ERROR not satisfied
+23 | foo(1 as u32 + //~ ERROR cannot add `()` to `u32`
| ^ no implementation for `u32 + ()`
|
= help: the trait `std::ops::Add<()>` is not implemented for `u32`
diff --git a/src/test/ui/suggestions/for-c-in-str.stderr b/src/test/ui/suggestions/for-c-in-str.stderr
index 7a6dc9a5040..88a7b1b49d6 100644
--- a/src/test/ui/suggestions/for-c-in-str.stderr
+++ b/src/test/ui/suggestions/for-c-in-str.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied
--> $DIR/for-c-in-str.rs:14:14
|
14 | for c in "asdf" {
- | ^^^^^^ `&str` is not an iterator; maybe try calling `.iter()` or a similar method
+ | ^^^^^^ `&str` is not an iterator; try calling `.chars()` or `.bytes()`
|
= help: the trait `std::iter::Iterator` is not implemented for `&str`
= note: required by `std::iter::IntoIterator::into_iter`