From 08b0aca05e3709766fd7e0e01ec56a8511e4c46b Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 9 Apr 2019 13:40:21 -0700 Subject: [PATCH 001/239] string: implement From<&String> for String Allow Strings to be created from borrowed Strings. This is mostly to make things like passing &String to an `impl Into` parameter frictionless. --- src/liballoc/string.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index a3e2098695f7..ace2b3ebf559 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -2179,6 +2179,14 @@ impl From<&str> for String { } } +#[stable(feature = "from_ref_string", since = "1.35.0")] +impl From<&String> for String { + #[inline] + fn from(s: &String) -> String { + s.clone() + } +} + // note: test pulls in libstd, which causes errors here #[cfg(not(test))] #[stable(feature = "string_from_box", since = "1.18.0")] From eba03d462e987a969d21aa74632e4d96dbe9751e Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Fri, 12 Apr 2019 01:23:23 -0500 Subject: [PATCH 002/239] Fix convert module's documentation links --- src/libcore/convert.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index e903bd936c48..dbe0d204aca8 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -213,7 +213,7 @@ pub trait AsMut { /// /// # Generic Implementations /// -/// - [`From`]` for U` implies `Into for T` +/// - [`From`]` for U` implies `Into for T` /// - [`Into`]` is reflexive, which means that `Into for T` is implemented /// /// # Implementing `Into` for conversions to external types @@ -273,7 +273,7 @@ pub trait AsMut { /// [`Option`]: ../../std/option/enum.Option.html /// [`Result`]: ../../std/result/enum.Result.html /// [`String`]: ../../std/string/struct.String.html -/// [From]: trait.From.html +/// [`From`]: trait.From.html /// [`into`]: trait.Into.html#tymethod.into #[stable(feature = "rust1", since = "1.0.0")] pub trait Into: Sized { @@ -285,18 +285,18 @@ pub trait Into: Sized { /// Used to do value-to-value conversions while consuming the input value. It is the reciprocal of /// [`Into`]. /// -/// One should always prefer implementing [`From`] over [`Into`] -/// because implementing [`From`] automatically provides one with a implementation of [`Into`] +/// One should always prefer implementing `From` over [`Into`] +/// because implementing `From` automatically provides one with a implementation of [`Into`] /// thanks to the blanket implementation in the standard library. /// /// Only implement [`Into`] if a conversion to a type outside the current crate is required. -/// [`From`] cannot do these type of conversions because of Rust's orphaning rules. +/// `From` cannot do these type of conversions because of Rust's orphaning rules. /// See [`Into`] for more details. /// -/// Prefer using [`Into`] over using [`From`] when specifying trait bounds on a generic function. +/// Prefer using [`Into`] over using `From` when specifying trait bounds on a generic function. /// This way, types that directly implement [`Into`] can be used as arguments as well. /// -/// The [`From`] is also very useful when performing error handling. When constructing a function +/// The `From` is also very useful when performing error handling. When constructing a function /// that is capable of failing, the return type will generally be of the form `Result`. /// The `From` trait simplifies error handling by allowing a function to return a single error type /// that encapsulate multiple error types. See the "Examples" section and [the book][book] for more @@ -306,8 +306,8 @@ pub trait Into: Sized { /// /// # Generic Implementations /// -/// - [`From`]` for U` implies [`Into`]` for T` -/// - [`From`] is reflexive, which means that `From for T` is implemented +/// - `From` for U` implies [`Into`]` for T` +/// - `From` is reflexive, which means that `From for T` is implemented /// /// # Examples /// @@ -361,7 +361,7 @@ pub trait Into: Sized { /// [`Option`]: ../../std/option/enum.Option.html /// [`Result`]: ../../std/result/enum.Result.html /// [`String`]: ../../std/string/struct.String.html -/// [`Into`]: trait.Into.html +/// [`Into`]: trait.Into.html /// [`from`]: trait.From.html#tymethod.from /// [book]: ../../book/ch09-00-error-handling.html #[stable(feature = "rust1", since = "1.0.0")] @@ -422,7 +422,7 @@ pub trait TryInto: Sized { /// /// # Generic Implementations /// -/// - `TryFrom for U` implies [`TryInto`]` for T` +/// - `TryFrom for U` implies [`TryInto`]` for T` /// - [`try_from`] is reflexive, which means that `TryFrom for T` /// is implemented and cannot fail -- the associated `Error` type for /// calling `T::try_from()` on a value of type `T` is `Infallible`. From 6bf94cd3ff4af69c8128fb64d28a60f6c9385c19 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Sat, 13 Apr 2019 10:34:42 -0500 Subject: [PATCH 003/239] Remove dangling ` in Into documentation --- src/libcore/convert.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index dbe0d204aca8..e981001bd641 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -214,7 +214,7 @@ pub trait AsMut { /// # Generic Implementations /// /// - [`From`]` for U` implies `Into for T` -/// - [`Into`]` is reflexive, which means that `Into for T` is implemented +/// - [`Into`] is reflexive, which means that `Into for T` is implemented /// /// # Implementing `Into` for conversions to external types /// From b701d32ca80e58d41cadc18755567794d5e65bd9 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Sat, 13 Apr 2019 10:38:06 -0500 Subject: [PATCH 004/239] Remove broken links to self in Into documentation --- src/libcore/convert.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index e981001bd641..2498159edc70 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -203,9 +203,9 @@ pub trait AsMut { /// A value-to-value conversion that consumes the input value. The /// opposite of [`From`]. /// -/// One should only implement [`Into`] if a conversion to a type outside the current crate is -/// required. Otherwise one should always prefer implementing [`From`] over [`Into`] because -/// implementing [`From`] automatically provides one with a implementation of [`Into`] thanks to +/// One should only implement `Into` if a conversion to a type outside the current crate is +/// required. Otherwise one should always prefer implementing [`From`] over `Into` because +/// implementing [`From`] automatically provides one with a implementation of `Into` thanks to /// the blanket implementation in the standard library. [`From`] cannot do these type of /// conversions because of Rust's orphaning rules. /// @@ -214,7 +214,7 @@ pub trait AsMut { /// # Generic Implementations /// /// - [`From`]` for U` implies `Into for T` -/// - [`Into`] is reflexive, which means that `Into for T` is implemented +/// - `Into` is reflexive, which means that `Into for T` is implemented /// /// # Implementing `Into` for conversions to external types /// From 4a33ece38216a42764a0c74ae99baf183b888817 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Sat, 13 Apr 2019 11:57:02 -0500 Subject: [PATCH 005/239] Remove blank lines in AsRef documentation --- src/libcore/convert.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 2498159edc70..e04c01e50c0b 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -104,7 +104,6 @@ pub const fn identity(x: T) -> T { x } /// If you need to do a costly conversion it is better to implement [`From`] with type /// `&T` or write a custom function. /// -/// /// `AsRef` has the same signature as [`Borrow`], but `Borrow` is different in few aspects: /// /// - Unlike `AsRef`, `Borrow` has a blanket impl for any `T`, and can be used to accept either @@ -149,7 +148,6 @@ pub const fn identity(x: T) -> T { x } /// let s = "hello".to_string(); /// is_hello(s); /// ``` -/// #[stable(feature = "rust1", since = "1.0.0")] pub trait AsRef { /// Performs the conversion. From 27ff5360ab661a3c20ab7256529aeb61b4e2b215 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Sat, 13 Apr 2019 15:25:13 -0500 Subject: [PATCH 006/239] Reorder blank lines in AsMut documentation --- src/libcore/convert.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index e04c01e50c0b..86846d3842c0 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -180,6 +180,7 @@ pub trait AsRef { /// write a function `add_one`that takes all arguments that can be converted to `&mut u64`. /// Because [`Box`] implements `AsMut` `add_one` accepts arguments of type /// `&mut Box` as well: +/// /// ``` /// fn add_one>(num: &mut T) { /// *num.as_mut() += 1; @@ -189,8 +190,8 @@ pub trait AsRef { /// add_one(&mut boxed_num); /// assert_eq!(*boxed_num, 1); /// ``` -/// [`Box`]: ../../std/boxed/struct.Box.html /// +/// [`Box`]: ../../std/boxed/struct.Box.html #[stable(feature = "rust1", since = "1.0.0")] pub trait AsMut { /// Performs the conversion. From 1e48da6c81ba407b83189adff90abbd224dc1b62 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Sat, 13 Apr 2019 18:14:44 -0500 Subject: [PATCH 007/239] Escape &str in convert docs --- src/libcore/convert.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 86846d3842c0..df178e0ff0a6 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -132,7 +132,7 @@ pub const fn identity(x: T) -> T { x } /// converted a the specified type `T`. /// /// For example: By creating a generic function that takes an `AsRef` we express that we -/// want to accept all references that can be converted to &str as an argument. +/// want to accept all references that can be converted to `&str` as an argument. /// Since both [`String`] and `&str` implement `AsRef` we can accept both as input argument. /// /// [`String`]: ../../std/string/struct.String.html @@ -312,7 +312,8 @@ pub trait Into: Sized { /// /// [`String`] implements `From<&str>`: /// -/// An explicit conversion from a &str to a String is done as follows: +/// An explicit conversion from a `&str` to a String is done as follows: +/// /// ``` /// let string = "hello".to_string(); /// let other_string = String::from("hello"); From 1f5d510604be553906cdcbb2eddaf5277faf543d Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Sat, 13 Apr 2019 21:23:31 -0500 Subject: [PATCH 008/239] Fix stray ` in previous change --- src/libcore/convert.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index df178e0ff0a6..9da1c02dea06 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -305,7 +305,7 @@ pub trait Into: Sized { /// /// # Generic Implementations /// -/// - `From` for U` implies [`Into`]` for T` +/// - `From for U` implies [`Into`]` for T` /// - `From` is reflexive, which means that `From for T` is implemented /// /// # Examples From 9982e7d4071c3964e8212e3c547a7aaa4e12f01e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ho=C3=A0ng=20=C4=90=E1=BB=A9c=20Hi=E1=BA=BFu?= Date: Thu, 10 May 2018 12:42:03 +0700 Subject: [PATCH 009/239] lint: convert incoherent_fundamental_impls into hard error Also remove it from lint listings. --- src/doc/rustc/src/lints/groups.md | 4 +- .../src/lints/listing/deny-by-default.md | 41 ------------------ src/librustc/lint/builtin.rs | 7 --- src/librustc/traits/specialize/mod.rs | 43 +++++++++++-------- src/librustc_lint/lib.rs | 7 +-- .../coherence/inherent_impls_overlap.rs | 38 ++-------------- src/test/ui/issues/issue-43355.rs | 1 - src/test/ui/issues/issue-43355.stderr | 6 +-- 8 files changed, 34 insertions(+), 113 deletions(-) diff --git a/src/doc/rustc/src/lints/groups.md b/src/doc/rustc/src/lints/groups.md index 46b717f3387d..049e59b65172 100644 --- a/src/doc/rustc/src/lints/groups.md +++ b/src/doc/rustc/src/lints/groups.md @@ -21,9 +21,9 @@ Here's a list of each lint group, and the lints that they are made up of: | edition-2018 | Lints that will be turned into errors in Rust 2018 | tyvar-behind-raw-pointer | | rust-2018-idioms | Lints to nudge you toward idiomatic features of Rust 2018 | bare-trait-object, unreachable-pub | | unused | These lints detect things being declared but not used | unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-allocation, unused-doc-comment, unused-extern-crates, unused-features, unused-parens | -| future-incompatible | Lints that detect code that has future-compatibility problems | private-in-public, pub-use-of-private-extern-crate, patterns-in-fns-without-body, safe-extern-statics, invalid-type-param-default, legacy-directory-ownership, legacy-imports, legacy-constructor-visibility, missing-fragment-specifier, illegal-floating-point-literal-pattern, anonymous-parameters, parenthesized-params-in-types-and-modules, late-bound-lifetime-arguments, safe-packed-borrows, incoherent-fundamental-impls, tyvar-behind-raw-pointer, unstable-name-collision | +| future-incompatible | Lints that detect code that has future-compatibility problems | private-in-public, pub-use-of-private-extern-crate, patterns-in-fns-without-body, safe-extern-statics, invalid-type-param-default, legacy-directory-ownership, legacy-imports, legacy-constructor-visibility, missing-fragment-specifier, illegal-floating-point-literal-pattern, anonymous-parameters, parenthesized-params-in-types-and-modules, late-bound-lifetime-arguments, safe-packed-borrows, tyvar-behind-raw-pointer, unstable-name-collision | Additionally, there's a `bad-style` lint group that's a deprecated alias for `nonstandard-style`. Finally, you can also see the table above by invoking `rustc -W help`. This will give you the exact values for the specific -compiler you have installed. \ No newline at end of file +compiler you have installed. diff --git a/src/doc/rustc/src/lints/listing/deny-by-default.md b/src/doc/rustc/src/lints/listing/deny-by-default.md index fa62d1a03f53..c1740f272ed2 100644 --- a/src/doc/rustc/src/lints/listing/deny-by-default.md +++ b/src/doc/rustc/src/lints/listing/deny-by-default.md @@ -222,44 +222,3 @@ error: invalid `crate_type` value | ^^^^^^^^^^^^^^^^^^^^ | ``` - -## incoherent-fundamental-impls - -This lint detects potentially-conflicting impls that were erroneously allowed. Some -example code that triggers this lint: - -```rust,ignore -pub trait Trait1 { - type Output; -} - -pub trait Trait2 {} - -pub struct A; - -impl Trait1 for T where T: Trait2 { - type Output = (); -} - -impl Trait1> for A { - type Output = i32; -} -``` - -This will produce: - -```text -error: conflicting implementations of trait `Trait1>` for type `A`: (E0119) - --> src/main.rs:13:1 - | -9 | impl Trait1 for T where T: Trait2 { - | --------------------------------------------- first implementation here -... -13 | impl Trait1> for A { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `A` - | - = note: #[deny(incoherent_fundamental_impls)] on by default - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #46205 - = note: downstream crates may implement trait `Trait2>` for type `A` -``` diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 28a2a1eaf6b4..550114a5fb17 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -198,12 +198,6 @@ declare_lint! { "detects generic lifetime arguments in path segments with late bound lifetime parameters" } -declare_lint! { - pub INCOHERENT_FUNDAMENTAL_IMPLS, - Deny, - "potentially-conflicting impls were erroneously allowed" -} - declare_lint! { pub ORDER_DEPENDENT_TRAIT_OBJECTS, Deny, @@ -428,7 +422,6 @@ declare_lint_pass! { MISSING_FRAGMENT_SPECIFIER, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES, LATE_BOUND_LIFETIME_ARGUMENTS, - INCOHERENT_FUNDAMENTAL_IMPLS, ORDER_DEPENDENT_TRAIT_OBJECTS, DEPRECATED, UNUSED_UNSAFE, diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 384a5862cde0..c55f3c51f5a3 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -321,29 +321,34 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>( String::new(), |ty| { format!(" for type `{}`", ty) }), - if used_to_be_allowed.is_some() { " (E0119)" } else { "" } + match used_to_be_allowed { + Some(FutureCompatOverlapErrorKind::Issue33140) => " (E0119)", + _ => "", + } ); let impl_span = tcx.sess.source_map().def_span( tcx.span_of_impl(impl_def_id).unwrap() ); - let mut err = if let Some(kind) = used_to_be_allowed { - let lint = match kind { - FutureCompatOverlapErrorKind::Issue43355 => - lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS, - FutureCompatOverlapErrorKind::Issue33140 => - lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS, - }; - tcx.struct_span_lint_hir( - lint, - tcx.hir().as_local_hir_id(impl_def_id).unwrap(), - impl_span, - &msg) - } else { - struct_span_err!(tcx.sess, - impl_span, - E0119, - "{}", - msg) + let mut err = match used_to_be_allowed { + Some(FutureCompatOverlapErrorKind::Issue43355) | None => + struct_span_err!(tcx.sess, + impl_span, + E0119, + "{}", + msg), + Some(kind) => { + let lint = match kind { + FutureCompatOverlapErrorKind::Issue43355 => + unreachable!("converted to hard error above"), + FutureCompatOverlapErrorKind::Issue33140 => + lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS, + }; + tcx.struct_span_lint_hir( + lint, + tcx.hir().as_local_hir_id(impl_def_id).unwrap(), + impl_span, + &msg) + } }; match tcx.span_of_impl(overlap.with_impl) { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 9354f203e4e4..f2cf48793162 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -371,11 +371,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #46043 ", edition: None, }, - FutureIncompatibleInfo { - id: LintId::of(INCOHERENT_FUNDAMENTAL_IMPLS), - reference: "issue #46205 ", - edition: None, - }, FutureIncompatibleInfo { id: LintId::of(ORDER_DEPENDENT_TRAIT_OBJECTS), reference: "issue #56484 ", @@ -491,6 +486,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { "replaced with a generic attribute input check"); store.register_removed("duplicate_matcher_binding_name", "converted into hard error, see https://github.com/rust-lang/rust/issues/57742"); + store.register_removed("incoherent_fundamental_impls", + "converted into hard error, see https://github.com/rust-lang/rust/issues/46205"); } pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) { diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs index d0156db32e94..a9951c7fe447 100644 --- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs +++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs @@ -5,8 +5,6 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::traits::{self, IntercrateMode}; use rustc::ty::TyCtxt; -use crate::lint; - pub fn crate_inherent_impls_overlap_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) { assert_eq!(crate_num, LOCAL_CRATE); @@ -20,8 +18,7 @@ struct InherentOverlapChecker<'a, 'tcx: 'a> { impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> { fn check_for_common_items_in_impls(&self, impl1: DefId, impl2: DefId, - overlap: traits::OverlapResult<'_>, - used_to_be_allowed: bool) { + overlap: traits::OverlapResult<'_>) { let name_and_namespace = |def_id| { let item = self.tcx.associated_item(def_id); @@ -36,22 +33,12 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> { for &item2 in &impl_items2[..] { if (name, namespace) == name_and_namespace(item2) { - let hir_id = self.tcx.hir().as_local_hir_id(impl1); - let mut err = if used_to_be_allowed && hir_id.is_some() { - self.tcx.struct_span_lint_hir( - lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS, - hir_id.unwrap(), - self.tcx.span_of_impl(item1).unwrap(), - &format!("duplicate definitions with name `{}` (E0592)", name) - ) - } else { + let mut err = struct_span_err!(self.tcx.sess, self.tcx.span_of_impl(item1).unwrap(), E0592, "duplicate definitions with name `{}`", - name) - }; - + name); err.span_label(self.tcx.span_of_impl(item1).unwrap(), format!("duplicate definitions for `{}`", name)); err.span_label(self.tcx.span_of_impl(item2).unwrap(), @@ -76,7 +63,7 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> { for (i, &impl1_def_id) in impls.iter().enumerate() { for &impl2_def_id in &impls[(i + 1)..] { - let used_to_be_allowed = traits::overlapping_impls( + traits::overlapping_impls( self.tcx, impl1_def_id, impl2_def_id, @@ -86,28 +73,11 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> { impl1_def_id, impl2_def_id, overlap, - false, ); false }, || true, ); - - if used_to_be_allowed { - traits::overlapping_impls( - self.tcx, - impl1_def_id, - impl2_def_id, - IntercrateMode::Fixed, - |overlap| self.check_for_common_items_in_impls( - impl1_def_id, - impl2_def_id, - overlap, - true, - ), - || (), - ); - } } } } diff --git a/src/test/ui/issues/issue-43355.rs b/src/test/ui/issues/issue-43355.rs index 809300d6d196..bf819af79625 100644 --- a/src/test/ui/issues/issue-43355.rs +++ b/src/test/ui/issues/issue-43355.rs @@ -12,7 +12,6 @@ impl Trait1 for T where T: Trait2 { impl Trait1> for A { //~^ ERROR conflicting implementations of trait -//~| hard error //~| downstream crates may implement trait `Trait2>` for type `A` type Output = i32; } diff --git a/src/test/ui/issues/issue-43355.stderr b/src/test/ui/issues/issue-43355.stderr index 039f10447c07..75c69e5b3e3f 100644 --- a/src/test/ui/issues/issue-43355.stderr +++ b/src/test/ui/issues/issue-43355.stderr @@ -1,4 +1,4 @@ -error: conflicting implementations of trait `Trait1>` for type `A`: (E0119) +error[E0119]: conflicting implementations of trait `Trait1>` for type `A`: --> $DIR/issue-43355.rs:13:1 | LL | impl Trait1 for T where T: Trait2 { @@ -7,10 +7,8 @@ LL | impl Trait1 for T where T: Trait2 { LL | impl Trait1> for A { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `A` | - = note: #[deny(incoherent_fundamental_impls)] on by default - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #46205 = note: downstream crates may implement trait `Trait2>` for type `A` error: aborting due to previous error +For more information about this error, try `rustc --explain E0119`. From 5971266301e76a0f9ea131996cf699b18eaa7c89 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 18 Apr 2019 00:02:12 +0200 Subject: [PATCH 010/239] Fixes attributes position in types decl --- src/librustdoc/html/render.rs | 29 +++++++++++++------------- src/librustdoc/html/static/main.js | 6 +++++- src/librustdoc/html/static/rustdoc.css | 4 ++-- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 3ee131d8f5c8..e99cdb90b0ab 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3002,7 +3002,7 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec { fn item_constant(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item, c: &clean::Constant) -> fmt::Result { write!(w, "
")?;
-    render_attributes(w, it)?;
+    render_attributes(w, it, false)?;
     write!(w, "{vis}const \
                {name}: {typ}
", vis = VisSpace(&it.visibility), @@ -3014,7 +3014,7 @@ fn item_constant(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item, fn item_static(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item, s: &clean::Static) -> fmt::Result { write!(w, "
")?;
-    render_attributes(w, it)?;
+    render_attributes(w, it, false)?;
     write!(w, "{vis}static {mutability}\
                {name}: {typ}
", vis = VisSpace(&it.visibility), @@ -3037,7 +3037,7 @@ fn item_function(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item, f.generics ).len(); write!(w, "{}
", render_spotlight_traits(it)?)?;
-    render_attributes(w, it)?;
+    render_attributes(w, it, false)?;
     write!(w,
            "{vis}{constness}{unsafety}{asyncness}{abi}fn \
            {name}{generics}{decl}{where_clause}
", @@ -3126,7 +3126,7 @@ fn item_trait( // Output the trait definition wrap_into_docblock(w, |w| { write!(w, "
")?;
-        render_attributes(w, it)?;
+        render_attributes(w, it, true)?;
         write!(w, "{}{}{}trait {}{}{}",
                VisSpace(&it.visibility),
                UnsafetySpace(t.unsafety),
@@ -3479,7 +3479,7 @@ fn render_assoc_item(w: &mut fmt::Formatter<'_>,
         } else {
             (0, true)
         };
-        render_attributes(w, meth)?;
+        render_attributes(w, meth, false)?;
         write!(w, "{}{}{}{}{}{}{}fn {name}\
                    {generics}{decl}{where_clause}",
                if parent == ItemType::Trait { "    " } else { "" },
@@ -3526,7 +3526,7 @@ fn item_struct(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
                s: &clean::Struct) -> fmt::Result {
     wrap_into_docblock(w, |w| {
         write!(w, "
")?;
-        render_attributes(w, it)?;
+        render_attributes(w, it, true)?;
         render_struct(w,
                       it,
                       Some(&s.generics),
@@ -3577,7 +3577,7 @@ fn item_union(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
                s: &clean::Union) -> fmt::Result {
     wrap_into_docblock(w, |w| {
         write!(w, "
")?;
-        render_attributes(w, it)?;
+        render_attributes(w, it, true)?;
         render_union(w,
                      it,
                      Some(&s.generics),
@@ -3622,7 +3622,7 @@ fn item_enum(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
              e: &clean::Enum) -> fmt::Result {
     wrap_into_docblock(w, |w| {
         write!(w, "
")?;
-        render_attributes(w, it)?;
+        render_attributes(w, it, true)?;
         write!(w, "{}enum {}{}{}",
                VisSpace(&it.visibility),
                it.name.as_ref().unwrap(),
@@ -3783,7 +3783,7 @@ const ATTRIBUTE_WHITELIST: &'static [&'static str] = &[
     "non_exhaustive"
 ];
 
-fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item) -> fmt::Result {
+fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item, top: bool) -> fmt::Result {
     let mut attrs = String::new();
 
     for attr in &it.attrs.other_attrs {
@@ -3795,7 +3795,8 @@ fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item) -> fmt::Result {
         }
     }
     if attrs.len() > 0 {
-        write!(w, "
{}
", &attrs)?; + write!(w, "
{}
", + if top { " top-attr" } else { "" }, &attrs)?; } Ok(()) } @@ -4344,7 +4345,7 @@ fn item_existential( t: &clean::Existential, ) -> fmt::Result { write!(w, "
")?;
-    render_attributes(w, it)?;
+    render_attributes(w, it, false)?;
     write!(w, "existential type {}{}{where_clause}: {bounds};
", it.name.as_ref().unwrap(), t.generics, @@ -4363,7 +4364,7 @@ fn item_existential( fn item_trait_alias(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item, t: &clean::TraitAlias) -> fmt::Result { write!(w, "
")?;
-    render_attributes(w, it)?;
+    render_attributes(w, it, false)?;
     write!(w, "trait {}{}{} = {};
", it.name.as_ref().unwrap(), t.generics, @@ -4382,7 +4383,7 @@ fn item_trait_alias(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item, fn item_typedef(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item, t: &clean::Typedef) -> fmt::Result { write!(w, "
")?;
-    render_attributes(w, it)?;
+    render_attributes(w, it, false)?;
     write!(w, "type {}{}{where_clause} = {type_};
", it.name.as_ref().unwrap(), t.generics, @@ -4400,7 +4401,7 @@ fn item_typedef(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item, fn item_foreign_type(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item) -> fmt::Result { writeln!(w, "
extern {{")?;
-    render_attributes(w, it)?;
+    render_attributes(w, it, false)?;
     write!(
         w,
         "    {}type {};\n}}
", diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 00ca78b749e9..fe9b7c2012ad 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -2325,7 +2325,11 @@ if (!DOMTokenList.prototype.remove) { } var attributesToggle = createToggleWrapper(createSimpleToggle(false)); onEachLazy(main.getElementsByClassName("attributes"), function(i_e) { - i_e.parentNode.insertBefore(attributesToggle.cloneNode(true), i_e); + var attr_tog = attributesToggle.cloneNode(true); + if (hasClass(i_e, "top-attr") === true) { + addClass(attr_tog, "top-attr"); + } + i_e.parentNode.insertBefore(attr_tog, i_e); itemAttributesFunc(i_e); }); diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 2228e58b0d23..94e95d4e34e5 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1579,10 +1579,10 @@ div.name.expand::before { } /* This part is to fix the "Expand attributes" part in the type declaration. */ -.type-decl > pre > :first-child { +.type-decl > pre > .toggle-wrapper.toggle-attributes.top-attr { margin-left: 0 !important; } -.type-decl > pre > :nth-child(2) { +.type-decl > pre > .docblock.attributes.top-attr { margin-left: 1.8em !important; } .type-decl > pre > .toggle-attributes { From 19f1bade5fd8efb5e036ed2fadc0abd397cecb9f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 18 Apr 2019 23:06:49 +0200 Subject: [PATCH 011/239] Fix items alignment --- src/librustdoc/html/render.rs | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index e99cdb90b0ab..a2e843828f7a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3389,8 +3389,10 @@ fn assoc_const(w: &mut fmt::Formatter<'_>, it: &clean::Item, ty: &clean::Type, _default: Option<&String>, - link: AssocItemLink<'_>) -> fmt::Result { - write!(w, "{}const {}: {}", + link: AssocItemLink<'_>, + extra: &str) -> fmt::Result { + write!(w, "{}{}const {}: {}", + extra, VisSpace(&it.visibility), naive_assoc_href(it, link), it.name.as_ref().unwrap(), @@ -3401,8 +3403,10 @@ fn assoc_const(w: &mut fmt::Formatter<'_>, fn assoc_type(w: &mut W, it: &clean::Item, bounds: &[clean::GenericBound], default: Option<&clean::Type>, - link: AssocItemLink<'_>) -> fmt::Result { - write!(w, "type {}", + link: AssocItemLink<'_>, + extra: &str) -> fmt::Result { + write!(w, "{}type {}", + extra, naive_assoc_href(it, link), it.name.as_ref().unwrap())?; if !bounds.is_empty() { @@ -3513,10 +3517,12 @@ fn render_assoc_item(w: &mut fmt::Formatter<'_>, method(w, item, m.header, &m.generics, &m.decl, link, parent) } clean::AssociatedConstItem(ref ty, ref default) => { - assoc_const(w, item, ty, default.as_ref(), link) + assoc_const(w, item, ty, default.as_ref(), link, + if parent == ItemType::Trait { " " } else { "" }) } clean::AssociatedTypeItem(ref bounds, ref default) => { - assoc_type(w, item, bounds, default.as_ref(), link) + assoc_type(w, item, bounds, default.as_ref(), link, + if parent == ItemType::Trait { " " } else { "" }) } _ => panic!("render_assoc_item called on non-associated-item") } @@ -4129,7 +4135,8 @@ fn spotlight_decl(decl: &clean::FnDecl) -> Result { out.push_str(" "); assoc_type(&mut out, it, &[], Some(&tydef.type_), - AssocItemLink::GotoSource(t_did, &FxHashSet::default()))?; + AssocItemLink::GotoSource(t_did, &FxHashSet::default()), + "")?; out.push_str(";"); } } @@ -4165,7 +4172,8 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt if let clean::TypedefItem(ref tydef, _) = it.inner { write!(w, " ")?; assoc_type(w, it, &vec![], Some(&tydef.type_), - AssocItemLink::Anchor(None))?; + AssocItemLink::Anchor(None), + "")?; write!(w, ";")?; } } @@ -4235,7 +4243,7 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space())); write!(w, "

", id, item_type, extra_class)?; write!(w, "", ns_id)?; - assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id))?; + assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id), "")?; write!(w, "

")?; } clean::AssociatedConstItem(ref ty, ref default) => { @@ -4243,7 +4251,7 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space())); write!(w, "

", id, item_type, extra_class)?; write!(w, "", ns_id)?; - assoc_const(w, item, ty, default.as_ref(), link.anchor(&id))?; + assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), "")?; write!(w, "")?; render_stability_since_raw(w, item.stable_since(), outer_version)?; if let Some(l) = (Item { cx, item }).src_href() { @@ -4257,7 +4265,7 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space())); write!(w, "

", id, item_type, extra_class)?; write!(w, "", ns_id)?; - assoc_type(w, item, bounds, default.as_ref(), link.anchor(&id))?; + assoc_type(w, item, bounds, default.as_ref(), link.anchor(&id), "")?; write!(w, "

")?; } clean::StrippedItem(..) => return Ok(()), From f20d586c6fe90ac29f71b9568bd67e81e676c112 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 19 Apr 2019 10:20:18 +0200 Subject: [PATCH 012/239] Update test --- src/test/rustdoc/attributes.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/rustdoc/attributes.rs b/src/test/rustdoc/attributes.rs index eb0e3f065c7b..6ecdad3ec000 100644 --- a/src/test/rustdoc/attributes.rs +++ b/src/test/rustdoc/attributes.rs @@ -8,8 +8,8 @@ pub extern "C" fn f() {} #[export_name = "bar"] pub extern "C" fn g() {} -// @has foo/enum.Foo.html '//*[@class="docblock attributes"]' '#[repr(i64)]' -// @has foo/enum.Foo.html '//*[@class="docblock attributes"]' '#[must_use]' +// @has foo/enum.Foo.html '//*[@class="docblock attributes top-attr"]' '#[repr(i64)]' +// @has foo/enum.Foo.html '//*[@class="docblock attributes top-attr"]' '#[must_use]' #[repr(i64)] #[must_use] pub enum Foo { From 3e86cf36b5114f201868bf459934fe346a76a2d4 Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Fri, 19 Apr 2019 21:13:37 -0700 Subject: [PATCH 013/239] Add implementations of last in terms of next_back on a bunch of DoubleEndedIterators. r?Manishearth --- src/liballoc/collections/binary_heap.rs | 15 ++++++++++ src/liballoc/collections/btree/map.rs | 40 +++++++++++++++++++++++++ src/liballoc/collections/btree/set.rs | 15 ++++++++++ src/liballoc/string.rs | 4 +++ src/liballoc/vec.rs | 14 +++++++++ src/libcore/ascii.rs | 2 ++ src/libcore/iter/adapters/mod.rs | 5 ++++ src/libcore/slice/mod.rs | 20 +++++++++++++ src/libcore/str/mod.rs | 20 +++++++++++++ src/libstd/env.rs | 6 ++++ src/libstd/path.rs | 10 +++++++ src/libstd/sys/unix/args.rs | 2 ++ src/libstd/sys/wasm/args.rs | 4 +++ src/libstd/sys/windows/args.rs | 2 ++ 14 files changed, 159 insertions(+) diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index 8c142a3d317c..2b1e52cbf054 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -968,6 +968,11 @@ impl<'a, T> Iterator for Iter<'a, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1023,6 +1028,11 @@ impl Iterator for IntoIter { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1069,6 +1079,11 @@ impl Iterator for Drain<'_, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "drain", since = "1.6.0")] diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 6b079fc87cc7..414abb00ef1f 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -1193,6 +1193,11 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> { fn size_hint(&self) -> (usize, Option) { (self.length, Some(self.length)) } + + #[inline] + fn last(mut self) -> Option<(&'a K, &'a V)> { + self.next_back() + } } #[stable(feature = "fused", since = "1.26.0")] @@ -1253,6 +1258,11 @@ impl<'a, K: 'a, V: 'a> Iterator for IterMut<'a, K, V> { fn size_hint(&self) -> (usize, Option) { (self.length, Some(self.length)) } + + #[inline] + fn last(mut self) -> Option<(&'a K, &'a mut V)> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1359,6 +1369,11 @@ impl Iterator for IntoIter { fn size_hint(&self) -> (usize, Option) { (self.length, Some(self.length)) } + + #[inline] + fn last(mut self) -> Option<(K, V)> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1421,6 +1436,11 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a K> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1458,6 +1478,11 @@ impl<'a, K, V> Iterator for Values<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a V> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1495,6 +1520,11 @@ impl<'a, K, V> Iterator for Range<'a, K, V> { unsafe { Some(self.next_unchecked()) } } } + + #[inline] + fn last(mut self) -> Option<(&'a K, &'a V)> { + self.next_back() + } } #[stable(feature = "map_values_mut", since = "1.10.0")] @@ -1508,6 +1538,11 @@ impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a mut V> { + self.next_back() + } } #[stable(feature = "map_values_mut", since = "1.10.0")] @@ -1626,6 +1661,11 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> { unsafe { Some(self.next_unchecked()) } } } + + #[inline] + fn last(mut self) -> Option<(&'a K, &'a mut V)> { + self.next_back() + } } impl<'a, K, V> RangeMut<'a, K, V> { diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index 16a96ca19b82..6f2467dfd6b5 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -1019,6 +1019,11 @@ impl<'a, T> Iterator for Iter<'a, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> DoubleEndedIterator for Iter<'a, T> { @@ -1044,6 +1049,11 @@ impl Iterator for IntoIter { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for IntoIter { @@ -1073,6 +1083,11 @@ impl<'a, T> Iterator for Range<'a, T> { fn next(&mut self) -> Option<&'a T> { self.iter.next().map(|(k, _)| k) } + + #[inline] + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "btree_range", since = "1.17.0")] diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index a3e2098695f7..f01610a7c3f3 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -2367,6 +2367,10 @@ impl Iterator for Drain<'_> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "drain", since = "1.6.0")] diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index cd62c3e05244..50bb37b6ed27 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -2385,6 +2385,11 @@ impl Iterator for IntoIter { fn count(self) -> usize { self.len() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -2504,6 +2509,11 @@ impl Iterator for Drain<'_, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "drain", since = "1.6.0")] @@ -2573,6 +2583,10 @@ impl Iterator for Splice<'_, I> { fn size_hint(&self) -> (usize, Option) { self.drain.size_hint() } + + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "vec_splice", since = "1.21.0")] diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs index c0ab364380fb..ddee02ea232d 100644 --- a/src/libcore/ascii.rs +++ b/src/libcore/ascii.rs @@ -117,6 +117,8 @@ impl Iterator for EscapeDefault { type Item = u8; fn next(&mut self) -> Option { self.range.next().map(|i| self.data[i]) } fn size_hint(&self) -> (usize, Option) { self.range.size_hint() } + #[inline] + fn last(mut self) -> Option { self.next_back() } } #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for EscapeDefault { diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 3ab404a48d3d..d814e8a5958e 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -73,6 +73,11 @@ impl Iterator for Rev where I: DoubleEndedIterator { { self.iter.position(predicate) } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index bf3dda48dc79..cda4268607f9 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -3539,6 +3539,11 @@ impl<'a, T, P> Iterator for Split<'a, T, P> where P: FnMut(&T) -> bool { (1, Some(self.v.len() + 1)) } } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -3637,6 +3642,11 @@ impl<'a, T, P> Iterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { (1, Some(self.v.len() + 1)) } } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -3702,6 +3712,11 @@ impl<'a, T, P> Iterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "slice_rsplit", since = "1.27.0")] @@ -3766,6 +3781,11 @@ impl<'a, T, P> Iterator for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "slice_rsplit", since = "1.27.0")] diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 379c263c04ca..41399d219423 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1331,6 +1331,11 @@ impl<'a> Iterator for Lines<'a> { fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1377,6 +1382,11 @@ impl<'a> Iterator for LinesAny<'a> { fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -4215,6 +4225,11 @@ impl<'a> Iterator for SplitWhitespace<'a> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "split_whitespace", since = "1.1.0")] @@ -4241,6 +4256,11 @@ impl<'a> Iterator for SplitAsciiWhitespace<'a> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 01b301cb43d5..6cb160067f7e 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -740,6 +740,10 @@ impl Iterator for Args { self.inner.next().map(|s| s.into_string().unwrap()) } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "env", since = "1.0.0")] @@ -775,6 +779,8 @@ impl Iterator for ArgsOs { type Item = OsString; fn next(&mut self) -> Option { self.inner.next() } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + #[inline] + fn last(mut self) -> Option { self.next_back() } } #[stable(feature = "env", since = "1.0.0")] diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 1bbda9b5bcb1..79ba37b2eb56 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -886,6 +886,11 @@ impl<'a> Iterator for Iter<'a> { fn next(&mut self) -> Option<&'a OsStr> { self.inner.next().map(Component::as_os_str) } + + #[inline] + fn last(mut self) -> Option<&'a OsStr> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -949,6 +954,11 @@ impl<'a> Iterator for Components<'a> { } None } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs index 18de1096df2a..f0594bb21bd8 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -35,6 +35,8 @@ impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { self.iter.next() } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + #[inline] + fn last(mut self) -> Option { self.next_back() } } impl ExactSizeIterator for Args { diff --git a/src/libstd/sys/wasm/args.rs b/src/libstd/sys/wasm/args.rs index b3c77b869956..6766099c1ece 100644 --- a/src/libstd/sys/wasm/args.rs +++ b/src/libstd/sys/wasm/args.rs @@ -37,6 +37,10 @@ impl Iterator for Args { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } impl ExactSizeIterator for Args { diff --git a/src/libstd/sys/windows/args.rs b/src/libstd/sys/windows/args.rs index b04bb484eedb..744d7ec59d3a 100644 --- a/src/libstd/sys/windows/args.rs +++ b/src/libstd/sys/windows/args.rs @@ -181,6 +181,8 @@ impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { self.parsed_args_list.next() } fn size_hint(&self) -> (usize, Option) { self.parsed_args_list.size_hint() } + #[inline] + fn last(mut self) -> Option { self.next_back() } } impl DoubleEndedIterator for Args { From d9ea132b7322cebd595598a0639cf6018816d454 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Mon, 22 Apr 2019 18:20:19 +0100 Subject: [PATCH 014/239] Explain error when yielding a reference to a local variable --- .../borrow_check/error_reporting.rs | 34 ++++++--- .../borrow_check/nll/explain_borrow/mod.rs | 4 ++ .../error_reporting/region_name.rs | 71 +++++++++++++++++-- src/librustc_mir/util/borrowck_errors.rs | 6 +- src/test/ui/nll/issue-55850.rs | 2 +- src/test/ui/nll/issue-55850.stderr | 16 ++--- 6 files changed, 107 insertions(+), 26 deletions(-) diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 3ab0996d3a17..956e8c562727 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -826,18 +826,21 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let borrow_span = borrow_spans.var_or_use(); if let BorrowExplanation::MustBeValidFor { - category: ConstraintCategory::Return, + category, span, ref opt_place_desc, from_closure: false, .. } = explanation { - return self.report_cannot_return_reference_to_local( + if let Some(diag) = self.try_report_cannot_return_reference_to_local( borrow, borrow_span, span, + category, opt_place_desc.as_ref(), - ); + ) { + return diag; + } } let mut err = self.infcx.tcx.path_does_not_live_long_enough( @@ -1015,17 +1018,20 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ); if let BorrowExplanation::MustBeValidFor { - category: ConstraintCategory::Return, + category, span, from_closure: false, .. } = explanation { - return self.report_cannot_return_reference_to_local( + if let Some(diag) = self.try_report_cannot_return_reference_to_local( borrow, proper_span, span, + category, None, - ); + ) { + return diag; + } } let tcx = self.infcx.tcx; @@ -1064,15 +1070,22 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { err } - fn report_cannot_return_reference_to_local( + fn try_report_cannot_return_reference_to_local( &self, borrow: &BorrowData<'tcx>, borrow_span: Span, return_span: Span, + category: ConstraintCategory, opt_place_desc: Option<&String>, - ) -> DiagnosticBuilder<'cx> { + ) -> Option> { let tcx = self.infcx.tcx; + let return_kind = match category { + ConstraintCategory::Return => "return", + ConstraintCategory::Yield => "yield", + _ => return None, + }; + // FIXME use a better heuristic than Spans let reference_desc = if return_span == self.mir.source_info(borrow.reserve_location).span { "reference to" @@ -1110,7 +1123,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let local = if let Place::Base(PlaceBase::Local(local)) = *root_place { local } else { - bug!("report_cannot_return_reference_to_local: not a local") + bug!("try_report_cannot_return_reference_to_local: not a local") }; match self.mir.local_kind(local) { LocalKind::ReturnPointer | LocalKind::Temp => { @@ -1131,6 +1144,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let mut err = tcx.cannot_return_reference_to_local( return_span, + return_kind, reference_desc, &place_desc, Origin::Mir, @@ -1140,7 +1154,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { err.span_label(borrow_span, note); } - err + Some(err) } fn report_escaping_closure_capture( diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index 5ad54080c5a6..5b1c64039bee 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -313,9 +313,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { opt_place_desc, } } else { + debug!("explain_why_borrow_contains_point: \ + Could not generate a region name"); BorrowExplanation::Unexplained } } else { + debug!("explain_why_borrow_contains_point: \ + Could not generate an error region vid"); BorrowExplanation::Unexplained } } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index 362214d32571..e72d4c9e3d57 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -32,6 +32,7 @@ crate enum RegionNameSource { MatchedAdtAndSegment(Span), AnonRegionFromUpvar(Span, String), AnonRegionFromOutput(Span, String, String), + AnonRegionFromYieldTy(Span, String), } impl RegionName { @@ -46,7 +47,8 @@ impl RegionName { RegionNameSource::MatchedHirTy(..) | RegionNameSource::MatchedAdtAndSegment(..) | RegionNameSource::AnonRegionFromUpvar(..) | - RegionNameSource::AnonRegionFromOutput(..) => false, + RegionNameSource::AnonRegionFromOutput(..) | + RegionNameSource::AnonRegionFromYieldTy(..) => false, } } @@ -103,6 +105,12 @@ impl RegionName { format!("return type{} is {}", mir_description, type_name), ); }, + RegionNameSource::AnonRegionFromYieldTy(span, type_name) => { + diag.span_label( + *span, + format!("yield type is {}", type_name), + ); + } RegionNameSource::Static => {}, } } @@ -167,6 +175,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.give_name_if_anonymous_region_appears_in_output( infcx, mir, mir_def_id, fr, counter, ) + }) + .or_else(|| { + self.give_name_if_anonymous_region_appears_in_yield_ty( + infcx, mir, mir_def_id, fr, counter, + ) }); debug!("give_region_a_name: gave name {:?}", value); @@ -673,10 +686,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { "give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty ); - if !infcx - .tcx - .any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) - { + if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) { return None; } @@ -721,6 +731,57 @@ impl<'tcx> RegionInferenceContext<'tcx> { }) } + fn give_name_if_anonymous_region_appears_in_yield_ty( + &self, + infcx: &InferCtxt<'_, '_, 'tcx>, + mir: &Mir<'tcx>, + mir_def_id: DefId, + fr: RegionVid, + counter: &mut usize, + ) -> Option { + // Note: generators from `async fn` yield `()`, so we don't have to + // worry about them here. + let yield_ty = self.universal_regions.yield_ty?; + debug!( + "give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}", + yield_ty, + ); + + let tcx = infcx.tcx; + + if !tcx.any_free_region_meets(&yield_ty, |r| r.to_region_vid() == fr) { + return None; + } + + let mut highlight = RegionHighlightMode::default(); + highlight.highlighting_region_vid(fr, *counter); + let type_name = infcx.extract_type_name(&yield_ty, Some(highlight)); + + let mir_node_id = tcx.hir().as_local_node_id(mir_def_id).expect("non-local mir"); + + let yield_span = match tcx.hir().get(mir_node_id) { + hir::Node::Expr(hir::Expr { + node: hir::ExprKind::Closure(_, _, _, span, _), + .. + }) => ( + tcx.sess.source_map().end_point(*span) + ), + _ => mir.span, + }; + + debug!( + "give_name_if_anonymous_region_appears_in_yield_ty: \ + type_name = {:?}, yield_span = {:?}", + yield_span, + type_name, + ); + + Some(RegionName { + name: self.synthesize_region_name(counter), + source: RegionNameSource::AnonRegionFromYieldTy(yield_span, type_name), + }) + } + /// Creates a synthetic region named `'1`, incrementing the /// counter. fn synthesize_region_name(&self, counter: &mut usize) -> InternedString { diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs index e334e27cc855..0cbe39ab6d43 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/src/librustc_mir/util/borrowck_errors.rs @@ -650,6 +650,7 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { fn cannot_return_reference_to_local( self, span: Span, + return_kind: &str, reference_desc: &str, path_desc: &str, o: Origin, @@ -658,7 +659,8 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { self, span, E0515, - "cannot return {REFERENCE} {LOCAL}{OGN}", + "cannot {RETURN} {REFERENCE} {LOCAL}{OGN}", + RETURN=return_kind, REFERENCE=reference_desc, LOCAL=path_desc, OGN = o @@ -666,7 +668,7 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { err.span_label( span, - format!("returns a {} data owned by the current function", reference_desc), + format!("{}s a {} data owned by the current function", return_kind, reference_desc), ); self.cancel_if_wrong_origin(err, o) diff --git a/src/test/ui/nll/issue-55850.rs b/src/test/ui/nll/issue-55850.rs index 8a016bf87795..a8f7299f8993 100644 --- a/src/test/ui/nll/issue-55850.rs +++ b/src/test/ui/nll/issue-55850.rs @@ -25,7 +25,7 @@ where fn bug<'a>() -> impl Iterator { GenIter(move || { let mut s = String::new(); - yield &s[..] //~ ERROR `s` does not live long enough [E0597] + yield &s[..] //~ ERROR cannot yield value referencing local variable `s` [E0515] //~| ERROR borrow may still be in use when generator yields }) } diff --git a/src/test/ui/nll/issue-55850.stderr b/src/test/ui/nll/issue-55850.stderr index 66c2995efc88..86a8cdc42ff9 100644 --- a/src/test/ui/nll/issue-55850.stderr +++ b/src/test/ui/nll/issue-55850.stderr @@ -1,11 +1,11 @@ -error[E0597]: `s` does not live long enough - --> $DIR/issue-55850.rs:28:16 +error[E0515]: cannot yield value referencing local variable `s` + --> $DIR/issue-55850.rs:28:9 | LL | yield &s[..] - | ^ borrowed value does not live long enough -LL | -LL | }) - | - `s` dropped here while still borrowed + | ^^^^^^^-^^^^ + | | | + | | `s` is borrowed here + | yields a value referencing data owned by the current function error[E0626]: borrow may still be in use when generator yields --> $DIR/issue-55850.rs:28:16 @@ -15,5 +15,5 @@ LL | yield &s[..] error: aborting due to 2 previous errors -Some errors have detailed explanations: E0597, E0626. -For more information about an error, try `rustc --explain E0597`. +Some errors have detailed explanations: E0515, E0626. +For more information about an error, try `rustc --explain E0515`. From 4cb6d1c523ce375388622477e8020117a89d0c1d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 23 Apr 2019 17:51:10 +0200 Subject: [PATCH 015/239] deny -> warn --- src/libcore/tests/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 2e4a8a15d208..f168458bff1d 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -32,7 +32,7 @@ #![feature(slice_partition_dedup)] #![feature(copy_within)] #![feature(int_error_matching)] -#![deny(rust_2018_idioms)] +#![warn(rust_2018_idioms)] extern crate test; From 28234751bca49922023f1653f67831a81d038461 Mon Sep 17 00:00:00 2001 From: Felix Rabe Date: Tue, 23 Apr 2019 20:27:09 +0200 Subject: [PATCH 016/239] Outdent example, preserving nested fence --- src/doc/rustdoc/src/what-is-rustdoc.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/doc/rustdoc/src/what-is-rustdoc.md b/src/doc/rustdoc/src/what-is-rustdoc.md index 54472e35b1b2..bbcacb7f3d5d 100644 --- a/src/doc/rustdoc/src/what-is-rustdoc.md +++ b/src/doc/rustdoc/src/what-is-rustdoc.md @@ -98,21 +98,21 @@ documentation for them as well! `rustdoc` can also generate HTML from standalone Markdown files. Let's give it a try: create a `README.md` file with these contents: -```text - # Docs +````text +# Docs - This is a project to test out `rustdoc`. +This is a project to test out `rustdoc`. - [Here is a link!](https://www.rust-lang.org) +[Here is a link!](https://www.rust-lang.org) - ## Subheading +## Subheading - ```rust - fn foo() -> i32 { - 1 + 1 - } - ``` +```rust +fn foo() -> i32 { + 1 + 1 +} ``` +```` And call `rustdoc` on it: From 885a001788d18dbbde14587e1dbccca0dad73776 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 24 Apr 2019 21:15:25 +0200 Subject: [PATCH 017/239] const-stabilize NonNull::dangling and NonNull::cast --- src/libcore/ptr.rs | 2 -- src/test/run-pass/consts/const-ptr-nonnull.rs | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index f05700a1db28..eee83ba5ebd3 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2959,7 +2959,6 @@ impl NonNull { /// some other means. #[stable(feature = "nonnull", since = "1.25.0")] #[inline] - #[rustc_const_unstable(feature = "const_ptr_nonnull")] pub const fn dangling() -> Self { unsafe { let ptr = mem::align_of::() as *mut T; @@ -3023,7 +3022,6 @@ impl NonNull { /// Cast to a pointer of another type #[stable(feature = "nonnull_cast", since = "1.27.0")] #[inline] - #[rustc_const_unstable(feature = "const_ptr_nonnull")] pub const fn cast(self) -> NonNull { unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) diff --git a/src/test/run-pass/consts/const-ptr-nonnull.rs b/src/test/run-pass/consts/const-ptr-nonnull.rs index 91624e92fbe7..c5b9d837b47a 100644 --- a/src/test/run-pass/consts/const-ptr-nonnull.rs +++ b/src/test/run-pass/consts/const-ptr-nonnull.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(const_ptr_nonnull)] - use std::ptr::NonNull; const DANGLING: NonNull = NonNull::dangling(); From 8a47e088458866b6dd8aa28acc9db1e9e22be997 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 25 Apr 2019 07:53:06 +0100 Subject: [PATCH 018/239] Add test for current behaviour. This commit adds a test that causes a suggestion to replace `extern crate` with `use` when doing so would cause a compliation error, as the new name of the import would not be added to the prelude if a `use` was used. --- src/test/ui/suggestions/issue-57672.rs | 14 ++++++++++++++ src/test/ui/suggestions/issue-57672.stderr | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/test/ui/suggestions/issue-57672.rs create mode 100644 src/test/ui/suggestions/issue-57672.stderr diff --git a/src/test/ui/suggestions/issue-57672.rs b/src/test/ui/suggestions/issue-57672.rs new file mode 100644 index 000000000000..c8ea6e59582f --- /dev/null +++ b/src/test/ui/suggestions/issue-57672.rs @@ -0,0 +1,14 @@ +// aux-build:foo.rs +// compile-flags:--extern foo +// edition:2018 + +#![deny(unused_extern_crates)] + +extern crate foo as foo_renamed; +//~^ ERROR `extern crate` is not idiomatic in the new edition + +pub mod m { + pub use foo_renamed::Foo; +} + +fn main() {} diff --git a/src/test/ui/suggestions/issue-57672.stderr b/src/test/ui/suggestions/issue-57672.stderr new file mode 100644 index 000000000000..c9e4c373799e --- /dev/null +++ b/src/test/ui/suggestions/issue-57672.stderr @@ -0,0 +1,14 @@ +error: `extern crate` is not idiomatic in the new edition + --> $DIR/issue-57672.rs:7:1 + | +LL | extern crate foo as foo_renamed; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` + | +note: lint level defined here + --> $DIR/issue-57672.rs:5:9 + | +LL | #![deny(unused_extern_crates)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From 8869bc5adade466e9eca01172dfd257f14ab3392 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 25 Apr 2019 08:06:49 +0100 Subject: [PATCH 019/239] Do not suggest use over extern crate w/ alias. This commit stops `unused_extern_crates` lints from occuring on `extern crate` statements that alias the crate as the suggestion to change to a `use` statement would result in the aliased name no longer being added to the prelude, thereby causing compilation errors if other imports expected this to be the case. --- src/librustc_typeck/check_unused.rs | 7 ++++ src/test/ui/imports/extern-crate-used.rs | 12 ++++--- src/test/ui/imports/extern-crate-used.stderr | 34 +++---------------- .../extern-crate-idiomatic-in-2018.fixed | 7 ++-- .../extern-crate-idiomatic-in-2018.rs | 5 ++- .../extern-crate-idiomatic-in-2018.stderr | 8 +---- .../ui/rust-2018/remove-extern-crate.fixed | 6 +++- src/test/ui/rust-2018/remove-extern-crate.rs | 4 +++ .../ui/rust-2018/remove-extern-crate.stderr | 8 +---- src/test/ui/suggestions/issue-57672.rs | 2 +- src/test/ui/suggestions/issue-57672.stderr | 14 -------- 11 files changed, 41 insertions(+), 66 deletions(-) delete mode 100644 src/test/ui/suggestions/issue-57672.stderr diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index cbb6d9b29f59..3c3509f24ce1 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -158,6 +158,13 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) { continue; } + // If the extern crate is renamed, then we cannot suggest replacing it with a use as this + // would not insert the new name into the prelude, where other imports in the crate may be + // expecting it. + if extern_crate.orig_name.is_some() { + continue; + } + // If the extern crate has any attributes, they may have funky // semantics we can't faithfully represent using `use` (most // notably `#[macro_use]`). Ignore it. diff --git a/src/test/ui/imports/extern-crate-used.rs b/src/test/ui/imports/extern-crate-used.rs index 2d91cbc00f27..26150c7d4a16 100644 --- a/src/test/ui/imports/extern-crate-used.rs +++ b/src/test/ui/imports/extern-crate-used.rs @@ -5,10 +5,14 @@ #![deny(unused_extern_crates)] -extern crate core as iso1; //~ ERROR `extern crate` is not idiomatic in the new edition -extern crate core as iso2; //~ ERROR `extern crate` is not idiomatic in the new edition -extern crate core as iso3; //~ ERROR `extern crate` is not idiomatic in the new edition -extern crate core as iso4; //~ ERROR `extern crate` is not idiomatic in the new edition +// Shouldn't suggest changing to `use`, as new name +// would no longer be added to the prelude which could cause +// compilation errors for imports that use the new name in +// other modules. See #57672. +extern crate core as iso1; +extern crate core as iso2; +extern crate core as iso3; +extern crate core as iso4; // Doesn't introduce its extern prelude entry, so it's still considered unused. extern crate core; //~ ERROR unused extern crate diff --git a/src/test/ui/imports/extern-crate-used.stderr b/src/test/ui/imports/extern-crate-used.stderr index c0783feb7947..397bfa02902c 100644 --- a/src/test/ui/imports/extern-crate-used.stderr +++ b/src/test/ui/imports/extern-crate-used.stderr @@ -1,8 +1,8 @@ -error: `extern crate` is not idiomatic in the new edition - --> $DIR/extern-crate-used.rs:8:1 +error: unused extern crate + --> $DIR/extern-crate-used.rs:18:1 | -LL | extern crate core as iso1; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` +LL | extern crate core; + | ^^^^^^^^^^^^^^^^^^ help: remove it | note: lint level defined here --> $DIR/extern-crate-used.rs:6:9 @@ -10,29 +10,5 @@ note: lint level defined here LL | #![deny(unused_extern_crates)] | ^^^^^^^^^^^^^^^^^^^^ -error: `extern crate` is not idiomatic in the new edition - --> $DIR/extern-crate-used.rs:9:1 - | -LL | extern crate core as iso2; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` - -error: `extern crate` is not idiomatic in the new edition - --> $DIR/extern-crate-used.rs:10:1 - | -LL | extern crate core as iso3; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` - -error: `extern crate` is not idiomatic in the new edition - --> $DIR/extern-crate-used.rs:11:1 - | -LL | extern crate core as iso4; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` - -error: unused extern crate - --> $DIR/extern-crate-used.rs:14:1 - | -LL | extern crate core; - | ^^^^^^^^^^^^^^^^^^ help: remove it - -error: aborting due to 5 previous errors +error: aborting due to previous error diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed index ddd9abbd50ed..e51ce5d1d5b8 100644 --- a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed +++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed @@ -12,8 +12,11 @@ //~^ ERROR unused extern crate -use edition_lint_paths as bar; -//~^ ERROR `extern crate` is not idiomatic in the new edition +// Shouldn't suggest changing to `use`, as `bar` +// would no longer be added to the prelude which could cause +// compilation errors for imports that use `bar` in other +// modules. See #57672. +extern crate edition_lint_paths as bar; fn main() { // This is not considered to *use* the `extern crate` in Rust 2018: diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs index 47674bc19fc0..debbf085d618 100644 --- a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs +++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs @@ -12,8 +12,11 @@ extern crate edition_lint_paths; //~^ ERROR unused extern crate +// Shouldn't suggest changing to `use`, as `bar` +// would no longer be added to the prelude which could cause +// compilation errors for imports that use `bar` in other +// modules. See #57672. extern crate edition_lint_paths as bar; -//~^ ERROR `extern crate` is not idiomatic in the new edition fn main() { // This is not considered to *use* the `extern crate` in Rust 2018: diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr index f3f919394866..13980c70a82a 100644 --- a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr +++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr @@ -11,11 +11,5 @@ LL | #![deny(rust_2018_idioms)] | ^^^^^^^^^^^^^^^^ = note: #[deny(unused_extern_crates)] implied by #[deny(rust_2018_idioms)] -error: `extern crate` is not idiomatic in the new edition - --> $DIR/extern-crate-idiomatic-in-2018.rs:15:1 - | -LL | extern crate edition_lint_paths as bar; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/rust-2018/remove-extern-crate.fixed b/src/test/ui/rust-2018/remove-extern-crate.fixed index 17449caf84fb..14575d18c236 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.fixed +++ b/src/test/ui/rust-2018/remove-extern-crate.fixed @@ -7,7 +7,11 @@ #![warn(rust_2018_idioms)] -use core as another_name; +// Shouldn't suggest changing to `use`, as `another_name` +// would no longer be added to the prelude which could cause +// compilation errors for imports that use `another_name` in other +// modules. See #57672. +extern crate core as another_name; use remove_extern_crate; #[macro_use] extern crate remove_extern_crate as something_else; diff --git a/src/test/ui/rust-2018/remove-extern-crate.rs b/src/test/ui/rust-2018/remove-extern-crate.rs index fb2217df0005..0ee85f34e40d 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.rs +++ b/src/test/ui/rust-2018/remove-extern-crate.rs @@ -7,6 +7,10 @@ #![warn(rust_2018_idioms)] extern crate core; +// Shouldn't suggest changing to `use`, as `another_name` +// would no longer be added to the prelude which could cause +// compilation errors for imports that use `another_name` in other +// modules. See #57672. extern crate core as another_name; use remove_extern_crate; #[macro_use] diff --git a/src/test/ui/rust-2018/remove-extern-crate.stderr b/src/test/ui/rust-2018/remove-extern-crate.stderr index 549693201b70..5de0dfe96133 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.stderr +++ b/src/test/ui/rust-2018/remove-extern-crate.stderr @@ -12,13 +12,7 @@ LL | #![warn(rust_2018_idioms)] = note: #[warn(unused_extern_crates)] implied by #[warn(rust_2018_idioms)] warning: `extern crate` is not idiomatic in the new edition - --> $DIR/remove-extern-crate.rs:10:1 - | -LL | extern crate core as another_name; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` - -warning: `extern crate` is not idiomatic in the new edition - --> $DIR/remove-extern-crate.rs:28:5 + --> $DIR/remove-extern-crate.rs:32:5 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ help: convert it to a `use` diff --git a/src/test/ui/suggestions/issue-57672.rs b/src/test/ui/suggestions/issue-57672.rs index c8ea6e59582f..1773f72fc741 100644 --- a/src/test/ui/suggestions/issue-57672.rs +++ b/src/test/ui/suggestions/issue-57672.rs @@ -1,11 +1,11 @@ // aux-build:foo.rs // compile-flags:--extern foo +// compile-pass // edition:2018 #![deny(unused_extern_crates)] extern crate foo as foo_renamed; -//~^ ERROR `extern crate` is not idiomatic in the new edition pub mod m { pub use foo_renamed::Foo; diff --git a/src/test/ui/suggestions/issue-57672.stderr b/src/test/ui/suggestions/issue-57672.stderr deleted file mode 100644 index c9e4c373799e..000000000000 --- a/src/test/ui/suggestions/issue-57672.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: `extern crate` is not idiomatic in the new edition - --> $DIR/issue-57672.rs:7:1 - | -LL | extern crate foo as foo_renamed; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` - | -note: lint level defined here - --> $DIR/issue-57672.rs:5:9 - | -LL | #![deny(unused_extern_crates)] - | ^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - From 2e3d5c866fdead26f9e0e2b5620b236fea95c0e7 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 25 Apr 2019 11:40:01 -0700 Subject: [PATCH 020/239] Document the `html_root_url` doc attribute value. --- src/doc/rustdoc/src/the-doc-attribute.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/doc/rustdoc/src/the-doc-attribute.md b/src/doc/rustdoc/src/the-doc-attribute.md index 61e5b3d0133f..b165c5a6b3b9 100644 --- a/src/doc/rustdoc/src/the-doc-attribute.md +++ b/src/doc/rustdoc/src/the-doc-attribute.md @@ -92,6 +92,21 @@ the tracking issue. #![doc(issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")] ``` +### `html_root_url` + +The `#[doc(html_root_url = "…")]` attribute value indicates the URL for +generating links to external crates. When rustdoc needs to generate a link to +an item in an external crate, it will first check if the extern crate has been +documented locally on-disk, and if so link directly to it. Failing that, it +will use the URL given by the `--extern-html-root-url` command-line flag if +available. If that is not available, then it will use the `html_root_url` +value in the extern crate if it is available. If that is not available, then +the extern items will not be linked. + +```rust,ignore +#![doc(html_root_url = "https://docs.rs/serde/1.0")] +``` + ### `html_no_source` By default, `rustdoc` will include the source code of your program, with links From 5a3625d426bbd143e8178ae76e4d7939c6c96024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20St=C3=A5hl?= Date: Thu, 25 Apr 2019 19:06:04 +0200 Subject: [PATCH 021/239] Explicitly set height on rust logo element in docs The layout of the left side menu in docs reflows when navigating between pages because of missing height on the element of rust logo. Setting height='100' tells the browser to reserve that vertical space, leading to a less janky experience. --- src/librustdoc/html/layout.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index acf019fd2254..7453c90bf96c 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -183,13 +183,13 @@ pub fn render( if layout.logo.is_empty() { format!("\ logo", + alt='logo' width='100' height='100'>", path=p, static_root_path=static_root_path, suffix=page.resource_suffix) } else { format!("\ - logo", + logo", p, layout.logo) } From f998182fb40cace8de8981bd641a8fb93632a4a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20St=C3=A5hl?= Date: Thu, 25 Apr 2019 19:06:04 +0200 Subject: [PATCH 022/239] Revert "Explicitly set height on rust logo element in docs" This reverts commit d79a01b72f4722611cb21b719e6243aad3e7ec3c. --- src/librustdoc/html/layout.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 7453c90bf96c..acf019fd2254 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -183,13 +183,13 @@ pub fn render( if layout.logo.is_empty() { format!("\ logo", + alt='logo' width='100'>", path=p, static_root_path=static_root_path, suffix=page.resource_suffix) } else { format!("\ - logo", + logo", p, layout.logo) } From 184e3a3f92295fad81460ca13f9e845a2a5ff74a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20St=C3=A5hl?= Date: Sat, 27 Apr 2019 15:09:57 +0200 Subject: [PATCH 023/239] Wrap logo in container to prevent layout reflow --- src/librustdoc/html/layout.rs | 6 ++++-- src/librustdoc/html/static/rustdoc.css | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index acf019fd2254..7176abc3db87 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -182,14 +182,16 @@ pub fn render( let p = SlashChecker(&p); if layout.logo.is_empty() { format!("\ +
\ logo", + alt='logo' width='100'>
", path=p, static_root_path=static_root_path, suffix=page.resource_suffix) } else { format!("\ - logo", +
\ + logo
", p, layout.logo) } diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 53b08cf56978..66236d7cb450 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -182,6 +182,11 @@ nav.sub { display: none !important; } +.logo-container { + height: 0; + padding-bottom: 50%; +} + .sidebar img { margin: 20px auto; display: block; From 9db0fd7fd6a09969c3f3a0018599cef9e12b4ba9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 29 Apr 2019 11:45:06 +0200 Subject: [PATCH 024/239] Fix image position and display --- src/librustdoc/html/layout.rs | 6 ++---- src/librustdoc/html/static/rustdoc.css | 26 ++++++++++++++++++++------ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 7176abc3db87..ae0bd1aafa8f 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -183,15 +183,13 @@ pub fn render( if layout.logo.is_empty() { format!("\
\ - logo
", + logo", path=p, static_root_path=static_root_path, suffix=page.resource_suffix) } else { format!("\ -
\ - logo
", +
logo
", p, layout.logo) } diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 66236d7cb450..f9d00cad7170 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -183,16 +183,24 @@ nav.sub { } .logo-container { - height: 0; - padding-bottom: 50%; -} - -.sidebar img { + height: 100px; + width: 100px; + position: relative; margin: 20px auto; display: block; margin-top: 10px; } +.logo-container > img { + max-width: 100px; + max-height: 100px; + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + display: block; +} + .sidebar .location { border: 1px solid; font-size: 17px; @@ -1035,14 +1043,20 @@ span.since { padding: 0; } - .sidebar img { + .sidebar .logo-container { width: 35px; + height: 35px; margin-top: 5px; margin-bottom: 5px; float: left; margin-left: 50px; } + .sidebar .logo-container > img { + max-width: 35px; + max-height: 35px; + } + .sidebar-menu { position: fixed; z-index: 10; From 24d89e5016d269637712e9b3806f07234d59a650 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Fri, 26 Apr 2019 12:45:26 -0700 Subject: [PATCH 025/239] impl From for TryFromSliceError --- src/libcore/array.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libcore/array.rs b/src/libcore/array.rs index fb9c99f667df..50b3ef477904 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -11,7 +11,7 @@ use crate::borrow::{Borrow, BorrowMut}; use crate::cmp::Ordering; -use crate::convert::TryFrom; +use crate::convert::{Infallible, TryFrom}; use crate::fmt; use crate::hash::{Hash, self}; use crate::marker::Unsize; @@ -72,6 +72,13 @@ impl TryFromSliceError { } } +#[stable(feature = "try_from_slice_error", since = "1.36.0")] +impl From for TryFromSliceError { + fn from(x: Infallible) -> TryFromSliceError { + match x {} + } +} + macro_rules! __impl_slice_eq1 { ($Lhs: ty, $Rhs: ty) => { __impl_slice_eq1! { $Lhs, $Rhs, Sized } From 9b3583375dbd45b19b8ce8822b89ff79529354d6 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 29 Apr 2019 18:32:05 -0700 Subject: [PATCH 026/239] Document the order of {Vec,VecDeque,String}::retain It's natural for `retain` to work in order from beginning to end, but this wasn't actually documented to be the case. If we actually promise this, then the caller can do useful things like track the index of each element being tested, as [discussed in the forum][1]. This is now documented for `Vec`, `VecDeque`, and `String`. [1]: https://users.rust-lang.org/t/vec-retain-by-index/27697 `HashMap` and `HashSet` also have `retain`, and the `hashbrown` implementation does happen to use a plain `iter()` order too, but it's not certain that this should always be the case for these types. --- src/liballoc/collections/vec_deque.rs | 4 ++-- src/liballoc/string.rs | 4 ++-- src/liballoc/vec.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index d65c24f7350a..82a60f924444 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -1835,8 +1835,8 @@ impl VecDeque { /// Retains only the elements specified by the predicate. /// /// In other words, remove all elements `e` such that `f(&e)` returns false. - /// This method operates in place and preserves the order of the retained - /// elements. + /// This method operates in place, visiting each element exactly once in the + /// original order, and preserves the order of the retained elements. /// /// # Examples /// diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index a3e2098695f7..aaa381426933 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1200,8 +1200,8 @@ impl String { /// Retains only the characters specified by the predicate. /// /// In other words, remove all characters `c` such that `f(c)` returns `false`. - /// This method operates in place and preserves the order of the retained - /// characters. + /// This method operates in place, visiting each character exactly once in the + /// original order, and preserves the order of the retained characters. /// /// # Examples /// diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index cd62c3e05244..a9bc835010ff 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -937,8 +937,8 @@ impl Vec { /// Retains only the elements specified by the predicate. /// /// In other words, remove all elements `e` such that `f(&e)` returns `false`. - /// This method operates in place and preserves the order of the retained - /// elements. + /// This method operates in place, visiting each element exactly once in the + /// original order, and preserves the order of the retained elements. /// /// # Examples /// From 67ca448dac4ccf189e2c708be3f3569b70ee2698 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 29 Apr 2019 23:24:09 +0200 Subject: [PATCH 027/239] Improve file sidebar in source code view page on mobile --- src/librustdoc/html/static/rustdoc.css | 78 +++++++++++++++----------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 358549117a30..82ef6a410a30 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1232,6 +1232,39 @@ h4 > .important-traits { margin: 5px 0; } +#sidebar-toggle { + position: fixed; + top: 30px; + left: 300px; + z-index: 10; + padding: 3px; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + cursor: pointer; + font-weight: bold; + transition: left .5s; + font-size: 1.2em; + border: 1px solid; + border-left: 0; +} +#source-sidebar { + position: fixed; + top: 0; + bottom: 0; + left: 0; + width: 300px; + z-index: 1; + overflow: auto; + transition: left .5s; + border-right: 1px solid; +} +#source-sidebar > .title { + font-size: 1.5em; + text-align: center; + border-bottom: 1px solid; + margin-bottom: 6px; +} + @media (max-width: 700px) { h4 > .important-traits { position: absolute; @@ -1307,6 +1340,18 @@ h4 > .important-traits { #all-types { margin: 10px; } + + #sidebar-toggle { + top: 100px; + width: 30px; + font-size: 1.5rem; + text-align: center; + padding: 0; + } + + #source-sidebar { + z-index: 11; + } } @@ -1516,39 +1561,6 @@ kbd { margin-bottom: 1em; } -#sidebar-toggle { - position: fixed; - top: 30px; - left: 300px; - z-index: 10; - padding: 3px; - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; - cursor: pointer; - font-weight: bold; - transition: left .5s; - font-size: 1.2em; - border: 1px solid; - border-left: 0; -} -#source-sidebar { - position: fixed; - top: 0; - bottom: 0; - left: 0; - width: 300px; - z-index: 1; - overflow: auto; - transition: left .5s; - border-right: 1px solid; -} -#source-sidebar > .title { - font-size: 1.5em; - text-align: center; - border-bottom: 1px solid; - margin-bottom: 6px; -} - div.children { padding-left: 27px; display: none; From 87d1c17683b7911522e3bcc223a308c82702f7d8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 29 Apr 2019 23:43:39 +0200 Subject: [PATCH 028/239] Cleanup media queries --- src/librustdoc/html/static/rustdoc.css | 363 ++++++++++++------------- 1 file changed, 179 insertions(+), 184 deletions(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 82ef6a410a30..70984ea3e72a 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -998,133 +998,6 @@ span.since { opacity: 1; } -/* Media Queries */ - -@media (max-width: 700px) { - body { - padding-top: 0px; - } - - .rustdoc > .sidebar { - height: 45px; - min-height: 40px; - margin: 0; - margin-left: -15px; - padding: 0 15px; - position: static; - z-index: 11; - } - - .sidebar > .location { - float: right; - margin: 0px; - margin-top: 2px; - padding: 3px 10px 1px 10px; - min-height: 39px; - background: inherit; - text-align: left; - font-size: 24px; - } - - .sidebar .location:empty { - padding: 0; - } - - .sidebar img { - width: 35px; - margin-top: 5px; - margin-bottom: 5px; - float: left; - margin-left: 50px; - } - - .sidebar-menu { - position: fixed; - z-index: 10; - font-size: 2rem; - cursor: pointer; - width: 45px; - left: 0; - text-align: center; - display: block; - border-bottom: 1px solid; - border-right: 1px solid; - height: 45px; - } - - .sidebar-elems { - position: fixed; - z-index: 1; - left: 0; - top: 45px; - bottom: 0; - overflow-y: auto; - border-right: 1px solid; - display: none; - } - - .sidebar > .block.version { - border-bottom: none; - margin-top: 12px; - } - - nav.sub { - width: calc(100% - 32px); - float: right; - } - - .content { - margin-left: 0px; - } - - #main { - margin-top: 45px; - padding: 0; - } - - .content .in-band { - width: 100%; - } - - .content h4 > .out-of-band { - position: inherit; - } - - .toggle-wrapper > .collapse-toggle { - left: 0px; - } - - .toggle-wrapper { - height: 1.5em; - } - - #search { - margin-left: 0; - } - - .content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant { - display: flex; - } - - .anchor { - display: none !important; - } - - h1.fqn { - overflow: initial; - } - - #main > .line-numbers { - margin-top: 0; - } -} - -@media print { - nav.sub, .content .out-of-band, .collapse-toggle { - display: none; - } -} - .information { position: absolute; left: -20px; @@ -1265,7 +1138,177 @@ h4 > .important-traits { margin-bottom: 6px; } +.theme-picker { + position: absolute; + left: 211px; + top: 19px; +} + +.theme-picker button { + outline: none; +} + +#settings-menu { + position: absolute; + right: 0; + top: 10px; + outline: none; +} + +#theme-picker, #settings-menu { + padding: 4px; + width: 27px; + height: 29px; + border: 1px solid; + border-radius: 3px; + cursor: pointer; +} + +#theme-choices { + display: none; + position: absolute; + left: 0; + top: 28px; + border: 1px solid; + border-radius: 3px; + z-index: 1; + cursor: pointer; +} + +#theme-choices > button { + border: none; + width: 100%; + padding: 4px; + text-align: center; + background: rgba(0,0,0,0); +} + +#theme-choices > button:not(:first-child) { + border-top: 1px solid; +} + +/* Media Queries */ + @media (max-width: 700px) { + body { + padding-top: 0px; + } + + .rustdoc > .sidebar { + height: 45px; + min-height: 40px; + margin: 0; + margin-left: -15px; + padding: 0 15px; + position: static; + z-index: 11; + } + + .sidebar > .location { + float: right; + margin: 0px; + margin-top: 2px; + padding: 3px 10px 1px 10px; + min-height: 39px; + background: inherit; + text-align: left; + font-size: 24px; + } + + .sidebar .location:empty { + padding: 0; + } + + .sidebar img { + width: 35px; + margin-top: 5px; + margin-bottom: 5px; + float: left; + margin-left: 50px; + } + + .sidebar-menu { + position: fixed; + z-index: 10; + font-size: 2rem; + cursor: pointer; + width: 45px; + left: 0; + text-align: center; + display: block; + border-bottom: 1px solid; + border-right: 1px solid; + height: 45px; + } + + .sidebar-elems { + position: fixed; + z-index: 1; + left: 0; + top: 45px; + bottom: 0; + overflow-y: auto; + border-right: 1px solid; + display: none; + } + + .sidebar > .block.version { + border-bottom: none; + margin-top: 12px; + } + + nav.sub { + width: calc(100% - 32px); + float: right; + } + + .content { + margin-left: 0px; + } + + #main { + margin-top: 45px; + padding: 0; + } + + .content .in-band { + width: 100%; + } + + .content h4 > .out-of-band { + position: inherit; + } + + .toggle-wrapper > .collapse-toggle { + left: 0px; + } + + .toggle-wrapper { + height: 1.5em; + } + + #search { + margin-left: 0; + } + + .content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant { + display: flex; + } + + .anchor { + display: none !important; + } + + h1.fqn { + overflow: initial; + } + + .theme-picker { + left: 10px; + top: 54px; + z-index: 1; + } + h4 > .important-traits { position: absolute; left: -22px; @@ -1352,8 +1395,17 @@ h4 > .important-traits { #source-sidebar { z-index: 11; } + + #main > .line-numbers { + margin-top: 0; + } } +@media print { + nav.sub, .content .out-of-band, .collapse-toggle { + display: none; + } +} @media (max-width: 416px) { #titles { @@ -1453,63 +1505,6 @@ kbd { cursor: default; } -.theme-picker { - position: absolute; - left: 211px; - top: 19px; -} - -.theme-picker button { - outline: none; -} - -#settings-menu { - position: absolute; - right: 0; - top: 10px; - outline: none; -} - -#theme-picker, #settings-menu { - padding: 4px; - width: 27px; - height: 29px; - border: 1px solid; - border-radius: 3px; - cursor: pointer; -} - -#theme-choices { - display: none; - position: absolute; - left: 0; - top: 28px; - border: 1px solid; - border-radius: 3px; - z-index: 1; - cursor: pointer; -} - -#theme-choices > button { - border: none; - width: 100%; - padding: 4px; - text-align: center; - background: rgba(0,0,0,0); -} - -#theme-choices > button:not(:first-child) { - border-top: 1px solid; -} - -@media (max-width: 700px) { - .theme-picker { - left: 10px; - top: 54px; - z-index: 1; - } -} - .hidden-by-impl-hider, .hidden-by-usual-hider { /* important because of conflicting rule for small screens */ From 1e47250540bc97f921d1b7e2982f1904fa191dff Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 1 May 2019 17:59:48 +0200 Subject: [PATCH 029/239] as_ptr returns a read-only pointer --- src/libcore/slice/mod.rs | 6 ++++++ src/libcore/str/mod.rs | 5 +++++ src/libstd/ffi/c_str.rs | 9 +++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 8731f4867535..c273153fa5ea 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -359,6 +359,10 @@ impl [T] { /// The caller must ensure that the slice outlives the pointer this /// function returns, or else it will end up pointing to garbage. /// + /// The caller must also ensure that the memory the pointer (non-transitively) points to + /// is never written to (except inside an `UnsafeCell`). If you need to mutate + /// the contents of the slice, use [`as_mut_ptr`]. + /// /// Modifying the container referenced by this slice may cause its buffer /// to be reallocated, which would also make any pointers to it invalid. /// @@ -374,6 +378,8 @@ impl [T] { /// } /// } /// ``` + /// + /// [`as_mut_ptr`]: #method.as_mut_ptr #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub const fn as_ptr(&self) -> *const T { diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 45421848cec5..96a5ce61ca0b 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2188,7 +2188,12 @@ impl str { /// [`u8`]. This pointer will be pointing to the first byte of the string /// slice. /// + /// The caller must ensure that the memory the pointer points to + /// is never written to. If you need to mutate + /// the contents of the string slice, use [`as_mut_ptr`]. + /// /// [`u8`]: primitive.u8.html + /// [`as_mut_ptr`]: #method.as_mut_ptr /// /// # Examples /// diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index f93583dff818..5c6c43017cf6 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -43,7 +43,9 @@ use crate::sys; /// `CString` implements a [`as_ptr`] method through the [`Deref`] /// trait. This method will give you a `*const c_char` which you can /// feed directly to extern functions that expect a nul-terminated -/// string, like C's `strdup()`. +/// string, like C's `strdup()`. Notice that [`as_ptr`] returns a +/// read-only pointer; if the C code writes to it, that causes +/// undefined behavior. /// /// # Extracting a slice of the whole C string /// @@ -61,7 +63,7 @@ use crate::sys; /// /// Once you have the kind of slice you need (with or without a nul /// terminator), you can call the slice's own -/// [`as_ptr`][slice.as_ptr] method to get a raw pointer to pass to +/// [`as_ptr`][slice.as_ptr] method to get a read-only raw pointer to pass to /// extern functions. See the documentation for that function for a /// discussion on ensuring the lifetime of the raw pointer. /// @@ -1043,6 +1045,9 @@ impl CStr { /// /// **WARNING** /// + /// The returned pointer is read-only; writing to it (including passing it + /// to C code that writes to it) causes undefined behavior. + /// /// It is your responsibility to make sure that the underlying memory is not /// freed too early. For example, the following code will cause undefined /// behavior when `ptr` is used inside the `unsafe` block: From bd8885d340beb20ac1728d0bd7e64321da641b91 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Wed, 1 May 2019 22:23:07 +0200 Subject: [PATCH 030/239] Fall back to `/dev/urandom` on `EPERM` for `getrandom` This can happen because of seccomp or some VMs. Fixes #52609. --- src/libstd/sys/unix/rand.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs index 77f1439e17b1..71c62461ee9c 100644 --- a/src/libstd/sys/unix/rand.rs +++ b/src/libstd/sys/unix/rand.rs @@ -47,7 +47,12 @@ mod imp { let err = errno() as libc::c_int; if err == libc::EINTR { continue; - } else if err == libc::ENOSYS { + } else if err == libc::ENOSYS || err == libc::EPERM { + // Fall back to reading /dev/urandom if `getrandom` is not + // supported on the current kernel. + // + // Also fall back in case it is disabled by something like + // seccomp or inside of virtual machines. GETRANDOM_UNAVAILABLE.store(true, Ordering::Relaxed); return false; } else if err == libc::EAGAIN { From bd005a242a3125c432a76f982dab5a8d59e970f2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 1 May 2019 13:10:01 -0400 Subject: [PATCH 031/239] forego caching for all participants in cycles, apart from root node --- src/librustc/traits/select.rs | 50 ++++++++++++- src/test/ui/traits/cycle-cache-err-60010.rs | 71 +++++++++++++++++++ .../ui/traits/cycle-cache-err-60010.stderr | 20 ++++++ 3 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/traits/cycle-cache-err-60010.rs create mode 100644 src/test/ui/traits/cycle-cache-err-60010.stderr diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 8beabe058cf4..3c4d48b17b9f 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -43,6 +43,7 @@ use crate::hir; use rustc_data_structures::bit_set::GrowableBitSet; use rustc_data_structures::sync::Lock; use rustc_target::spec::abi::Abi; +use std::cell::Cell; use std::cmp; use std::fmt::{self, Display}; use std::iter; @@ -153,6 +154,31 @@ struct TraitObligationStack<'prev, 'tcx: 'prev> { /// selection-context's freshener. Used to check for recursion. fresh_trait_ref: ty::PolyTraitRef<'tcx>, + /// Starts out as false -- if, during evaluation, we encounter a + /// cycle, then we will set this flag to true for all participants + /// in the cycle (apart from the "head" node). These participants + /// will then forego caching their results. This is not the most + /// efficient solution, but it addresses #60010. The problem we + /// are trying to prevent: + /// + /// - If you have `A: AutoTrait` requires `B: AutoTrait` and `C: NonAutoTrait` + /// - `B: AutoTrait` requires `A: AutoTrait` (coinductive cycle, ok) + /// - `C: NonAutoTrait` requires `A: AutoTrait` (non-coinductive cycle, not ok) + /// + /// you don't want to cache that `B: AutoTrait` or `A: AutoTrait` + /// is `EvaluatedToOk`; this is because they were only considered + /// ok on the premise that if `A: AutoTrait` held, but we indeed + /// encountered a problem (later on) with `A: AutoTrait. So we + /// currently set a flag on the stack node for `B: AutoTrait` (as + /// well as the second instance of `A: AutoTrait`) to supress + /// caching. + /// + /// This is a simple, targeted fix. The correct fix requires + /// deeper changes, but would permit more caching: we could + /// basically defer caching until we have fully evaluated the + /// tree, and then cache the entire tree at once. + in_cycle: Cell, + previous: TraitObligationStackList<'prev, 'tcx>, } @@ -840,8 +866,16 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let (result, dep_node) = self.in_task(|this| this.evaluate_stack(&stack)); let result = result?; - debug!("CACHE MISS: EVAL({:?})={:?}", fresh_trait_ref, result); - self.insert_evaluation_cache(obligation.param_env, fresh_trait_ref, dep_node, result); + if !stack.in_cycle.get() { + debug!("CACHE MISS: EVAL({:?})={:?}", fresh_trait_ref, result); + self.insert_evaluation_cache(obligation.param_env, fresh_trait_ref, dep_node, result); + } else { + debug!( + "evaluate_trait_predicate_recursively: skipping cache because {:?} \ + is a cycle participant", + fresh_trait_ref, + ); + } Ok(result) } @@ -948,6 +982,17 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { { debug!("evaluate_stack({:?}) --> recursive", stack.fresh_trait_ref); + // If we have a stack like `A B C D E A`, where the top of + // the stack is the final `A`, then this will iterate over + // `A, E, D, C, B` -- i.e., all the participants apart + // from the cycle head. We mark them as participating in a + // cycle. This suppresses caching for those nodes. See + // `in_cycle` field for more details. + for item in stack.iter().take(rec_index + 1) { + debug!("evaluate_stack: marking {:?} as cycle participant", item.fresh_trait_ref); + item.in_cycle.set(true); + } + // Subtle: when checking for a coinductive cycle, we do // not compare using the "freshened trait refs" (which // have erased regions) but rather the fully explicit @@ -3692,6 +3737,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { TraitObligationStack { obligation, fresh_trait_ref, + in_cycle: Cell::new(false), previous: previous_stack, } } diff --git a/src/test/ui/traits/cycle-cache-err-60010.rs b/src/test/ui/traits/cycle-cache-err-60010.rs new file mode 100644 index 000000000000..45aa1b3c5223 --- /dev/null +++ b/src/test/ui/traits/cycle-cache-err-60010.rs @@ -0,0 +1,71 @@ +// Test that we properly detect the cycle amongst the traits +// here and report an error. + +use std::panic::RefUnwindSafe; + +trait Database { + type Storage; +} +trait HasQueryGroup {} +trait Query { + type Data; +} +trait SourceDatabase { + fn parse(&self) { + loop {} + } +} + +struct ParseQuery; +struct RootDatabase { + _runtime: Runtime, +} +struct Runtime { + _storage: Box, +} +struct SalsaStorage { + _parse: >::Data, //~ ERROR overflow +} + +impl Database for RootDatabase { //~ ERROR overflow + type Storage = SalsaStorage; +} +impl HasQueryGroup for RootDatabase {} +impl Query for ParseQuery +where + DB: SourceDatabase, + DB: Database, +{ + type Data = RootDatabase; +} +impl SourceDatabase for T +where + T: RefUnwindSafe, + T: HasQueryGroup, +{ +} + +pub(crate) fn goto_implementation(db: &RootDatabase) -> u32 { + // This is not satisfied: + // + // - `RootDatabase: SourceDatabase` + // - requires `RootDatabase: RefUnwindSafe` + `RootDatabase: HasQueryGroup` + // - `RootDatabase: RefUnwindSafe` + // - requires `Runtime: RefUnwindSafe` + // - `Runtime: RefUnwindSafe` + // - requires `DB::Storage: RefUnwindSafe` (`SalsaStorage: RefUnwindSafe`) + // - `SalsaStorage: RefUnwindSafe` + // - requires `>::Data: RefUnwindSafe`, + // which means `ParseQuery: Query` + // - `ParseQuery: Query` + // - requires `RootDatabase: SourceDatabase`, + // - `RootDatabase: SourceDatabase` is already on the stack, so we have a + // cycle with non-coinductive participants + // + // we used to fail to report an error here because we got the + // caching wrong. + SourceDatabase::parse(db); + 22 +} + +fn main() {} diff --git a/src/test/ui/traits/cycle-cache-err-60010.stderr b/src/test/ui/traits/cycle-cache-err-60010.stderr new file mode 100644 index 000000000000..9192f7ba2e3b --- /dev/null +++ b/src/test/ui/traits/cycle-cache-err-60010.stderr @@ -0,0 +1,20 @@ +error[E0275]: overflow evaluating the requirement `RootDatabase: SourceDatabase` + --> $DIR/cycle-cache-err-60010.rs:27:5 + | +LL | _parse: >::Data, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: required because of the requirements on the impl of `Query` for `ParseQuery` + +error[E0275]: overflow evaluating the requirement `RootDatabase: SourceDatabase` + --> $DIR/cycle-cache-err-60010.rs:30:6 + | +LL | impl Database for RootDatabase { + | ^^^^^^^^ + | + = note: required because of the requirements on the impl of `Query` for `ParseQuery` + = note: required because it appears within the type `SalsaStorage` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0275`. From 30cf0e4251533e67603c755acee5b0bd56197fce Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 2 May 2019 13:36:30 +0200 Subject: [PATCH 032/239] clarify wording --- src/libcore/slice/mod.rs | 4 ++-- src/libcore/str/mod.rs | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index c273153fa5ea..50d2ba0d3ef7 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -360,8 +360,8 @@ impl [T] { /// function returns, or else it will end up pointing to garbage. /// /// The caller must also ensure that the memory the pointer (non-transitively) points to - /// is never written to (except inside an `UnsafeCell`). If you need to mutate - /// the contents of the slice, use [`as_mut_ptr`]. + /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer + /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`]. /// /// Modifying the container referenced by this slice may cause its buffer /// to be reallocated, which would also make any pointers to it invalid. diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 96a5ce61ca0b..ef4bd83cbc5a 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2188,9 +2188,8 @@ impl str { /// [`u8`]. This pointer will be pointing to the first byte of the string /// slice. /// - /// The caller must ensure that the memory the pointer points to - /// is never written to. If you need to mutate - /// the contents of the string slice, use [`as_mut_ptr`]. + /// The caller must ensure that the returned pointer is never written to. + /// If you need to mutate the contents of the string slice, use [`as_mut_ptr`]. /// /// [`u8`]: primitive.u8.html /// [`as_mut_ptr`]: #method.as_mut_ptr From e2a25007beba16caa8653f1f3c35bcb7543d659e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 2 May 2019 23:31:50 +0200 Subject: [PATCH 033/239] Fix search sidebar width when no crate select is present --- src/librustdoc/html/static/rustdoc.css | 4 ++-- src/librustdoc/html/static/themes/dark.css | 7 ++++--- src/librustdoc/html/static/themes/light.css | 8 ++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 53b08cf56978..778677b43708 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -658,18 +658,18 @@ a { transition: border-color 300ms ease; transition: border-radius 300ms ease-in-out; transition: box-shadow 300ms ease-in-out; - width: calc(100% - 32px); + width: 100%; } #crate-search + .search-input { border-radius: 0 1px 1px 0; + width: calc(100% - 32px); } .search-input:focus { border-radius: 2px; border: 0; outline: 0; - box-shadow: 0 0 8px #078dd8; } .search-results .desc { diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index f1255f522473..e44ae2ad10ce 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -164,20 +164,21 @@ a.test-arrow { color: #111; background-color: #f0f0f0; border-color: #000; + box-shadow: 0 0 0 1px #000, 0 0 0 2px transparent; } .search-input { color: #111; - box-shadow: 0 0 0 1px #000, 0 0 0 2px transparent; background-color: #f0f0f0; + box-shadow: 0 0 0 1px #000, 0 0 0 2px transparent; } .search-input:focus { border-color: #008dfd; } -#crate-search + .search-input { - box-shadow: 1px 0 0 1px #000, 0 0 0 2px transparent; +#crate-search + .search-input:focus { + box-shadow: 0 0 8px 4px #078dd8; } .module-item .stab { diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index c052e6b37ade..4c37000dde2c 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -164,21 +164,21 @@ a.test-arrow { color: #555; background-color: white; border-color: #e0e0e0; - box-shadow: 0px 0 0 1px #e0e0e0, 0 0 0 2px transparent; + box-shadow: 0 0 0 1px #e0e0e0, 0 0 0 2px transparent; } .search-input { color: #555; - box-shadow: 0 0 0 1px #e0e0e0, 0 0 0 2px transparent; background-color: white; + box-shadow: 0 0 0 1px #e0e0e0, 0 0 0 2px transparent; } .search-input:focus { border-color: #66afe9; } -#crate-search + .search-input { - box-shadow: 1px 0 0 1px #e0e0e0, 0 0 0 2px transparent; +#crate-search + .search-input:focus { + box-shadow: 0 0 8px #078dd8; } .module-item .stab { From ccb9dac5ed65341bf8d9ce01a83b9aad02f42526 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sat, 4 May 2019 23:48:57 +0900 Subject: [PATCH 034/239] Fix intra-doc link resolution failure on re-exporting libstd --- src/liballoc/alloc.rs | 18 +++++++++++++++ src/libcore/task/wake.rs | 23 +++++++++++++++++++ src/libstd/alloc.rs | 5 ++++ src/libstd/collections/hash/map.rs | 5 +++- src/libstd/error.rs | 18 +++++++++++++++ src/libstd/ffi/os_str.rs | 2 ++ src/libstd/fs.rs | 2 ++ src/libstd/io/buffered.rs | 2 +- src/libstd/net/addr.rs | 13 +++++++++++ src/libstd/sync/mutex.rs | 2 ++ src/libstd/sync/rwlock.rs | 2 ++ src/libstd/thread/mod.rs | 1 + .../rustdoc/intra-link-libstd-re-export.rs | 3 +++ 13 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 src/test/rustdoc/intra-link-libstd-re-export.rs diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index ddc6481eec78..41ff06d70ff0 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -37,6 +37,8 @@ extern "Rust" { /// /// Note: while this type is unstable, the functionality it provides can be /// accessed through the [free functions in `alloc`](index.html#functions). +/// +/// [`Alloc`]: trait.Alloc.html #[unstable(feature = "allocator_api", issue = "32838")] #[derive(Copy, Clone, Default, Debug)] pub struct Global; @@ -54,6 +56,10 @@ pub struct Global; /// /// See [`GlobalAlloc::alloc`]. /// +/// [`Global`]: struct.Global.html +/// [`Alloc`]: trait.Alloc.html +/// [`GlobalAlloc::alloc`]: trait.GlobalAlloc.html#tymethod.alloc +/// /// # Examples /// /// ``` @@ -87,6 +93,10 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 { /// # Safety /// /// See [`GlobalAlloc::dealloc`]. +/// +/// [`Global`]: struct.Global.html +/// [`Alloc`]: trait.Alloc.html +/// [`GlobalAlloc::dealloc`]: trait.GlobalAlloc.html#tymethod.dealloc #[stable(feature = "global_alloc", since = "1.28.0")] #[inline] pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { @@ -105,6 +115,10 @@ pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { /// # Safety /// /// See [`GlobalAlloc::realloc`]. +/// +/// [`Global`]: struct.Global.html +/// [`Alloc`]: trait.Alloc.html +/// [`GlobalAlloc::realloc`]: trait.GlobalAlloc.html#method.realloc #[stable(feature = "global_alloc", since = "1.28.0")] #[inline] pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { @@ -124,6 +138,10 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 /// /// See [`GlobalAlloc::alloc_zeroed`]. /// +/// [`Global`]: struct.Global.html +/// [`Alloc`]: trait.Alloc.html +/// [`GlobalAlloc::alloc_zeroed`]: trait.GlobalAlloc.html#method.alloc_zeroed +/// /// # Examples /// /// ``` diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index b4e912498320..a6d611d2e93c 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -10,6 +10,8 @@ use crate::marker::{PhantomData, Unpin}; /// /// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that /// customizes the behavior of the `RawWaker`. +/// +/// [`Waker`]: struct.Waker.html #[derive(PartialEq, Debug)] #[stable(feature = "futures_api", since = "1.36.0")] pub struct RawWaker { @@ -55,6 +57,8 @@ impl RawWaker { /// pointer of a properly constructed [`RawWaker`] object from inside the /// [`RawWaker`] implementation. Calling one of the contained functions using /// any other `data` pointer will cause undefined behavior. +/// +/// [`RawWaker`]: struct.RawWaker.html #[stable(feature = "futures_api", since = "1.36.0")] #[derive(PartialEq, Copy, Clone, Debug)] pub struct RawWakerVTable { @@ -65,6 +69,9 @@ pub struct RawWakerVTable { /// required for this additional instance of a [`RawWaker`] and associated /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup /// of the same task that would have been awoken by the original [`RawWaker`]. + /// + /// [`Waker`]: struct.Waker.html + /// [`RawWaker`]: struct.RawWaker.html clone: unsafe fn(*const ()) -> RawWaker, /// This function will be called when `wake` is called on the [`Waker`]. @@ -73,6 +80,9 @@ pub struct RawWakerVTable { /// The implementation of this function must make sure to release any /// resources that are associated with this instance of a [`RawWaker`] and /// associated task. + /// + /// [`Waker`]: struct.Waker.html + /// [`RawWaker`]: struct.RawWaker.html wake: unsafe fn(*const ()), /// This function will be called when `wake_by_ref` is called on the [`Waker`]. @@ -80,6 +90,9 @@ pub struct RawWakerVTable { /// /// This function is similar to `wake`, but must not consume the provided data /// pointer. + /// + /// [`Waker`]: struct.Waker.html + /// [`RawWaker`]: struct.RawWaker.html wake_by_ref: unsafe fn(*const ()), /// This function gets called when a [`RawWaker`] gets dropped. @@ -87,6 +100,8 @@ pub struct RawWakerVTable { /// The implementation of this function must make sure to release any /// resources that are associated with this instance of a [`RawWaker`] and /// associated task. + /// + /// [`RawWaker`]: struct.RawWaker.html drop: unsafe fn(*const ()), } @@ -128,6 +143,9 @@ impl RawWakerVTable { /// The implementation of this function must make sure to release any /// resources that are associated with this instance of a [`RawWaker`] and /// associated task. + /// + /// [`Waker`]: struct.Waker.html + /// [`RawWaker`]: struct.RawWaker.html #[rustc_promotable] #[cfg_attr(stage0, unstable(feature = "futures_api_const_fn_ptr", issue = "50547"))] #[cfg_attr(not(stage0), stable(feature = "futures_api", since = "1.36.0"))] @@ -201,6 +219,8 @@ impl fmt::Debug for Context<'_> { /// executor-specific wakeup behavior. /// /// Implements [`Clone`], [`Send`], and [`Sync`]. +/// +/// [`RawWaker`]: struct.RawWaker.html #[repr(transparent)] #[stable(feature = "futures_api", since = "1.36.0")] pub struct Waker { @@ -266,6 +286,9 @@ impl Waker { /// The behavior of the returned `Waker` is undefined if the contract defined /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld. /// Therefore this method is unsafe. + /// + /// [`RawWaker`]: struct.RawWaker.html + /// [`RawWakerVTable`]: struct.RawWakerVTable.html #[inline] #[stable(feature = "futures_api", since = "1.36.0")] pub unsafe fn from_raw(waker: RawWaker) -> Waker { diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index 4241f47b661d..ff52974775b0 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -173,6 +173,9 @@ static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut()); /// about the allocation that failed. /// /// The allocation error hook is a global resource. +/// +/// [`set_alloc_error_hook`]: fn.set_alloc_error_hook.html +/// [`take_alloc_error_hook`]: fn.take_alloc_error_hook.html #[unstable(feature = "alloc_error_hook", issue = "51245")] pub fn set_alloc_error_hook(hook: fn(Layout)) { HOOK.store(hook as *mut (), Ordering::SeqCst); @@ -183,6 +186,8 @@ pub fn set_alloc_error_hook(hook: fn(Layout)) { /// *See also the function [`set_alloc_error_hook`].* /// /// If no custom hook is registered, the default hook will be returned. +/// +/// [`set_alloc_error_hook`]: fn.set_alloc_error_hook.html #[unstable(feature = "alloc_error_hook", issue = "51245")] pub fn take_alloc_error_hook() -> fn(Layout) { let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst); diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index f9fb392f9f52..af4f911a7842 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2492,7 +2492,10 @@ impl DefaultHasher { #[stable(feature = "hashmap_default_hasher", since = "1.13.0")] impl Default for DefaultHasher { - /// Creates a new `DefaultHasher` using [`new`][DefaultHasher::new]. + // FIXME: here should link `new` to [DefaultHasher::new], but it occurs intra-doc link + // resolution failure when re-exporting libstd items. When #56922 fixed, + // link `new` to [DefaultHasher::new] again. + /// Creates a new `DefaultHasher` using `new`. /// See its documentation for more. fn default() -> DefaultHasher { DefaultHasher::new() diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 081fff0562b1..71227c31c553 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -207,6 +207,8 @@ pub trait Error: Debug + Display { impl<'a, E: Error + 'a> From for Box { /// Converts a type of [`Error`] into a box of dyn [`Error`]. /// + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -244,6 +246,8 @@ impl<'a, E: Error + Send + Sync + 'a> From for Box From for Box for Box { /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -318,6 +324,8 @@ impl From for Box { impl From for Box { /// Converts a [`String`] into a box of dyn [`Error`]. /// + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -339,6 +347,8 @@ impl From for Box { impl<'a> From<&str> for Box { /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -359,6 +369,8 @@ impl<'a> From<&str> for Box { impl From<&str> for Box { /// Converts a [`str`] into a box of dyn [`Error`]. /// + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -378,6 +390,9 @@ impl From<&str> for Box { impl<'a, 'b> From> for Box { /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// + /// [`Cow`]: ../borrow/enum.Cow.html + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -399,6 +414,9 @@ impl<'a, 'b> From> for Box { impl<'a> From> for Box { /// Converts a [`Cow`] into a box of dyn [`Error`]. /// + /// [`Cow`]: ../borrow/enum.Cow.html + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 13aee783750f..c7c5849a00fa 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -351,6 +351,8 @@ impl From for OsString { /// Converts a [`String`] into a [`OsString`]. /// /// The conversion copies the data, and includes an allocation on the heap. + /// + /// [`OsString`]: ../../std/ffi/struct.OsString.html fn from(s: String) -> OsString { OsString { inner: Buf::from_string(s) } } diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 991b45fd4a2e..616b5eb836ff 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -1812,6 +1812,8 @@ pub fn canonicalize>(path: P) -> io::Result { /// function.) /// * `path` already exists. /// +/// [`create_dir_all`]: fn.create_dir_all.html +/// /// # Examples /// /// ```no_run diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 5be2687d8f5f..e309f81192cf 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -754,7 +754,7 @@ impl fmt::Display for IntoInnerError { /// completed, rather than the entire buffer at once. Enter `LineWriter`. It /// does exactly that. /// -/// Like [`BufWriter`], a `LineWriter`’s buffer will also be flushed when the +/// Like [`BufWriter`][bufwriter], a `LineWriter`’s buffer will also be flushed when the /// `LineWriter` goes out of scope or when its internal buffer is full. /// /// [bufwriter]: struct.BufWriter.html diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index ec54d8a042a3..b3f0508221a5 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -546,6 +546,9 @@ impl FromInner for SocketAddrV6 { #[stable(feature = "ip_from_ip", since = "1.16.0")] impl From for SocketAddr { /// Converts a [`SocketAddrV4`] into a [`SocketAddr::V4`]. + /// + /// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html + /// [`SocketAddr::V4`]: ../../std/net/enum.SocketAddr.html#variant.V4 fn from(sock4: SocketAddrV4) -> SocketAddr { SocketAddr::V4(sock4) } @@ -554,6 +557,9 @@ impl From for SocketAddr { #[stable(feature = "ip_from_ip", since = "1.16.0")] impl From for SocketAddr { /// Converts a [`SocketAddrV6`] into a [`SocketAddr::V6`]. + /// + /// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html + /// [`SocketAddr::V6`]: ../../std/net/enum.SocketAddr.html#variant.V6 fn from(sock6: SocketAddrV6) -> SocketAddr { SocketAddr::V6(sock6) } @@ -567,6 +573,13 @@ impl> From<(I, u16)> for SocketAddr { /// and creates a [`SocketAddr::V6`] for a [`IpAddr::V6`]. /// /// `u16` is treated as port of the newly created [`SocketAddr`]. + /// + /// [`IpAddr`]: ../../std/net/enum.IpAddr.html + /// [`IpAddr::V4`]: ../../std/net/enum.IpAddr.html#variant.V4 + /// [`IpAddr::V6`]: ../../std/net/enum.IpAddr.html#variant.V6 + /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html + /// [`SocketAddr::V4`]: ../../std/net/enum.SocketAddr.html#variant.V4 + /// [`SocketAddr::V6`]: ../../std/net/enum.SocketAddr.html#variant.V6 fn from(pieces: (I, u16)) -> SocketAddr { SocketAddr::new(pieces.0.into(), pieces.1) } diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 11ac34fcb24f..87c2318a9377 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -376,6 +376,8 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Mutex { impl From for Mutex { /// Creates a new mutex in an unlocked state ready for use. /// This is equivalent to [`Mutex::new`]. + /// + /// [`Mutex::new`]: ../../std/sync/struct.Mutex.html#method.new fn from(t: T) -> Self { Mutex::new(t) } diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index 1299a7440956..b1b56f321fc6 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -453,6 +453,8 @@ impl Default for RwLock { impl From for RwLock { /// Creates a new instance of an `RwLock` which is unlocked. /// This is equivalent to [`RwLock::new`]. + /// + /// [`RwLock::new`]: ../../std/sync/struct.RwLock.html#method.new fn from(t: T) -> Self { RwLock::new(t) } diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index fce28ffd9c38..35de4f4008b6 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -443,6 +443,7 @@ impl Builder { /// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn /// [`io::Result`]: ../../std/io/type.Result.html /// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html + /// [`JoinHandle::join`]: ../../std/thread/struct.JoinHandle.html#method.join #[unstable(feature = "thread_spawn_unchecked", issue = "55132")] pub unsafe fn spawn_unchecked<'a, F, T>(self, f: F) -> io::Result> where F: FnOnce() -> T, F: Send + 'a, T: Send + 'a diff --git a/src/test/rustdoc/intra-link-libstd-re-export.rs b/src/test/rustdoc/intra-link-libstd-re-export.rs new file mode 100644 index 000000000000..6f239292ec20 --- /dev/null +++ b/src/test/rustdoc/intra-link-libstd-re-export.rs @@ -0,0 +1,3 @@ +#![deny(intra_doc_link_resolution_failure)] + +pub use std::*; From 9a0a87a654303c69856d55dac419a2c440efc3d4 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 6 May 2019 13:02:12 -0700 Subject: [PATCH 035/239] Revert "Disable big-endian simd in swap_nonoverlapping_bytes" This reverts commit 77bd4dc65406ba3cedbc779e6f6280868231912e. Issue #42778 was formerly easy to reproduce on two big-endian targets, `powerpc64` and `s390x`, so we disabled SIMD on this function for all big-endian targets as a workaround. I have re-tested this code on `powerpc64` and `s390x`, each with the bundled LLVM 8 and with external LLVM 7 and LLVM 6, and the problems no longer appear. So it seems safe to remove this workaround, although I'm still a little uncomfortable that we never found a root-cause... --- src/libcore/ptr.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index a41be4269d50..c3f6d7daf234 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -374,10 +374,7 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) { // #[repr(simd)], even if we don't actually use this struct directly. // // FIXME repr(simd) broken on emscripten and redox - // It's also broken on big-endian powerpc64 and s390x. #42778 - #[cfg_attr(not(any(target_os = "emscripten", target_os = "redox", - target_endian = "big")), - repr(simd))] + #[cfg_attr(not(any(target_os = "emscripten", target_os = "redox")), repr(simd))] struct Block(u64, u64, u64, u64); struct UnalignedBlock(u64, u64, u64, u64); From 20a5aa302e786acba8f845e326e226f16ca56afb Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 17 Apr 2019 20:17:12 -0500 Subject: [PATCH 036/239] set the default edition when pre-parsing a doctest --- src/librustdoc/config.rs | 25 ++++++------ src/librustdoc/externalfiles.rs | 9 +++-- src/librustdoc/html/markdown.rs | 54 +++++++++++++------------ src/librustdoc/html/render.rs | 18 ++++++--- src/librustdoc/lib.rs | 11 +++-- src/librustdoc/markdown.rs | 12 ++++-- src/librustdoc/test.rs | 8 +++- src/tools/error_index_generator/main.rs | 4 +- 8 files changed, 86 insertions(+), 55 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 72421c9decc6..0a403f61e9c2 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -386,18 +386,6 @@ impl Options { } } - let mut id_map = html::markdown::IdMap::new(); - id_map.populate(html::render::initial_ids()); - let external_html = match ExternalHtml::load( - &matches.opt_strs("html-in-header"), - &matches.opt_strs("html-before-content"), - &matches.opt_strs("html-after-content"), - &matches.opt_strs("markdown-before-content"), - &matches.opt_strs("markdown-after-content"), &diag, &mut id_map) { - Some(eh) => eh, - None => return Err(3), - }; - let edition = matches.opt_str("edition").unwrap_or("2015".to_string()); let edition = match edition.parse() { Ok(e) => e, @@ -407,6 +395,19 @@ impl Options { } }; + let mut id_map = html::markdown::IdMap::new(); + id_map.populate(html::render::initial_ids()); + let external_html = match ExternalHtml::load( + &matches.opt_strs("html-in-header"), + &matches.opt_strs("html-before-content"), + &matches.opt_strs("html-after-content"), + &matches.opt_strs("markdown-before-content"), + &matches.opt_strs("markdown-after-content"), + &diag, &mut id_map, edition) { + Some(eh) => eh, + None => return Err(3), + }; + match matches.opt_str("r").as_ref().map(|s| &**s) { Some("rust") | None => {} Some(s) => { diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index 0378b12662da..d604ba11d418 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -3,6 +3,7 @@ use std::path::Path; use std::str; use errors; use crate::syntax::feature_gate::UnstableFeatures; +use crate::syntax::edition::Edition; use crate::html::markdown::{IdMap, ErrorCodes, Markdown}; use std::cell::RefCell; @@ -23,7 +24,7 @@ pub struct ExternalHtml { impl ExternalHtml { pub fn load(in_header: &[String], before_content: &[String], after_content: &[String], md_before_content: &[String], md_after_content: &[String], diag: &errors::Handler, - id_map: &mut IdMap) + id_map: &mut IdMap, edition: Edition) -> Option { let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()); load_external_files(in_header, diag) @@ -34,7 +35,8 @@ impl ExternalHtml { .and_then(|(ih, bc)| load_external_files(md_before_content, diag) .map(|m_bc| (ih, - format!("{}{}", bc, Markdown(&m_bc, &[], RefCell::new(id_map), codes)))) + format!("{}{}", bc, Markdown(&m_bc, &[], RefCell::new(id_map), + codes, edition)))) ) .and_then(|(ih, bc)| load_external_files(after_content, diag) @@ -43,7 +45,8 @@ impl ExternalHtml { .and_then(|(ih, bc, ac)| load_external_files(md_after_content, diag) .map(|m_ac| (ih, bc, - format!("{}{}", ac, Markdown(&m_ac, &[], RefCell::new(id_map), codes)))) + format!("{}{}", ac, Markdown(&m_ac, &[], RefCell::new(id_map), + codes, edition)))) ) .map(|(ih, bc, ac)| ExternalHtml { diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index a3b041c6954c..5f450fcf6fca 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -42,14 +42,21 @@ fn opts() -> Options { /// A unit struct which has the `fmt::Display` trait implemented. When /// formatted, this struct will emit the HTML corresponding to the rendered /// version of the contained markdown string. -/// The second parameter is a list of link replacements +/// +/// The second parameter is a list of link replacements. +/// +/// The third is the current list of used header IDs. +/// +/// The fourth is whether to allow the use of explicit error codes in doctest lang strings. +/// +/// The fifth is what default edition to use when parsing doctests (to add a `fn main`). pub struct Markdown<'a>( - pub &'a str, pub &'a [(String, String)], pub RefCell<&'a mut IdMap>, pub ErrorCodes); + pub &'a str, pub &'a [(String, String)], pub RefCell<&'a mut IdMap>, pub ErrorCodes, pub Edition); /// A unit struct like `Markdown`, that renders the markdown with a /// table of contents. -pub struct MarkdownWithToc<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes); +pub struct MarkdownWithToc<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes, pub Edition); /// A unit struct like `Markdown`, that renders the markdown escaping HTML tags. -pub struct MarkdownHtml<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes); +pub struct MarkdownHtml<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes, pub Edition); /// A unit struct like `Markdown`, that renders only the first paragraph. pub struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [(String, String)]); @@ -146,13 +153,15 @@ thread_local!(pub static PLAYGROUND: RefCell, String)>> = struct CodeBlocks<'a, I: Iterator>> { inner: I, check_error_codes: ErrorCodes, + edition: Edition, } impl<'a, I: Iterator>> CodeBlocks<'a, I> { - fn new(iter: I, error_codes: ErrorCodes) -> Self { + fn new(iter: I, error_codes: ErrorCodes, edition: Edition) -> Self { CodeBlocks { inner: iter, check_error_codes: error_codes, + edition, } } } @@ -177,6 +186,9 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'a, I> { return event; } + let explicit_edition = edition.is_some(); + let edition = edition.unwrap_or(self.edition); + let mut origtext = String::new(); for event in &mut self.inner { match event { @@ -202,22 +214,14 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'a, I> { .collect::>>().join("\n"); let krate = krate.as_ref().map(|s| &**s); let (test, _) = test::make_test(&test, krate, false, - &Default::default()); + &Default::default(), edition); let channel = if test.contains("#![feature(") { "&version=nightly" } else { "" }; - let edition_string = if let Some(e @ Edition::Edition2018) = edition { - format!("&edition={}{}", e, - if channel == "&version=nightly" { "" } - else { "&version=nightly" }) - } else if let Some(e) = edition { - format!("&edition={}", e) - } else { - "".to_owned() - }; + let edition_string = format!("&edition={}", edition); // These characters don't need to be escaped in a URI. // FIXME: use a library function for percent encoding. @@ -247,8 +251,8 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'a, I> { Some(("This example is not tested".to_owned(), "ignore")) } else if compile_fail { Some(("This example deliberately fails to compile".to_owned(), "compile_fail")) - } else if let Some(e) = edition { - Some((format!("This code runs with edition {}", e), "edition")) + } else if explicit_edition { + Some((format!("This code runs with edition {}", edition), "edition")) } else { None }; @@ -259,7 +263,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'a, I> { Some(&format!("rust-example-rendered{}", if ignore { " ignore" } else if compile_fail { " compile_fail" } - else if edition.is_some() { " edition " } + else if explicit_edition { " edition " } else { "" })), playground_button.as_ref().map(String::as_str), Some((s1.as_str(), s2)))); @@ -270,7 +274,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'a, I> { Some(&format!("rust-example-rendered{}", if ignore { " ignore" } else if compile_fail { " compile_fail" } - else if edition.is_some() { " edition " } + else if explicit_edition { " edition " } else { "" })), playground_button.as_ref().map(String::as_str), None)); @@ -659,7 +663,7 @@ impl LangString { impl<'a> fmt::Display for Markdown<'a> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let Markdown(md, links, ref ids, codes) = *self; + let Markdown(md, links, ref ids, codes, edition) = *self; let mut ids = ids.borrow_mut(); // This is actually common enough to special-case @@ -678,7 +682,7 @@ impl<'a> fmt::Display for Markdown<'a> { let p = HeadingLinks::new(p, None, &mut ids); let p = LinkReplacer::new(p, links); - let p = CodeBlocks::new(p, codes); + let p = CodeBlocks::new(p, codes, edition); let p = Footnotes::new(p); html::push_html(&mut s, p); @@ -688,7 +692,7 @@ impl<'a> fmt::Display for Markdown<'a> { impl<'a> fmt::Display for MarkdownWithToc<'a> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let MarkdownWithToc(md, ref ids, codes) = *self; + let MarkdownWithToc(md, ref ids, codes, edition) = *self; let mut ids = ids.borrow_mut(); let p = Parser::new_ext(md, opts()); @@ -699,7 +703,7 @@ impl<'a> fmt::Display for MarkdownWithToc<'a> { { let p = HeadingLinks::new(p, Some(&mut toc), &mut ids); - let p = CodeBlocks::new(p, codes); + let p = CodeBlocks::new(p, codes, edition); let p = Footnotes::new(p); html::push_html(&mut s, p); } @@ -712,7 +716,7 @@ impl<'a> fmt::Display for MarkdownWithToc<'a> { impl<'a> fmt::Display for MarkdownHtml<'a> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let MarkdownHtml(md, ref ids, codes) = *self; + let MarkdownHtml(md, ref ids, codes, edition) = *self; let mut ids = ids.borrow_mut(); // This is actually common enough to special-case @@ -728,7 +732,7 @@ impl<'a> fmt::Display for MarkdownHtml<'a> { let mut s = String::with_capacity(md.len() * 3 / 2); let p = HeadingLinks::new(p, None, &mut ids); - let p = CodeBlocks::new(p, codes); + let p = CodeBlocks::new(p, codes, edition); let p = Footnotes::new(p); html::push_html(&mut s, p); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 472192a64649..d92681c4f235 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -47,6 +47,7 @@ use std::rc::Rc; use errors; use serialize::json::{ToJson, Json, as_json}; use syntax::ast; +use syntax::edition::Edition; use syntax::ext::base::MacroKind; use syntax::source_map::FileName; use syntax::feature_gate::UnstableFeatures; @@ -107,6 +108,8 @@ struct Context { /// publicly reused items to redirect to the right location. pub render_redirect_pages: bool, pub codes: ErrorCodes, + /// The default edition used to parse doctests. + pub edition: Edition, /// The map used to ensure all generated 'id=' attributes are unique. id_map: Rc>, pub shared: Arc, @@ -513,7 +516,8 @@ pub fn run(mut krate: clean::Crate, options: RenderOptions, passes: FxHashSet, renderinfo: RenderInfo, - diag: &errors::Handler) -> Result<(), Error> { + diag: &errors::Handler, + edition: Edition) -> Result<(), Error> { // need to save a copy of the options for rendering the index page let md_opts = options.clone(); let RenderOptions { @@ -603,6 +607,7 @@ pub fn run(mut krate: clean::Crate, dst, render_redirect_pages: false, codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()), + edition, id_map: Rc::new(RefCell::new(id_map)), shared: Arc::new(scx), }; @@ -1127,7 +1132,7 @@ themePicker.onblur = handleThemeButtonsBlur; md_opts.output = cx.dst.clone(); md_opts.external_html = (*cx.shared).layout.external_html.clone(); - crate::markdown::render(index_page, md_opts, diag); + crate::markdown::render(index_page, md_opts, diag, cx.edition); } else { let dst = cx.dst.join("index.html"); let mut w = BufWriter::new(try_err!(File::create(&dst), &dst)); @@ -2552,7 +2557,7 @@ fn render_markdown(w: &mut fmt::Formatter<'_>, if is_hidden { " hidden" } else { "" }, prefix, Markdown(md_text, &links, RefCell::new(&mut ids), - cx.codes)) + cx.codes, cx.edition)) } fn document_short( @@ -2917,7 +2922,7 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec { if let Some(note) = note { let mut ids = cx.id_map.borrow_mut(); - let html = MarkdownHtml(¬e, RefCell::new(&mut ids), error_codes); + let html = MarkdownHtml(¬e, RefCell::new(&mut ids), error_codes, cx.edition); message.push_str(&format!(": {}", html)); } stability.push(format!("
{}
", message)); @@ -2966,7 +2971,7 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec { message = format!( "
{}{}
", message, - MarkdownHtml(&unstable_reason, RefCell::new(&mut ids), error_codes) + MarkdownHtml(&unstable_reason, RefCell::new(&mut ids), error_codes, cx.edition) ); } @@ -4179,7 +4184,8 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) { let mut ids = cx.id_map.borrow_mut(); write!(w, "
{}
", - Markdown(&*dox, &i.impl_item.links(), RefCell::new(&mut ids), cx.codes))?; + Markdown(&*dox, &i.impl_item.links(), RefCell::new(&mut ids), + cx.codes, cx.edition))?; } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 5b76f6861de7..f5061b671828 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -391,7 +391,10 @@ fn main_args(args: &[String]) -> i32 { match (options.should_test, options.markdown_input()) { (true, true) => return markdown::test(options, &diag), (true, false) => return test::run(options), - (false, true) => return markdown::render(options.input, options.render_options, &diag), + (false, true) => return markdown::render(options.input, + options.render_options, + &diag, + options.edition), (false, false) => {} } @@ -399,7 +402,8 @@ fn main_args(args: &[String]) -> i32 { // but we can't crates the Handler ahead of time because it's not Send let diag_opts = (options.error_format, options.debugging_options.treat_err_as_bug, - options.debugging_options.ui_testing); + options.debugging_options.ui_testing, + options.edition); let show_coverage = options.show_coverage; rust_input(options, move |out| { if show_coverage { @@ -410,7 +414,7 @@ fn main_args(args: &[String]) -> i32 { let Output { krate, passes, renderinfo, renderopts } = out; info!("going to format"); - let (error_format, treat_err_as_bug, ui_testing) = diag_opts; + let (error_format, treat_err_as_bug, ui_testing, edition) = diag_opts; let diag = core::new_handler(error_format, None, treat_err_as_bug, ui_testing); match html::render::run( krate, @@ -418,6 +422,7 @@ fn main_args(args: &[String]) -> i32 { passes.into_iter().collect(), renderinfo, &diag, + edition, ) { Ok(_) => rustc_driver::EXIT_SUCCESS, Err(e) => { diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index c496dde8426c..b0a37ea9c808 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -5,6 +5,7 @@ use std::cell::RefCell; use errors; use testing; +use syntax::edition::Edition; use syntax::source_map::DUMMY_SP; use syntax::feature_gate::UnstableFeatures; @@ -36,7 +37,12 @@ fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) { /// Render `input` (e.g., "foo.md") into an HTML file in `output` /// (e.g., output = "bar" => "bar/foo.html"). -pub fn render(input: PathBuf, options: RenderOptions, diag: &errors::Handler) -> i32 { +pub fn render( + input: PathBuf, + options: RenderOptions, + diag: &errors::Handler, + edition: Edition +) -> i32 { let mut output = options.output; output.push(input.file_stem().unwrap()); output.set_extension("html"); @@ -76,9 +82,9 @@ pub fn render(input: PathBuf, options: RenderOptions, diag: &errors::Handler) -> let mut ids = IdMap::new(); let error_codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()); let text = if !options.markdown_no_toc { - MarkdownWithToc(text, RefCell::new(&mut ids), error_codes).to_string() + MarkdownWithToc(text, RefCell::new(&mut ids), error_codes, edition).to_string() } else { - Markdown(text, &[], RefCell::new(&mut ids), error_codes).to_string() + Markdown(text, &[], RefCell::new(&mut ids), error_codes, edition).to_string() }; let err = write!( diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 5c0a4da1cd7e..7a9b82c71653 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -167,7 +167,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, maybe_sysroot: Option, linker: Option, edition: Edition, persist_doctests: Option) { let (test, line_offset) = match panic::catch_unwind(|| { - make_test(test, Some(cratename), as_test_harness, opts) + make_test(test, Some(cratename), as_test_harness, opts, edition) }) { Ok((test, line_offset)) => (test, line_offset), Err(cause) if cause.is::() => { @@ -356,7 +356,8 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, pub fn make_test(s: &str, cratename: Option<&str>, dont_insert_main: bool, - opts: &TestOptions) + opts: &TestOptions, + edition: Edition) -> (String, usize) { let (crate_attrs, everything_else, crates) = partition_source(s); let everything_else = everything_else.trim(); @@ -390,6 +391,8 @@ pub fn make_test(s: &str, use errors::emitter::EmitterWriter; use errors::Handler; + syntax::ext::hygiene::set_default_edition(edition); + let filename = FileName::anon_source_code(s); let source = crates + &everything_else; @@ -397,6 +400,7 @@ pub fn make_test(s: &str, // send all the errors that libsyntax emits directly into a `Sink` instead of stderr. let cm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let emitter = EmitterWriter::new(box io::sink(), None, false, false, false); + // FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser let handler = Handler::with_emitter(false, None, box emitter); let sess = ParseSess::with_span_handler(handler, cm); diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index 04986b59ea0f..38bd3fc006dc 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -15,6 +15,7 @@ use std::path::Path; use std::path::PathBuf; use std::cell::RefCell; +use syntax::edition::DEFAULT_EDITION; use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata}; use rustdoc::html::markdown::{Markdown, IdMap, ErrorCodes, PLAYGROUND}; @@ -97,7 +98,8 @@ impl Formatter for HTMLFormatter { Some(ref desc) => { let mut id_map = self.0.borrow_mut(); write!(output, "{}", - Markdown(desc, &[], RefCell::new(&mut id_map), ErrorCodes::Yes))? + Markdown(desc, &[], RefCell::new(&mut id_map), + ErrorCodes::Yes, DEFAULT_EDITION))? }, None => write!(output, "

No description.

\n")?, } From e66e1c7186f027a17a0959d0e8f42367446217c1 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 18 Apr 2019 09:10:08 -0500 Subject: [PATCH 037/239] update playground url tests with new edition behavior --- src/test/rustdoc/playground-arg.rs | 2 +- src/test/rustdoc/playground.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/rustdoc/playground-arg.rs b/src/test/rustdoc/playground-arg.rs index fb1be7397e65..018716ad45af 100644 --- a/src/test/rustdoc/playground-arg.rs +++ b/src/test/rustdoc/playground-arg.rs @@ -11,4 +11,4 @@ pub fn dummy() {} // ensure that `extern crate foo;` was inserted into code snips automatically: -// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0Aextern%20crate%20foo%3B%0Afn%20main()%20%7B%0Ause%20foo%3A%3Adummy%3B%0Adummy()%3B%0A%7D"]' "Run" +// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0Aextern%20crate%20foo%3B%0Afn%20main()%20%7B%0Ause%20foo%3A%3Adummy%3B%0Adummy()%3B%0A%7D&edition=2015"]' "Run" diff --git a/src/test/rustdoc/playground.rs b/src/test/rustdoc/playground.rs index 1b76e6c88534..9971c7b4297a 100644 --- a/src/test/rustdoc/playground.rs +++ b/src/test/rustdoc/playground.rs @@ -24,6 +24,6 @@ //! } //! ``` -// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D"]' "Run" -// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0Aprintln!(%22Hello%2C%20world!%22)%3B%0A%7D"]' "Run" -// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D&version=nightly"]' "Run" +// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D&edition=2015"]' "Run" +// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0Aprintln!(%22Hello%2C%20world!%22)%3B%0A%7D&edition=2015"]' "Run" +// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D&version=nightly&edition=2015"]' "Run" From a6d26eb053e9c56fdc9d9e20a2952041a165e559 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 18 Apr 2019 09:15:39 -0500 Subject: [PATCH 038/239] add test for `async move` in a doctest --- src/test/rustdoc/async-move-doctest.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/test/rustdoc/async-move-doctest.rs diff --git a/src/test/rustdoc/async-move-doctest.rs b/src/test/rustdoc/async-move-doctest.rs new file mode 100644 index 000000000000..42723132782c --- /dev/null +++ b/src/test/rustdoc/async-move-doctest.rs @@ -0,0 +1,14 @@ +// compile-flags:--test +// edition:2018 + +// prior to setting the default edition for the doctest pre-parser, this doctest would fail due to +// a fatal parsing error +// see https://github.com/rust-lang/rust/issues/59313 + +//! ``` +//! #![feature(async_await)] +//! +//! fn foo() { +//! drop(async move {}); +//! } +//! ``` From 5b167bf4bbdff169ca735476e66fdf9b4e6501fd Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 18 Apr 2019 12:23:54 -0500 Subject: [PATCH 039/239] update rustdoc unit tests --- src/librustdoc/html/markdown.rs | 11 +++++++---- src/librustdoc/test.rs | 35 +++++++++++++++++---------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 5f450fcf6fca..df01ac2f4440 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1050,7 +1050,7 @@ mod tests { use super::{ErrorCodes, LangString, Markdown, MarkdownHtml, IdMap}; use super::plain_summary_line; use std::cell::RefCell; - use syntax::edition::Edition; + use syntax::edition::{Edition, DEFAULT_EDITION}; #[test] fn test_lang_string_parse() { @@ -1102,7 +1102,8 @@ mod tests { fn test_header() { fn t(input: &str, expect: &str) { let mut map = IdMap::new(); - let output = Markdown(input, &[], RefCell::new(&mut map), ErrorCodes::Yes).to_string(); + let output = Markdown(input, &[], RefCell::new(&mut map), + ErrorCodes::Yes, DEFAULT_EDITION).to_string(); assert_eq!(output, expect, "original: {}", input); } @@ -1124,7 +1125,8 @@ mod tests { fn test_header_ids_multiple_blocks() { let mut map = IdMap::new(); fn t(map: &mut IdMap, input: &str, expect: &str) { - let output = Markdown(input, &[], RefCell::new(map), ErrorCodes::Yes).to_string(); + let output = Markdown(input, &[], RefCell::new(map), + ErrorCodes::Yes, DEFAULT_EDITION).to_string(); assert_eq!(output, expect, "original: {}", input); } @@ -1161,7 +1163,8 @@ mod tests { fn test_markdown_html_escape() { fn t(input: &str, expect: &str) { let mut idmap = IdMap::new(); - let output = MarkdownHtml(input, RefCell::new(&mut idmap), ErrorCodes::Yes).to_string(); + let output = MarkdownHtml(input, RefCell::new(&mut idmap), + ErrorCodes::Yes, DEFAULT_EDITION).to_string(); assert_eq!(output, expect, "original: {}", input); } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 7a9b82c71653..268f0602d487 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -884,6 +884,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> { #[cfg(test)] mod tests { use super::{TestOptions, make_test}; + use syntax::edition::DEFAULT_EDITION; #[test] fn make_test_basic() { @@ -896,7 +897,7 @@ mod tests { fn main() { assert_eq!(2+2, 4); }".to_string(); - let output = make_test(input, None, false, &opts); + let output = make_test(input, None, false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 2)); } @@ -912,7 +913,7 @@ assert_eq!(2+2, 4); fn main() { assert_eq!(2+2, 4); }".to_string(); - let output = make_test(input, Some("asdf"), false, &opts); + let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 2)); } @@ -931,7 +932,7 @@ fn main() { use asdf::qwop; assert_eq!(2+2, 4); }".to_string(); - let output = make_test(input, Some("asdf"), false, &opts); + let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 3)); } @@ -953,7 +954,7 @@ fn main() { use asdf::qwop; assert_eq!(2+2, 4); }".to_string(); - let output = make_test(input, Some("asdf"), false, &opts); + let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 2)); } @@ -972,7 +973,7 @@ fn main() { use std::*; assert_eq!(2+2, 4); }".to_string(); - let output = make_test(input, Some("std"), false, &opts); + let output = make_test(input, Some("std"), false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 2)); } @@ -992,7 +993,7 @@ fn main() { use asdf::qwop; assert_eq!(2+2, 4); }".to_string(); - let output = make_test(input, Some("asdf"), false, &opts); + let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 2)); } @@ -1010,7 +1011,7 @@ fn main() { use asdf::qwop; assert_eq!(2+2, 4); }".to_string(); - let output = make_test(input, Some("asdf"), false, &opts); + let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 2)); } @@ -1030,7 +1031,7 @@ fn main() { use asdf::qwop; assert_eq!(2+2, 4); }".to_string(); - let output = make_test(input, Some("asdf"), false, &opts); + let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 3)); // Adding more will also bump the returned line offset. @@ -1043,7 +1044,7 @@ fn main() { use asdf::qwop; assert_eq!(2+2, 4); }".to_string(); - let output = make_test(input, Some("asdf"), false, &opts); + let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 4)); } @@ -1061,7 +1062,7 @@ assert_eq!(2+2, 4);"; fn main() { assert_eq!(2+2, 4); }".to_string(); - let output = make_test(input, None, false, &opts); + let output = make_test(input, None, false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 2)); } @@ -1078,7 +1079,7 @@ assert_eq!(2+2, 4); fn main() { assert_eq!(2+2, 4); }".to_string(); - let output = make_test(input, None, false, &opts); + let output = make_test(input, None, false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 1)); } @@ -1095,7 +1096,7 @@ assert_eq!(2+2, 4);"; fn main() { assert_eq!(2+2, 4); }".to_string(); - let output = make_test(input, None, false, &opts); + let output = make_test(input, None, false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 2)); } @@ -1110,7 +1111,7 @@ assert_eq!(2+2, 4);"; "#![allow(unused)] //Ceci n'est pas une `fn main` assert_eq!(2+2, 4);".to_string(); - let output = make_test(input, None, true, &opts); + let output = make_test(input, None, true, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 1)); } @@ -1125,7 +1126,7 @@ assert_eq!(2+2, 4);".to_string(); "fn main() { assert_eq!(2+2, 4); }".to_string(); - let output = make_test(input, None, false, &opts); + let output = make_test(input, None, false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 1)); } @@ -1144,7 +1145,7 @@ fn main() { assert_eq!(2+2, 4); }".to_string(); - let output = make_test(input, None, false, &opts); + let output = make_test(input, None, false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 2)); let input = @@ -1159,7 +1160,7 @@ fn main() { assert_eq!(asdf::foo, 4); }".to_string(); - let output = make_test(input, Some("asdf"), false, &opts); + let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 3)); } @@ -1178,7 +1179,7 @@ test_wrapper! { fn main() {} }".to_string(); - let output = make_test(input, Some("my_crate"), false, &opts); + let output = make_test(input, Some("my_crate"), false, &opts, DEFAULT_EDITION); assert_eq!(output, (expected, 1)); } } From e61ff7717e6936929c3fb7cdb001383c64105cf3 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 18 Apr 2019 14:20:18 -0500 Subject: [PATCH 040/239] update rustdoc doc test --- src/librustdoc/html/markdown.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index df01ac2f4440..12d10254c4d0 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -8,12 +8,16 @@ //! ``` //! #![feature(rustc_private)] //! +//! extern crate syntax; +//! +//! use syntax::edition::Edition; //! use rustdoc::html::markdown::{IdMap, Markdown, ErrorCodes}; //! use std::cell::RefCell; //! //! let s = "My *markdown* _text_"; //! let mut id_map = IdMap::new(); -//! let html = format!("{}", Markdown(s, &[], RefCell::new(&mut id_map), ErrorCodes::Yes)); +//! let html = format!("{}", Markdown(s, &[], RefCell::new(&mut id_map), +//! ErrorCodes::Yes, Edition::Edition2015)); //! // ... something using html //! ``` From 76b49007f3400a6bc5af5586c2a31121c2525568 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 19 Apr 2019 08:54:26 -0500 Subject: [PATCH 041/239] don't pre-allocate the default edition string --- src/librustdoc/config.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 0a403f61e9c2..d17d27271ce6 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -13,7 +13,7 @@ use rustc::session::config::{nightly_options, build_codegen_options, build_debug use rustc::session::search_paths::SearchPath; use rustc_driver; use rustc_target::spec::TargetTriple; -use syntax::edition::Edition; +use syntax::edition::{Edition, DEFAULT_EDITION}; use crate::core::new_handler; use crate::externalfiles::ExternalHtml; @@ -386,13 +386,16 @@ impl Options { } } - let edition = matches.opt_str("edition").unwrap_or("2015".to_string()); - let edition = match edition.parse() { - Ok(e) => e, - Err(_) => { - diag.struct_err("could not parse edition").emit(); - return Err(1); + let edition = if let Some(e) = matches.opt_str("edition") { + match e.parse() { + Ok(e) => e, + Err(_) => { + diag.struct_err("could not parse edition").emit(); + return Err(1); + } } + } else { + DEFAULT_EDITION }; let mut id_map = html::markdown::IdMap::new(); From 48d1be4f46225350bb59f87a46bf2f6cba041013 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Mon, 6 May 2019 17:06:59 -0400 Subject: [PATCH 042/239] Test interaction of unions with non-zero/niche-filling optimization Notably this nails down part of the behavior that MaybeUninit assumes, e.g. that a Option> does not take advantage of non-zero optimization, and thus is a safe construct. --- src/test/run-pass/union/union-nonzero.rs | 30 +++++++++++++++++++ src/test/ui/print_type_sizes/niche-filling.rs | 17 +++++++++++ .../ui/print_type_sizes/niche-filling.stdout | 26 ++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 src/test/run-pass/union/union-nonzero.rs diff --git a/src/test/run-pass/union/union-nonzero.rs b/src/test/run-pass/union/union-nonzero.rs new file mode 100644 index 000000000000..614aa9ec0ce1 --- /dev/null +++ b/src/test/run-pass/union/union-nonzero.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(dead_code)] + +use std::mem::{size_of, transmute}; + +union U1 { + a: A, +} + +union U2 { + a: A, + b: B, +} + +fn main() { + // Unions do not participate in niche-filling/non-zero optimization... + assert!(size_of::>>() > size_of::>()); + assert!(size_of::>>() > size_of::>()); + + // ...even when theoretically possible: + assert!(size_of::>>() > size_of::>()); + assert!(size_of::>>() > size_of::>()); + + // The unused bits of the () variant can have any value. + let zeroed: U2<&u8, ()> = unsafe { transmute(std::ptr::null::()) }; + + if let None = Some(zeroed) { + panic!() + } +} diff --git a/src/test/ui/print_type_sizes/niche-filling.rs b/src/test/ui/print_type_sizes/niche-filling.rs index bed1e32a6015..0127261b2b7d 100644 --- a/src/test/ui/print_type_sizes/niche-filling.rs +++ b/src/test/ui/print_type_sizes/niche-filling.rs @@ -57,6 +57,15 @@ pub enum Enum4 { Four(D) } +pub union Union1 { + a: A, +} + +pub union Union2 { + a: A, + b: B, +} + #[start] fn start(_: isize, _: *const *const u8) -> isize { let _x: MyOption = Default::default(); @@ -69,5 +78,13 @@ fn start(_: isize, _: *const *const u8) -> isize { let _e: Enum4<(), char, (), ()> = Enum4::One(()); let _f: Enum4<(), (), bool, ()> = Enum4::One(()); let _g: Enum4<(), (), (), MyOption> = Enum4::One(()); + + // Unions do not currently participate in niche filling. + let _h: MyOption> = Default::default(); + + // ...even when theoretically possible. + let _i: MyOption> = Default::default(); + let _j: MyOption> = Default::default(); + 0 } diff --git a/src/test/ui/print_type_sizes/niche-filling.stdout b/src/test/ui/print_type_sizes/niche-filling.stdout index 9cdb2ae4f57e..301edc0d086b 100644 --- a/src/test/ui/print_type_sizes/niche-filling.stdout +++ b/src/test/ui/print_type_sizes/niche-filling.stdout @@ -14,6 +14,21 @@ print-type-size field `.post`: 2 bytes print-type-size field `.pre`: 1 bytes print-type-size variant `None`: 0 bytes print-type-size end padding: 1 bytes +print-type-size type: `MyOption>`: 8 bytes, alignment: 4 bytes +print-type-size discriminant: 4 bytes +print-type-size variant `Some`: 4 bytes +print-type-size field `.0`: 4 bytes +print-type-size variant `None`: 0 bytes +print-type-size type: `MyOption>`: 8 bytes, alignment: 4 bytes +print-type-size discriminant: 4 bytes +print-type-size variant `Some`: 4 bytes +print-type-size field `.0`: 4 bytes +print-type-size variant `None`: 0 bytes +print-type-size type: `MyOption>`: 8 bytes, alignment: 4 bytes +print-type-size discriminant: 4 bytes +print-type-size variant `Some`: 4 bytes +print-type-size field `.0`: 4 bytes +print-type-size variant `None`: 0 bytes print-type-size type: `NestedNonZero`: 8 bytes, alignment: 4 bytes print-type-size field `.val`: 4 bytes print-type-size field `.post`: 2 bytes @@ -36,6 +51,17 @@ print-type-size type: `MyOption`: 4 bytes, alignment: 4 by print-type-size variant `Some`: 4 bytes print-type-size field `.0`: 4 bytes print-type-size variant `None`: 0 bytes +print-type-size type: `Union1`: 4 bytes, alignment: 4 bytes +print-type-size variant `Union1`: 4 bytes +print-type-size field `.a`: 4 bytes +print-type-size type: `Union2`: 4 bytes, alignment: 4 bytes +print-type-size variant `Union2`: 4 bytes +print-type-size field `.a`: 4 bytes +print-type-size field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes +print-type-size type: `Union2`: 4 bytes, alignment: 4 bytes +print-type-size variant `Union2`: 4 bytes +print-type-size field `.a`: 4 bytes +print-type-size field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes print-type-size type: `std::num::NonZeroU32`: 4 bytes, alignment: 4 bytes print-type-size field `.0`: 4 bytes print-type-size type: `Enum4<(), (), (), MyOption>`: 2 bytes, alignment: 1 bytes From 76c52290214c49a9ba0cf506ac7e636543e087ff Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Tue, 7 May 2019 12:16:33 -0400 Subject: [PATCH 043/239] Document purpose of union-nonzero test --- src/test/run-pass/union/union-nonzero.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/test/run-pass/union/union-nonzero.rs b/src/test/run-pass/union/union-nonzero.rs index 614aa9ec0ce1..07a58aa7746d 100644 --- a/src/test/run-pass/union/union-nonzero.rs +++ b/src/test/run-pass/union/union-nonzero.rs @@ -1,6 +1,18 @@ // run-pass #![allow(dead_code)] +// Tests that unions aren't subject to unsafe non-zero/niche-filling optimizations. +// +// For example, if a union `U` can contain both a `&T` and a `*const T`, there's definitely no +// bit-value that an `Option` could reuse as `None`; this test makes sure that isn't done. +// +// Secondly, this tests the status quo to not apply such optimizations to types containing unions +// even if they're theoretically possible. (discussion: https://github.com/rust-lang/rust/issues/36394) +// +// Notably this nails down part of the behavior that `MaybeUninit` assumes: that a +// `Option>` does not take advantage of non-zero optimization, and thus is a safe +// construct. + use std::mem::{size_of, transmute}; union U1 { From aa1db2476a7b6e3155bf40cc48f6bc897575c622 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Tue, 7 May 2019 12:17:28 -0400 Subject: [PATCH 044/239] Add non-non-zero test to union-nonzero test --- src/test/run-pass/union/union-nonzero.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test/run-pass/union/union-nonzero.rs b/src/test/run-pass/union/union-nonzero.rs index 07a58aa7746d..2108cc3a4ea7 100644 --- a/src/test/run-pass/union/union-nonzero.rs +++ b/src/test/run-pass/union/union-nonzero.rs @@ -24,10 +24,18 @@ union U2 { b: B, } +// Option uses a value other than 0 and 1 as None +#[derive(Clone,Copy)] +enum E { + A = 0, + B = 1, +} + fn main() { // Unions do not participate in niche-filling/non-zero optimization... assert!(size_of::>>() > size_of::>()); assert!(size_of::>>() > size_of::>()); + assert!(size_of::>>() > size_of::>()); // ...even when theoretically possible: assert!(size_of::>>() > size_of::>()); From 58d39a93a04ca1f322a1a899f59390339f696c36 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Wed, 8 May 2019 23:45:19 +0200 Subject: [PATCH 045/239] save-analysis: Fix ICE when processing associated constant --- src/librustc_save_analysis/dump_visitor.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index a45e32ddb669..1e65f868ebac 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -463,10 +463,12 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { } // walk type and init value - self.visit_ty(typ); - if let Some(expr) = expr { - self.visit_expr(expr); - } + self.nest_tables(id, |v| { + v.visit_ty(typ); + if let Some(expr) = expr { + v.visit_expr(expr); + } + }); } // FIXME tuple structs should generate tuple-specific data. From e73ba21ce1c788c43ce2efd70e00176c1caacf02 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Thu, 9 May 2019 14:06:36 +0200 Subject: [PATCH 046/239] save-analysis: Add UI testsuite --- src/test/ui/save-analysis/issue-59134-0.rs | 12 ++++++++++++ src/test/ui/save-analysis/issue-59134-0.stderr | 9 +++++++++ src/test/ui/save-analysis/issue-59134-1.rs | 12 ++++++++++++ src/test/ui/save-analysis/issue-59134-1.stderr | 9 +++++++++ 4 files changed, 42 insertions(+) create mode 100644 src/test/ui/save-analysis/issue-59134-0.rs create mode 100644 src/test/ui/save-analysis/issue-59134-0.stderr create mode 100644 src/test/ui/save-analysis/issue-59134-1.rs create mode 100644 src/test/ui/save-analysis/issue-59134-1.stderr diff --git a/src/test/ui/save-analysis/issue-59134-0.rs b/src/test/ui/save-analysis/issue-59134-0.rs new file mode 100644 index 000000000000..93c7fbbca846 --- /dev/null +++ b/src/test/ui/save-analysis/issue-59134-0.rs @@ -0,0 +1,12 @@ +// compile-flags: -Zsave-analysis + +// Check that this doesn't ICE when processing associated const (field expr). + +pub fn f() { + trait Trait {} + impl Trait { + const FLAG: u32 = bogus.field; //~ ERROR cannot find value `bogus` + } +} + +fn main() {} \ No newline at end of file diff --git a/src/test/ui/save-analysis/issue-59134-0.stderr b/src/test/ui/save-analysis/issue-59134-0.stderr new file mode 100644 index 000000000000..4e9b2e6fdeb4 --- /dev/null +++ b/src/test/ui/save-analysis/issue-59134-0.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `bogus` in this scope + --> $DIR/issue-59134-0.rs:8:27 + | +LL | const FLAG: u32 = bogus.field; + | ^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/save-analysis/issue-59134-1.rs b/src/test/ui/save-analysis/issue-59134-1.rs new file mode 100644 index 000000000000..085f22cacbc5 --- /dev/null +++ b/src/test/ui/save-analysis/issue-59134-1.rs @@ -0,0 +1,12 @@ +// compile-flags: -Zsave-analysis + +// Check that this doesn't ICE when processing associated const (type). + +fn func() { + trait Trait { + type MyType; + const CONST: Self::MyType = bogus.field; //~ ERROR cannot find value `bogus` + } +} + +fn main() {} \ No newline at end of file diff --git a/src/test/ui/save-analysis/issue-59134-1.stderr b/src/test/ui/save-analysis/issue-59134-1.stderr new file mode 100644 index 000000000000..bdc335eaac04 --- /dev/null +++ b/src/test/ui/save-analysis/issue-59134-1.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `bogus` in this scope + --> $DIR/issue-59134-1.rs:8:37 + | +LL | const CONST: Self::MyType = bogus.field; + | ^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. From 0af18eed107f8b5d113e7d8e33f9182e37f0996b Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Thu, 9 May 2019 16:15:53 +0200 Subject: [PATCH 047/239] Appease tidy --- src/test/ui/save-analysis/issue-59134-0.rs | 2 +- src/test/ui/save-analysis/issue-59134-1.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/save-analysis/issue-59134-0.rs b/src/test/ui/save-analysis/issue-59134-0.rs index 93c7fbbca846..3158328b3ff1 100644 --- a/src/test/ui/save-analysis/issue-59134-0.rs +++ b/src/test/ui/save-analysis/issue-59134-0.rs @@ -9,4 +9,4 @@ pub fn f() { } } -fn main() {} \ No newline at end of file +fn main() {} diff --git a/src/test/ui/save-analysis/issue-59134-1.rs b/src/test/ui/save-analysis/issue-59134-1.rs index 085f22cacbc5..3cb629777a49 100644 --- a/src/test/ui/save-analysis/issue-59134-1.rs +++ b/src/test/ui/save-analysis/issue-59134-1.rs @@ -9,4 +9,4 @@ fn func() { } } -fn main() {} \ No newline at end of file +fn main() {} From 1acd37fde5b07c66853b925d7d91dd3be6dc2a78 Mon Sep 17 00:00:00 2001 From: Dodo Date: Thu, 9 May 2019 20:30:36 +0200 Subject: [PATCH 048/239] make vecdeque_rotate stable --- src/liballoc/collections/vec_deque.rs | 8 ++------ src/liballoc/tests/lib.rs | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index d65c24f7350a..7e7a854d2f33 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -1934,8 +1934,6 @@ impl VecDeque { /// # Examples /// /// ``` - /// #![feature(vecdeque_rotate)] - /// /// use std::collections::VecDeque; /// /// let mut buf: VecDeque<_> = (0..10).collect(); @@ -1949,7 +1947,7 @@ impl VecDeque { /// } /// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); /// ``` - #[unstable(feature = "vecdeque_rotate", issue = "56686")] + #[stable(feature = "vecdeque_rotate", since = "1.35.0")] pub fn rotate_left(&mut self, mid: usize) { assert!(mid <= self.len()); let k = self.len() - mid; @@ -1979,8 +1977,6 @@ impl VecDeque { /// # Examples /// /// ``` - /// #![feature(vecdeque_rotate)] - /// /// use std::collections::VecDeque; /// /// let mut buf: VecDeque<_> = (0..10).collect(); @@ -1994,7 +1990,7 @@ impl VecDeque { /// } /// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); /// ``` - #[unstable(feature = "vecdeque_rotate", issue = "56686")] + #[stable(feature = "vecdeque_rotate", since = "1.35.0")] pub fn rotate_right(&mut self, k: usize) { assert!(k <= self.len()); let mid = self.len() - k; diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index b736750c5760..ddb3120e89d7 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -6,7 +6,6 @@ #![feature(repeat_generic_slice)] #![feature(try_reserve)] #![feature(unboxed_closures)] -#![feature(vecdeque_rotate)] #![deny(rust_2018_idioms)] use std::hash::{Hash, Hasher}; From 1fe3ce1c42b8125f4f93dd3c3a5d5eed8c0cb651 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 30 Apr 2019 19:37:25 -0700 Subject: [PATCH 049/239] Omit the vendor component in the WASI triple This renames wasm32-unknown-wasi to wasm32-wasi, omitting the vendor component. This follows aarch64-linux-android, x86_64-fuchsia, and others in omitting the vendor field, which has the advantage of aligning with the [multiarch tuple](https://wiki.debian.org/Multiarch/Tuples), and of being less noisy. --- config.toml.example | 2 +- src/ci/docker/dist-various-2/Dockerfile | 4 +-- .../dist-various-2/build-wasi-toolchain.sh | 2 +- src/librustc_target/spec/mod.rs | 2 +- ...{wasm32_unknown_wasi.rs => wasm32_wasi.rs} | 34 +++++++++---------- src/tools/build-manifest/src/main.rs | 2 +- 6 files changed, 23 insertions(+), 23 deletions(-) rename src/librustc_target/spec/{wasm32_unknown_wasi.rs => wasm32_wasi.rs} (80%) diff --git a/config.toml.example b/config.toml.example index 8b2153cd2e63..556625b531d1 100644 --- a/config.toml.example +++ b/config.toml.example @@ -480,7 +480,7 @@ # linked binaries #musl-root = "..." -# The root location of the `wasm32-unknown-wasi` sysroot. +# The root location of the `wasm32-wasi` sysroot. #wasi-root = "..." # Used in testing for configuring where the QEMU images are located, you diff --git a/src/ci/docker/dist-various-2/Dockerfile b/src/ci/docker/dist-various-2/Dockerfile index c0f3326524d5..b0a3f715b494 100644 --- a/src/ci/docker/dist-various-2/Dockerfile +++ b/src/ci/docker/dist-various-2/Dockerfile @@ -69,7 +69,7 @@ ENV TARGETS=x86_64-fuchsia ENV TARGETS=$TARGETS,aarch64-fuchsia ENV TARGETS=$TARGETS,sparcv9-sun-solaris ENV TARGETS=$TARGETS,wasm32-unknown-unknown -ENV TARGETS=$TARGETS,wasm32-unknown-wasi +ENV TARGETS=$TARGETS,wasm32-wasi ENV TARGETS=$TARGETS,x86_64-sun-solaris ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32 ENV TARGETS=$TARGETS,x86_64-unknown-cloudabi @@ -79,5 +79,5 @@ ENV TARGETS=$TARGETS,nvptx64-nvidia-cuda ENV X86_FORTANIX_SGX_LIBS="/x86_64-fortanix-unknown-sgx/lib/" ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --disable-docs \ - --set target.wasm32-unknown-wasi.wasi-root=/wasm32-unknown-wasi + --set target.wasm32-wasi.wasi-root=/wasm32-wasi ENV SCRIPT python2.7 ../x.py dist --target $TARGETS diff --git a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh index 965286e5bcf6..98d6df043bac 100755 --- a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh +++ b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh @@ -13,7 +13,7 @@ git clone https://github.com/CraneStation/wasi-sysroot cd wasi-sysroot git reset --hard e5f14be38362f1ab83302895a6e74b2ffd0e2302 -make -j$(nproc) INSTALL_DIR=/wasm32-unknown-wasi install +make -j$(nproc) INSTALL_DIR=/wasm32-wasi install cd .. rm -rf reference-sysroot-wasi diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 46fefd78f451..b30a4fe76a2d 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -444,7 +444,7 @@ supported_targets! { ("asmjs-unknown-emscripten", asmjs_unknown_emscripten), ("wasm32-unknown-emscripten", wasm32_unknown_emscripten), ("wasm32-unknown-unknown", wasm32_unknown_unknown), - ("wasm32-unknown-wasi", wasm32_unknown_wasi), + ("wasm32-wasi", wasm32_wasi), ("wasm32-experimental-emscripten", wasm32_experimental_emscripten), ("thumbv6m-none-eabi", thumbv6m_none_eabi), diff --git a/src/librustc_target/spec/wasm32_unknown_wasi.rs b/src/librustc_target/spec/wasm32_wasi.rs similarity index 80% rename from src/librustc_target/spec/wasm32_unknown_wasi.rs rename to src/librustc_target/spec/wasm32_wasi.rs index 0412635bfe2d..bb33493a7733 100644 --- a/src/librustc_target/spec/wasm32_unknown_wasi.rs +++ b/src/librustc_target/spec/wasm32_wasi.rs @@ -1,4 +1,4 @@ -//! The `wasm32-unknown-wasi` target is a new and still (as of March 2019) +//! The `wasm32-wasi` target is a new and still (as of April 2019) an //! experimental target. The definition in this file is likely to be tweaked //! over time and shouldn't be relied on too much. //! @@ -13,14 +13,14 @@ //! serve two use cases here with this target: //! //! * First, we want Rust usage of the target to be as hassle-free as possible, -//! ideally avoiding the need to configure and install a local -//! wasm32-unknown-wasi toolchain. +//! ideally avoiding the need to configure and install a local wasm32-wasi +//! toolchain. //! //! * Second, one of the primary use cases of LLVM's new wasm backend and the //! wasm support in LLD is that any compiled language can interoperate with -//! any other. To that the `wasm32-unknown-wasi` target is the first with a -//! viable C standard library and sysroot common definition, so we want Rust -//! and C/C++ code to interoperate when compiled to `wasm32-unknown-unknown`. +//! any other. To that the `wasm32-wasi` target is the first with a viable C +//! standard library and sysroot common definition, so we want Rust and C/C++ +//! code to interoperate when compiled to `wasm32-unknown-unknown`. //! //! You'll note, however, that the two goals above are somewhat at odds with one //! another. To attempt to solve both use cases in one go we define a target @@ -39,8 +39,8 @@ //! necessary. //! //! All in all, by default, no external dependencies are required. You can -//! compile `wasm32-unknown-wasi` binaries straight out of the box. You can't, -//! however, reliably interoperate with C code in this mode (yet). +//! compile `wasm32-wasi` binaries straight out of the box. You can't, however, +//! reliably interoperate with C code in this mode (yet). //! //! ## Interop with C required //! @@ -53,17 +53,17 @@ //! //! 2. If you're using rustc to build a linked artifact then you'll need to //! specify `-C linker` to a `clang` binary that supports -//! `wasm32-unknown-wasi` and is configured with the `wasm32-unknown-wasi` -//! sysroot. This will cause Rust code to be linked against the libc.a that -//! the specified `clang` provides. +//! `wasm32-wasi` and is configured with the `wasm32-wasi` sysroot. This +//! will cause Rust code to be linked against the libc.a that the specified +//! `clang` provides. //! //! 3. If you're building a staticlib and integrating Rust code elsewhere, then //! compiling with `-C target-feature=-crt-static` is all you need to do. //! //! You can configure the linker via Cargo using the -//! `CARGO_TARGET_WASM32_UNKNOWN_WASI_LINKER` env var. Be sure to also set -//! `CC_wasm32-unknown-wasi` if any crates in the dependency graph are using -//! the `cc` crate. +//! `CARGO_TARGET_WASM32_WASI_LINKER` env var. Be sure to also set +//! `CC_wasm32-wasi` if any crates in the dependency graph are using the `cc` +//! crate. //! //! ## Remember, this is all in flux //! @@ -82,7 +82,7 @@ pub fn target() -> Result { .pre_link_args .entry(LinkerFlavor::Gcc) .or_insert(Vec::new()) - .push("--target=wasm32-unknown-wasi".to_string()); + .push("--target=wasm32-wasi".to_string()); // When generating an executable be sure to put the startup object at the // front so the main function is correctly hooked up. @@ -98,13 +98,13 @@ pub fn target() -> Result { options.crt_static_respected = true; Ok(Target { - llvm_target: "wasm32-unknown-wasi".to_string(), + llvm_target: "wasm32-wasi".to_string(), target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), target_os: "wasi".to_string(), target_env: String::new(), - target_vendor: "unknown".to_string(), + target_vendor: String::new(), data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(), arch: "wasm32".to_string(), linker_flavor: LinkerFlavor::Lld(LldFlavor::Wasm), diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 61cc78ad807a..5efd51b65c14 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -108,7 +108,7 @@ static TARGETS: &[&str] = &[ "thumbv8m.main-none-eabihf", "wasm32-unknown-emscripten", "wasm32-unknown-unknown", - "wasm32-unknown-wasi", + "wasm32-wasi", "x86_64-apple-darwin", "x86_64-apple-ios", "x86_64-fortanix-unknown-sgx", From 4d033990fcb96023739a13c43e72b341de51e865 Mon Sep 17 00:00:00 2001 From: Dodo Date: Thu, 9 May 2019 20:50:02 +0200 Subject: [PATCH 050/239] supposed to be 1.36.0 --- src/liballoc/collections/vec_deque.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 7e7a854d2f33..65a888a97036 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -1947,7 +1947,7 @@ impl VecDeque { /// } /// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); /// ``` - #[stable(feature = "vecdeque_rotate", since = "1.35.0")] + #[stable(feature = "vecdeque_rotate", since = "1.36.0")] pub fn rotate_left(&mut self, mid: usize) { assert!(mid <= self.len()); let k = self.len() - mid; @@ -1990,7 +1990,7 @@ impl VecDeque { /// } /// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); /// ``` - #[stable(feature = "vecdeque_rotate", since = "1.35.0")] + #[stable(feature = "vecdeque_rotate", since = "1.36.0")] pub fn rotate_right(&mut self, k: usize) { assert!(k <= self.len()); let mid = self.len() - k; From adb998fe21f148e8f84fc1262725c4385216c95d Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Thu, 9 May 2019 15:00:06 -0700 Subject: [PATCH 051/239] Fix cfg(test) build on SGX --- src/libstd/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 3976f2344e24..2401946536ff 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -223,6 +223,7 @@ #![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"), feature(global_asm, slice_index_methods, decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))] +#![cfg_attr(all(test, target_vendor = "fortanix", target_env = "sgx"), feature(fixed_size_array))] // std is implemented with unstable features, many of which are internal // compiler details that will never be stable From 08cd34e4fc062345dd20c018384b360cd57915b1 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 9 May 2019 15:37:37 -0700 Subject: [PATCH 052/239] Switch to SPDX 2.1 license expression According to the Cargo Reference: https://doc.rust-lang.org/cargo/reference/manifest.html > This is an SPDX 2.1 license expression for this package. Currently > crates.io will validate the license provided against a whitelist of > known license and exception identifiers from the SPDX license list > 2.4. Parentheses are not currently supported. > > Multiple licenses can be separated with a `/`, although that usage > is deprecated. Instead, use a license expression with AND and OR > operators to get more explicit semantics. --- src/libstd/Cargo.toml | 2 +- src/tools/rustbook/Cargo.toml | 2 +- src/tools/rustc-std-workspace-alloc/Cargo.toml | 2 +- src/tools/rustc-std-workspace-core/Cargo.toml | 2 +- src/tools/rustc-workspace-hack/Cargo.toml | 2 +- src/tools/unstable-book-gen/Cargo.toml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index ad5d62f667ac..5d797b756213 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -3,7 +3,7 @@ authors = ["The Rust Project Developers"] name = "std" version = "0.0.0" build = "build.rs" -license = "MIT/Apache-2.0" +license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/rust.git" description = "The Rust Standard Library" edition = "2018" diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index 5bf1553b2271..d2b1a7bac60a 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -2,7 +2,7 @@ authors = ["The Rust Project Developers"] name = "rustbook" version = "0.1.0" -license = "MIT/Apache-2.0" +license = "MIT OR Apache-2.0" edition = "2018" [dependencies] diff --git a/src/tools/rustc-std-workspace-alloc/Cargo.toml b/src/tools/rustc-std-workspace-alloc/Cargo.toml index 98578914963d..05df1fddc7f1 100644 --- a/src/tools/rustc-std-workspace-alloc/Cargo.toml +++ b/src/tools/rustc-std-workspace-alloc/Cargo.toml @@ -2,7 +2,7 @@ name = "rustc-std-workspace-alloc" version = "1.0.0" authors = ["Alex Crichton "] -license = 'MIT/Apache-2.0' +license = 'MIT OR Apache-2.0' description = """ Hack for the compiler's own build system """ diff --git a/src/tools/rustc-std-workspace-core/Cargo.toml b/src/tools/rustc-std-workspace-core/Cargo.toml index d527ce12bc3a..38ca56a557be 100644 --- a/src/tools/rustc-std-workspace-core/Cargo.toml +++ b/src/tools/rustc-std-workspace-core/Cargo.toml @@ -2,7 +2,7 @@ name = "rustc-std-workspace-core" version = "1.0.0" authors = ["Alex Crichton "] -license = 'MIT/Apache-2.0' +license = 'MIT OR Apache-2.0' description = """ Hack for the compiler's own build system """ diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml index d51841cd6507..290c4481c005 100644 --- a/src/tools/rustc-workspace-hack/Cargo.toml +++ b/src/tools/rustc-workspace-hack/Cargo.toml @@ -2,7 +2,7 @@ name = "rustc-workspace-hack" version = "1.0.0" authors = ["Alex Crichton "] -license = 'MIT/Apache-2.0' +license = 'MIT OR Apache-2.0' description = """ Hack for the compiler's own build system """ diff --git a/src/tools/unstable-book-gen/Cargo.toml b/src/tools/unstable-book-gen/Cargo.toml index 3209de09aeb6..e43e4e6c7cb5 100644 --- a/src/tools/unstable-book-gen/Cargo.toml +++ b/src/tools/unstable-book-gen/Cargo.toml @@ -3,7 +3,7 @@ authors = ["est31 ", "The Rust Project Developers"] name = "unstable-book-gen" version = "0.1.0" -license = "MIT/Apache-2.0" +license = "MIT OR Apache-2.0" edition = "2018" [dependencies] From 7c55b48d3121178ca05e04812e4c708f7fa6dff5 Mon Sep 17 00:00:00 2001 From: MaulingMonkey Date: Thu, 9 May 2019 16:15:43 -0700 Subject: [PATCH 053/239] Fix .natvis visualizers. Updated to handle these changes: - `core::ptr::*` lost their `__0` elements and are just plain pointers - `core::ptr::*` probably shouldn't dereference in `DisplayString` s - `VecDeque` and `Vec` use `core::ptr::*` s - `VecDeque` and `LinkedList` moved modules again. Retested - still working fine, left alone: - `String`, `&str`, `Option` --- src/etc/natvis/liballoc.natvis | 12 ++++++------ src/etc/natvis/libcore.natvis | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/etc/natvis/liballoc.natvis b/src/etc/natvis/liballoc.natvis index e3d99e34b357..de30b58526a1 100644 --- a/src/etc/natvis/liballoc.natvis +++ b/src/etc/natvis/liballoc.natvis @@ -7,11 +7,11 @@ buf.cap len - buf.ptr.pointer.__0 + buf.ptr.pointer - + {{ size={tail <= head ? head - tail : buf.cap - tail + head} }} tail <= head ? head - tail : buf.cap - tail + head @@ -24,19 +24,19 @@ - buf.ptr.pointer.__0 + i + buf.ptr.pointer[i] i = (i + 1 == buf.cap ? 0 : i + 1) - + {{ size={len} }} len - *(alloc::linked_list::Node<$T1> **)&head - *(alloc::linked_list::Node<$T1> **)&next + *(alloc::collections::linked_list::Node<$T1> **)&head + *(alloc::collections::linked_list::Node<$T1> **)&next element diff --git a/src/etc/natvis/libcore.natvis b/src/etc/natvis/libcore.natvis index 37d64be1ce96..0e703b3b9502 100644 --- a/src/etc/natvis/libcore.natvis +++ b/src/etc/natvis/libcore.natvis @@ -1,15 +1,15 @@ - {{ Unique {*pointer.__0} }} + {{ Unique {pointer} }} - pointer.__0 + pointer - {{ Shared {*pointer.__0} }} + {{ Shared {pointer} }} - pointer.__0 + pointer From c921aaed3967ba03b55ce1a6e2e4b192d95599c5 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Fri, 10 May 2019 14:44:43 +0900 Subject: [PATCH 054/239] Include expression to wait for to the span of Await --- src/libsyntax/parse/parser.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d97d1e2f0f4e..ddc145e1cded 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2764,6 +2764,7 @@ impl<'a> Parser<'a> { self.expect(&token::OpenDelim(token::Paren))?; let expr = self.parse_expr()?; self.expect(&token::CloseDelim(token::Paren))?; + hi = self.prev_span; ex = ExprKind::Await(ast::AwaitOrigin::MacroLike, expr); } else if self.token.is_path_start() { let path = self.parse_path(PathStyle::Expr)?; From 8c465b4efab9dec55434193acacf0a10e83c3ae0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 9 May 2019 11:45:56 +1000 Subject: [PATCH 055/239] Add `InternedString::with2`. This lets comparisons occur with a single access to the interner, instead of two. --- src/libsyntax_pos/symbol.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 20759217b54a..107cf8360c4f 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -725,6 +725,15 @@ impl InternedString { unsafe { f(&*str) } } + fn with2 R, R>(self, other: &InternedString, f: F) -> R { + let (self_str, other_str) = with_interner(|interner| { + (interner.get(self.symbol) as *const str, + interner.get(other.symbol) as *const str) + }); + // This is safe for the same reason that `with` is safe. + unsafe { f(&*self_str, &*other_str) } + } + pub fn as_symbol(self) -> Symbol { self.symbol } @@ -745,7 +754,7 @@ impl PartialOrd for InternedString { if self.symbol == other.symbol { return Some(Ordering::Equal); } - self.with(|self_str| other.with(|other_str| self_str.partial_cmp(other_str))) + self.with2(other, |self_str, other_str| self_str.partial_cmp(other_str)) } } @@ -754,7 +763,7 @@ impl Ord for InternedString { if self.symbol == other.symbol { return Ordering::Equal; } - self.with(|self_str| other.with(|other_str| self_str.cmp(&other_str))) + self.with2(other, |self_str, other_str| self_str.cmp(other_str)) } } From c2cae7bbc3880ec2874b32756c7c5dc52997a552 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 9 May 2019 11:54:47 +1000 Subject: [PATCH 056/239] Avoid recursion in de-gensym functions. --- src/libsyntax_pos/symbol.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 107cf8360c4f..e8472e1b9f1f 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -492,7 +492,7 @@ impl Interner { if (symbol.0.as_usize()) < self.strings.len() { symbol } else { - self.interned(self.gensyms[(SymbolIndex::MAX_AS_U32 - symbol.0.as_u32()) as usize]) + self.gensyms[(SymbolIndex::MAX_AS_U32 - symbol.0.as_u32()) as usize] } } @@ -513,7 +513,10 @@ impl Interner { pub fn get(&self, symbol: Symbol) -> &str { match self.strings.get(symbol.0.as_usize()) { Some(string) => string, - None => self.get(self.gensyms[(SymbolIndex::MAX_AS_U32 - symbol.0.as_u32()) as usize]), + None => { + let symbol = self.gensyms[(SymbolIndex::MAX_AS_U32 - symbol.0.as_u32()) as usize]; + self.strings[symbol.0.as_usize()] + } } } } From 0e27c36145594dcf3f00707543f11f591a63ec95 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 9 May 2019 12:09:57 +1000 Subject: [PATCH 057/239] Add various comments. Lots of details I wish I'd known when I first looked at this code. --- src/libsyntax_pos/symbol.rs | 52 ++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index e8472e1b9f1f..ee4a581123f8 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -344,9 +344,22 @@ impl Decodable for Ident { } } -/// A symbol is an interned or gensymed string. The use of `newtype_index!` means -/// that `Option` only takes up 4 bytes, because `newtype_index!` reserves -/// the last 256 values for tagging purposes. +/// A symbol is an interned or gensymed string. A gensym is a symbol that is +/// never equal to any other symbol. E.g.: +/// ``` +/// assert_eq!(Symbol::intern("x"), Symbol::intern("x")) +/// assert_ne!(Symbol::gensym("x"), Symbol::intern("x")) +/// assert_ne!(Symbol::gensym("x"), Symbol::gensym("x")) +/// ``` +/// Conceptually, a gensym can be thought of as a normal symbol with an +/// invisible unique suffix. Gensyms are useful when creating new identifiers +/// that must not match any existing identifiers, e.g. during macro expansion +/// and syntax desugaring. +/// +/// Internally, a Symbol is implemented as an index, and all operations +/// (including hashing, equality, and ordering) operate on that index. The use +/// of `newtype_index!` means that `Option` only takes up 4 bytes, +/// because `newtype_index!` reserves the last 256 values for tagging purposes. /// /// Note that `Symbol` cannot directly be a `newtype_index!` because it implements /// `fmt::Debug`, `Encodable`, and `Decodable` in special ways. @@ -380,6 +393,7 @@ impl Symbol { with_interner(|interner| interner.gensymed(self)) } + // WARNING: this function is deprecated and will be removed in the future. pub fn is_gensymed(self) -> bool { with_interner(|interner| interner.is_gensymed(self)) } @@ -510,6 +524,8 @@ impl Interner { symbol.0.as_usize() >= self.strings.len() } + // Get the symbol as a string. `Symbol::as_str()` should be used in + // preference to this function. pub fn get(&self, symbol: Symbol) -> &str { match self.strings.get(symbol.0.as_usize()) { Some(string) => string, @@ -614,11 +630,17 @@ fn with_interner T>(f: F) -> T { GLOBALS.with(|globals| f(&mut *globals.symbol_interner.lock())) } -/// Represents a string stored in the interner. Because the interner outlives any thread -/// which uses this type, we can safely treat `string` which points to interner data, -/// as an immortal string, as long as this type never crosses between threads. -// FIXME: ensure that the interner outlives any thread which uses `LocalInternedString`, -// by creating a new thread right after constructing the interner. +/// An alternative to `Symbol` and `InternedString`, useful when the chars +/// within the symbol need to be accessed. It is best used for temporary +/// values. +/// +/// Because the interner outlives any thread which uses this type, we can +/// safely treat `string` which points to interner data, as an immortal string, +/// as long as this type never crosses between threads. +// +// FIXME: ensure that the interner outlives any thread which uses +// `LocalInternedString`, by creating a new thread right after constructing the +// interner. #[derive(Clone, Copy, Hash, PartialOrd, Eq, Ord)] pub struct LocalInternedString { string: &'static str, @@ -711,7 +733,19 @@ impl Encodable for LocalInternedString { } } -/// Represents a string stored in the string interner. +/// An alternative to `Symbol` that is focused on string contents. It has two +/// main differences to `Symbol`. +/// +/// First, its implementations of `Hash`, `PartialOrd` and `Ord` work with the +/// string chars rather than the symbol integer. This is useful when hash +/// stability is required across compile sessions, or a guaranteed sort +/// ordering is required. +/// +/// Second, gensym-ness is irrelevant. E.g.: +/// ``` +/// assert_ne!(Symbol::gensym("x"), Symbol::gensym("x")) +/// assert_eq!(Symbol::gensym("x").as_interned_str(), Symbol::gensym("x").as_interned_str()) +/// ``` #[derive(Clone, Copy, Eq)] pub struct InternedString { symbol: Symbol, From cb7eacb1d2f856f52f2daf3b58325e667f654eca Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 9 May 2019 12:14:30 +1000 Subject: [PATCH 058/239] Remove the `From for String` impl. It's not used. --- src/libsyntax_pos/symbol.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index ee4a581123f8..231cfb793f84 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -840,12 +840,6 @@ impl<'a> PartialEq for &'a String { } } -impl std::convert::From for String { - fn from(val: InternedString) -> String { - val.as_symbol().to_string() - } -} - impl fmt::Debug for InternedString { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.with(|str| fmt::Debug::fmt(&str, f)) From e53bb1aefb0aba8fcadaf73b2c0f334dd36c2b23 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 9 May 2019 14:06:10 +1000 Subject: [PATCH 059/239] Reduce `Symbol`'s interface slightly. --- src/libsyntax_pos/symbol.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 231cfb793f84..d0ba09af30b0 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -380,10 +380,6 @@ impl Symbol { with_interner(|interner| interner.intern(string)) } - pub fn interned(self) -> Self { - with_interner(|interner| interner.interned(self)) - } - /// Gensyms a new `usize`, using the current interner. pub fn gensym(string: &str) -> Self { with_interner(|interner| interner.gensym(string)) @@ -502,7 +498,7 @@ impl Interner { name } - pub fn interned(&self, symbol: Symbol) -> Symbol { + fn interned(&self, symbol: Symbol) -> Symbol { if (symbol.0.as_usize()) < self.strings.len() { symbol } else { From d28b7afd17e26c6b17a65b981684d03a0905c293 Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 10 May 2019 08:55:54 +0100 Subject: [PATCH 060/239] Extend existing test for nested mut patterns. At request of `@centril`, this commit extends the existing test added by #60676 to include nested `mut` patterns. --- src/test/ui/async-await/issue-60674.rs | 6 ++++++ src/test/ui/async-await/issue-60674.stdout | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/test/ui/async-await/issue-60674.rs b/src/test/ui/async-await/issue-60674.rs index 37e356e5baf4..ecb80803383b 100644 --- a/src/test/ui/async-await/issue-60674.rs +++ b/src/test/ui/async-await/issue-60674.rs @@ -11,4 +11,10 @@ extern crate issue_60674; #[issue_60674::attr] async fn f(mut x: u8) {} +#[issue_60674::attr] +async fn g((mut x, y, mut z): (u8, u8, u8)) {} + +#[issue_60674::attr] +async fn g(mut x: u8, (a, mut b, c): (u8, u8, u8), y: u8) {} + fn main() {} diff --git a/src/test/ui/async-await/issue-60674.stdout b/src/test/ui/async-await/issue-60674.stdout index a93944db1c59..86c3591b3afc 100644 --- a/src/test/ui/async-await/issue-60674.stdout +++ b/src/test/ui/async-await/issue-60674.stdout @@ -1 +1,3 @@ async fn f(mut x: u8) { } +async fn g((mut x, y, mut z): (u8, u8, u8)) { } +async fn g(mut x: u8, (a, mut b, c): (u8, u8, u8), y: u8) { } From 11426a4d502cac062773071cf7fd320a383564ff Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Fri, 10 May 2019 10:19:58 +0530 Subject: [PATCH 061/239] refactor some `FnType` stuff to `rustc::ty::layout` --- src/librustc/ty/layout.rs | 349 +++++++++++++++++++++++++++++++ src/librustc_codegen_llvm/abi.rs | 291 -------------------------- 2 files changed, 349 insertions(+), 291 deletions(-) diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index d1a8a9a34e15..58d27d4c5dbe 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -19,6 +19,12 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; pub use rustc_target::abi::*; +use rustc_target::spec::HasTargetSpec; +use rustc_target::abi::call::{ + ArgAttribute, ArgAttributes, ArgType, Conv, FnType, IgnoreMode, PassMode +}; + + pub trait IntegerExt { fn to_ty<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, signed: bool) -> Ty<'tcx>; @@ -2259,3 +2265,346 @@ impl<'a, 'gcx> HashStable> for LayoutError<'gcx> } } } + +pub trait FnTypeExt<'tcx, C> { + fn of_instance(cx: &C, instance: &ty::Instance<'tcx>) -> Self + where + C: LayoutOf, TyLayout = TyLayout<'tcx>> + + HasDataLayout + + HasTargetSpec + + HasTyCtxt<'tcx> + + HasParamEnv<'tcx>; + fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self + where + C: LayoutOf, TyLayout = TyLayout<'tcx>> + + HasDataLayout + + HasTargetSpec + + HasTyCtxt<'tcx> + + HasParamEnv<'tcx>; + fn new_vtable(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self + where + C: LayoutOf, TyLayout = TyLayout<'tcx>> + + HasDataLayout + + HasTargetSpec + + HasTyCtxt<'tcx> + + HasParamEnv<'tcx>; + fn new_internal( + cx: &C, + sig: ty::FnSig<'tcx>, + extra_args: &[Ty<'tcx>], + mk_arg_type: impl Fn(Ty<'tcx>, Option) -> ArgType<'tcx, Ty<'tcx>>, + ) -> Self + where + C: LayoutOf, TyLayout = TyLayout<'tcx>> + + HasDataLayout + + HasTargetSpec + + HasTyCtxt<'tcx> + + HasParamEnv<'tcx>; +} + + +impl<'tcx, C> FnTypeExt<'tcx, C> for call::FnType<'tcx, Ty<'tcx>> { + fn of_instance(cx: &C, instance: &ty::Instance<'tcx>) -> Self + where + C: LayoutOf, TyLayout = TyLayout<'tcx>> + + HasDataLayout + + HasTargetSpec + + HasTargetSpec + + HasTyCtxt<'tcx> + + HasParamEnv<'tcx>, + { + let sig = instance.fn_sig(cx.tcx()); + let sig = cx + .tcx() + .normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); + call::FnType::new(cx, sig, &[]) + } + + fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self + where + C: LayoutOf, TyLayout = TyLayout<'tcx>> + + HasDataLayout + + HasTargetSpec + + HasTyCtxt<'tcx> + + HasParamEnv<'tcx>, + { + call::FnType::new_internal(cx, sig, extra_args, |ty, _| ArgType::new(cx.layout_of(ty))) + } + + + fn new_vtable(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self + where + C: LayoutOf, TyLayout = TyLayout<'tcx>> + + HasDataLayout + + HasTargetSpec + + HasTyCtxt<'tcx> + + HasParamEnv<'tcx>, + { + FnType::new_internal(cx, sig, extra_args, |ty, arg_idx| { + let mut layout = cx.layout_of(ty); + // Don't pass the vtable, it's not an argument of the virtual fn. + // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait` + // or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen + if arg_idx == Some(0) { + let fat_pointer_ty = if layout.is_unsized() { + // unsized `self` is passed as a pointer to `self` + // FIXME (mikeyhew) change this to use &own if it is ever added to the language + cx.tcx().mk_mut_ptr(layout.ty) + } else { + match layout.abi { + Abi::ScalarPair(..) => (), + _ => bug!("receiver type has unsupported layout: {:?}", layout), + } + + // In the case of Rc, we need to explicitly pass a *mut RcBox + // with a Scalar (not ScalarPair) ABI. This is a hack that is understood + // elsewhere in the compiler as a method on a `dyn Trait`. + // To get the type `*mut RcBox`, we just keep unwrapping newtypes until we + // get a built-in pointer type + let mut fat_pointer_layout = layout; + 'descend_newtypes: while !fat_pointer_layout.ty.is_unsafe_ptr() + && !fat_pointer_layout.ty.is_region_ptr() + { + 'iter_fields: for i in 0..fat_pointer_layout.fields.count() { + let field_layout = fat_pointer_layout.field(cx, i); + + if !field_layout.is_zst() { + fat_pointer_layout = field_layout; + continue 'descend_newtypes; + } + } + + bug!( + "receiver has no non-zero-sized fields {:?}", + fat_pointer_layout + ); + } + + fat_pointer_layout.ty + }; + + // we now have a type like `*mut RcBox` + // change its layout to that of `*mut ()`, a thin pointer, but keep the same type + // this is understood as a special case elsewhere in the compiler + let unit_pointer_ty = cx.tcx().mk_mut_ptr(cx.tcx().mk_unit()); + layout = cx.layout_of(unit_pointer_ty); + layout.ty = fat_pointer_ty; + } + ArgType::new(layout) + }) + } + + fn new_internal( + cx: &C, + sig: ty::FnSig<'tcx>, + extra_args: &[Ty<'tcx>], + mk_arg_type: impl Fn(Ty<'tcx>, Option) -> ArgType<'tcx, Ty<'tcx>>, + ) -> Self + where + C: LayoutOf, TyLayout = TyLayout<'tcx>> + + HasDataLayout + + HasTargetSpec + + HasTargetSpec + + HasTyCtxt<'tcx> + + HasParamEnv<'tcx>, + { + debug!("FnType::new_internal({:?}, {:?})", sig, extra_args); + + use rustc_target::spec::abi::Abi::*; + let conv = match cx.tcx().sess.target.target.adjust_abi(sig.abi) { + RustIntrinsic | PlatformIntrinsic | Rust | RustCall => Conv::C, + + // It's the ABI's job to select this, not ours. + System => bug!("system abi should be selected elsewhere"), + + Stdcall => Conv::X86Stdcall, + Fastcall => Conv::X86Fastcall, + Vectorcall => Conv::X86VectorCall, + Thiscall => Conv::X86ThisCall, + C => Conv::C, + Unadjusted => Conv::C, + Win64 => Conv::X86_64Win64, + SysV64 => Conv::X86_64SysV, + Aapcs => Conv::ArmAapcs, + PtxKernel => Conv::PtxKernel, + Msp430Interrupt => Conv::Msp430Intr, + X86Interrupt => Conv::X86Intr, + AmdGpuKernel => Conv::AmdGpuKernel, + + // These API constants ought to be more specific... + Cdecl => Conv::C, + }; + + let mut inputs = sig.inputs(); + let extra_args = if sig.abi == RustCall { + assert!(!sig.c_variadic && extra_args.is_empty()); + + match sig.inputs().last().unwrap().sty { + ty::Tuple(tupled_arguments) => { + inputs = &sig.inputs()[0..sig.inputs().len() - 1]; + tupled_arguments.iter().map(|k| k.expect_ty()).collect() + } + _ => { + bug!( + "argument to function with \"rust-call\" ABI \ + is not a tuple" + ); + } + } + } else { + assert!(sig.c_variadic || extra_args.is_empty()); + extra_args.to_vec() + }; + + let target = &cx.tcx().sess.target.target; + let win_x64_gnu = + target.target_os == "windows" && target.arch == "x86_64" && target.target_env == "gnu"; + let linux_s390x = + target.target_os == "linux" && target.arch == "s390x" && target.target_env == "gnu"; + let linux_sparc64 = + target.target_os == "linux" && target.arch == "sparc64" && target.target_env == "gnu"; + let rust_abi = match sig.abi { + RustIntrinsic | PlatformIntrinsic | Rust | RustCall => true, + _ => false, + }; + + // Handle safe Rust thin and fat pointers. + let adjust_for_rust_scalar = |attrs: &mut ArgAttributes, + scalar: &Scalar, + layout: TyLayout<'tcx>, + offset: Size, + is_return: bool| { + // Booleans are always an i1 that needs to be zero-extended. + if scalar.is_bool() { + attrs.set(ArgAttribute::ZExt); + return; + } + + // Only pointer types handled below. + if scalar.value != Pointer { + return; + } + + if scalar.valid_range.start() < scalar.valid_range.end() { + if *scalar.valid_range.start() > 0 { + attrs.set(ArgAttribute::NonNull); + } + } + + if let Some(pointee) = layout.pointee_info_at(cx, offset) { + if let Some(kind) = pointee.safe { + attrs.pointee_size = pointee.size; + attrs.pointee_align = Some(pointee.align); + + // `Box` pointer parameters never alias because ownership is transferred + // `&mut` pointer parameters never alias other parameters, + // or mutable global data + // + // `&T` where `T` contains no `UnsafeCell` is immutable, + // and can be marked as both `readonly` and `noalias`, as + // LLVM's definition of `noalias` is based solely on memory + // dependencies rather than pointer equality + let no_alias = match kind { + PointerKind::Shared => false, + PointerKind::UniqueOwned => true, + PointerKind::Frozen | PointerKind::UniqueBorrowed => !is_return, + }; + if no_alias { + attrs.set(ArgAttribute::NoAlias); + } + + if kind == PointerKind::Frozen && !is_return { + attrs.set(ArgAttribute::ReadOnly); + } + } + } + }; + + // Store the index of the last argument. This is useful for working with + // C-compatible variadic arguments. + let last_arg_idx = if sig.inputs().is_empty() { + None + } else { + Some(sig.inputs().len() - 1) + }; + + let arg_of = |ty: Ty<'tcx>, arg_idx: Option| { + let is_return = arg_idx.is_none(); + let mut arg = mk_arg_type(ty, arg_idx); + if arg.layout.is_zst() { + // For some forsaken reason, x86_64-pc-windows-gnu + // doesn't ignore zero-sized struct arguments. + // The same is true for s390x-unknown-linux-gnu + // and sparc64-unknown-linux-gnu. + if is_return || rust_abi || (!win_x64_gnu && !linux_s390x && !linux_sparc64) { + arg.mode = PassMode::Ignore(IgnoreMode::Zst); + } + } + + // If this is a C-variadic function, this is not the return value, + // and there is one or more fixed arguments; ensure that the `VaList` + // is ignored as an argument. + if sig.c_variadic { + match (last_arg_idx, arg_idx) { + (Some(last_idx), Some(cur_idx)) if last_idx == cur_idx => { + let va_list_did = match cx.tcx().lang_items().va_list() { + Some(did) => did, + None => bug!("`va_list` lang item required for C-variadic functions"), + }; + match ty.sty { + ty::Adt(def, _) if def.did == va_list_did => { + // This is the "spoofed" `VaList`. Set the arguments mode + // so that it will be ignored. + arg.mode = PassMode::Ignore(IgnoreMode::CVarArgs); + } + _ => (), + } + } + _ => {} + } + } + + // FIXME(eddyb) other ABIs don't have logic for scalar pairs. + if !is_return && rust_abi { + if let Abi::ScalarPair(ref a, ref b) = arg.layout.abi { + let mut a_attrs = ArgAttributes::new(); + let mut b_attrs = ArgAttributes::new(); + adjust_for_rust_scalar(&mut a_attrs, a, arg.layout, Size::ZERO, false); + adjust_for_rust_scalar( + &mut b_attrs, + b, + arg.layout, + a.value.size(cx).align_to(b.value.align(cx).abi), + false, + ); + arg.mode = PassMode::Pair(a_attrs, b_attrs); + return arg; + } + } + + if let Abi::Scalar(ref scalar) = arg.layout.abi { + if let PassMode::Direct(ref mut attrs) = arg.mode { + adjust_for_rust_scalar(attrs, scalar, arg.layout, Size::ZERO, is_return); + } + } + + arg + }; + + let fn_ty = FnType { + ret: arg_of(sig.output(), None), + args: inputs + .iter() + .cloned() + .chain(extra_args) + .enumerate() + .map(|(i, ty)| arg_of(ty, Some(i))) + .collect(), + c_variadic: sig.c_variadic, + conv, + }; + // FIXME: uncomment this after figuring out wwhere should adjust_for_abi reside. + //fn_ty.adjust_for_abi(cx, sig.abi); + fn_ty + } +} diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 70d184240fcc..cf4a523d9caa 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -295,19 +295,6 @@ impl ArgTypeMethods<'tcx> for Builder<'a, 'll, 'tcx> { } pub trait FnTypeExt<'tcx> { - fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>) -> Self; - fn new(cx: &CodegenCx<'ll, 'tcx>, - sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>]) -> Self; - fn new_vtable(cx: &CodegenCx<'ll, 'tcx>, - sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>]) -> Self; - fn new_internal( - cx: &CodegenCx<'ll, 'tcx>, - sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>], - mk_arg_type: impl Fn(Ty<'tcx>, Option) -> ArgType<'tcx, Ty<'tcx>>, - ) -> Self; fn adjust_for_abi(&mut self, cx: &CodegenCx<'ll, 'tcx>, abi: Abi); @@ -319,284 +306,6 @@ pub trait FnTypeExt<'tcx> { } impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> { - fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>) -> Self { - let sig = instance.fn_sig(cx.tcx); - let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); - FnType::new(cx, sig, &[]) - } - - fn new(cx: &CodegenCx<'ll, 'tcx>, - sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>]) -> Self { - FnType::new_internal(cx, sig, extra_args, |ty, _| { - ArgType::new(cx.layout_of(ty)) - }) - } - - fn new_vtable(cx: &CodegenCx<'ll, 'tcx>, - sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>]) -> Self { - FnType::new_internal(cx, sig, extra_args, |ty, arg_idx| { - let mut layout = cx.layout_of(ty); - // Don't pass the vtable, it's not an argument of the virtual fn. - // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait` - // or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen - if arg_idx == Some(0) { - let fat_pointer_ty = if layout.is_unsized() { - // unsized `self` is passed as a pointer to `self` - // FIXME (mikeyhew) change this to use &own if it is ever added to the language - cx.tcx.mk_mut_ptr(layout.ty) - } else { - match layout.abi { - LayoutAbi::ScalarPair(..) => (), - _ => bug!("receiver type has unsupported layout: {:?}", layout) - } - - // In the case of Rc, we need to explicitly pass a *mut RcBox - // with a Scalar (not ScalarPair) ABI. This is a hack that is understood - // elsewhere in the compiler as a method on a `dyn Trait`. - // To get the type `*mut RcBox`, we just keep unwrapping newtypes until we - // get a built-in pointer type - let mut fat_pointer_layout = layout; - 'descend_newtypes: while !fat_pointer_layout.ty.is_unsafe_ptr() - && !fat_pointer_layout.ty.is_region_ptr() - { - 'iter_fields: for i in 0..fat_pointer_layout.fields.count() { - let field_layout = fat_pointer_layout.field(cx, i); - - if !field_layout.is_zst() { - fat_pointer_layout = field_layout; - continue 'descend_newtypes - } - } - - bug!("receiver has no non-zero-sized fields {:?}", fat_pointer_layout); - } - - fat_pointer_layout.ty - }; - - // we now have a type like `*mut RcBox` - // change its layout to that of `*mut ()`, a thin pointer, but keep the same type - // this is understood as a special case elsewhere in the compiler - let unit_pointer_ty = cx.tcx.mk_mut_ptr(cx.tcx.mk_unit()); - layout = cx.layout_of(unit_pointer_ty); - layout.ty = fat_pointer_ty; - } - ArgType::new(layout) - }) - } - - fn new_internal( - cx: &CodegenCx<'ll, 'tcx>, - sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>], - mk_arg_type: impl Fn(Ty<'tcx>, Option) -> ArgType<'tcx, Ty<'tcx>>, - ) -> Self { - debug!("FnType::new_internal({:?}, {:?})", sig, extra_args); - - use self::Abi::*; - let conv = match cx.sess().target.target.adjust_abi(sig.abi) { - RustIntrinsic | PlatformIntrinsic | - Rust | RustCall => Conv::C, - - // It's the ABI's job to select this, not ours. - System => bug!("system abi should be selected elsewhere"), - - Stdcall => Conv::X86Stdcall, - Fastcall => Conv::X86Fastcall, - Vectorcall => Conv::X86VectorCall, - Thiscall => Conv::X86ThisCall, - C => Conv::C, - Unadjusted => Conv::C, - Win64 => Conv::X86_64Win64, - SysV64 => Conv::X86_64SysV, - Aapcs => Conv::ArmAapcs, - PtxKernel => Conv::PtxKernel, - Msp430Interrupt => Conv::Msp430Intr, - X86Interrupt => Conv::X86Intr, - AmdGpuKernel => Conv::AmdGpuKernel, - - // These API constants ought to be more specific... - Cdecl => Conv::C, - }; - - let mut inputs = sig.inputs(); - let extra_args = if sig.abi == RustCall { - assert!(!sig.c_variadic && extra_args.is_empty()); - - match sig.inputs().last().unwrap().sty { - ty::Tuple(tupled_arguments) => { - inputs = &sig.inputs()[0..sig.inputs().len() - 1]; - tupled_arguments.iter().map(|k| k.expect_ty()).collect() - } - _ => { - bug!("argument to function with \"rust-call\" ABI \ - is not a tuple"); - } - } - } else { - assert!(sig.c_variadic || extra_args.is_empty()); - extra_args.to_vec() - }; - - let target = &cx.sess().target.target; - let win_x64_gnu = target.target_os == "windows" - && target.arch == "x86_64" - && target.target_env == "gnu"; - let linux_s390x = target.target_os == "linux" - && target.arch == "s390x" - && target.target_env == "gnu"; - let linux_sparc64 = target.target_os == "linux" - && target.arch == "sparc64" - && target.target_env == "gnu"; - let rust_abi = match sig.abi { - RustIntrinsic | PlatformIntrinsic | Rust | RustCall => true, - _ => false - }; - - // Handle safe Rust thin and fat pointers. - let adjust_for_rust_scalar = |attrs: &mut ArgAttributes, - scalar: &layout::Scalar, - layout: TyLayout<'tcx, Ty<'tcx>>, - offset: Size, - is_return: bool| { - // Booleans are always an i1 that needs to be zero-extended. - if scalar.is_bool() { - attrs.set(ArgAttribute::ZExt); - return; - } - - // Only pointer types handled below. - if scalar.value != layout::Pointer { - return; - } - - if scalar.valid_range.start() < scalar.valid_range.end() { - if *scalar.valid_range.start() > 0 { - attrs.set(ArgAttribute::NonNull); - } - } - - if let Some(pointee) = layout.pointee_info_at(cx, offset) { - if let Some(kind) = pointee.safe { - attrs.pointee_size = pointee.size; - attrs.pointee_align = Some(pointee.align); - - // `Box` pointer parameters never alias because ownership is transferred - // `&mut` pointer parameters never alias other parameters, - // or mutable global data - // - // `&T` where `T` contains no `UnsafeCell` is immutable, - // and can be marked as both `readonly` and `noalias`, as - // LLVM's definition of `noalias` is based solely on memory - // dependencies rather than pointer equality - let no_alias = match kind { - PointerKind::Shared => false, - PointerKind::UniqueOwned => true, - PointerKind::Frozen | - PointerKind::UniqueBorrowed => !is_return - }; - if no_alias { - attrs.set(ArgAttribute::NoAlias); - } - - if kind == PointerKind::Frozen && !is_return { - attrs.set(ArgAttribute::ReadOnly); - } - } - } - }; - - // Store the index of the last argument. This is useful for working with - // C-compatible variadic arguments. - let last_arg_idx = if sig.inputs().is_empty() { - None - } else { - Some(sig.inputs().len() - 1) - }; - - let arg_of = |ty: Ty<'tcx>, arg_idx: Option| { - let is_return = arg_idx.is_none(); - let mut arg = mk_arg_type(ty, arg_idx); - if arg.layout.is_zst() { - // For some forsaken reason, x86_64-pc-windows-gnu - // doesn't ignore zero-sized struct arguments. - // The same is true for s390x-unknown-linux-gnu - // and sparc64-unknown-linux-gnu. - if is_return || rust_abi || (!win_x64_gnu && !linux_s390x && !linux_sparc64) { - arg.mode = PassMode::Ignore(IgnoreMode::Zst); - } - } - - // If this is a C-variadic function, this is not the return value, - // and there is one or more fixed arguments; ensure that the `VaList` - // is ignored as an argument. - if sig.c_variadic { - match (last_arg_idx, arg_idx) { - (Some(last_idx), Some(cur_idx)) if last_idx == cur_idx => { - let va_list_did = match cx.tcx.lang_items().va_list() { - Some(did) => did, - None => bug!("`va_list` lang item required for C-variadic functions"), - }; - match ty.sty { - ty::Adt(def, _) if def.did == va_list_did => { - // This is the "spoofed" `VaList`. Set the arguments mode - // so that it will be ignored. - arg.mode = PassMode::Ignore(IgnoreMode::CVarArgs); - }, - _ => (), - } - } - _ => {} - } - } - - // FIXME(eddyb) other ABIs don't have logic for scalar pairs. - if !is_return && rust_abi { - if let layout::Abi::ScalarPair(ref a, ref b) = arg.layout.abi { - let mut a_attrs = ArgAttributes::new(); - let mut b_attrs = ArgAttributes::new(); - adjust_for_rust_scalar(&mut a_attrs, - a, - arg.layout, - Size::ZERO, - false); - adjust_for_rust_scalar(&mut b_attrs, - b, - arg.layout, - a.value.size(cx).align_to(b.value.align(cx).abi), - false); - arg.mode = PassMode::Pair(a_attrs, b_attrs); - return arg; - } - } - - if let layout::Abi::Scalar(ref scalar) = arg.layout.abi { - if let PassMode::Direct(ref mut attrs) = arg.mode { - adjust_for_rust_scalar(attrs, - scalar, - arg.layout, - Size::ZERO, - is_return); - } - } - - arg - }; - - let mut fn_ty = FnType { - ret: arg_of(sig.output(), None), - args: inputs.iter().cloned().chain(extra_args).enumerate().map(|(i, ty)| { - arg_of(ty, Some(i)) - }).collect(), - c_variadic: sig.c_variadic, - conv, - }; - fn_ty.adjust_for_abi(cx, sig.abi); - fn_ty - } - fn adjust_for_abi(&mut self, cx: &CodegenCx<'ll, 'tcx>, abi: Abi) { From c81780b156c446819d94c9382eb590e881fa87b0 Mon Sep 17 00:00:00 2001 From: Marcel Hellwig Date: Fri, 10 May 2019 12:02:31 +0200 Subject: [PATCH 062/239] add regression test for #60629 --- src/test/incremental/issue-60629.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/test/incremental/issue-60629.rs diff --git a/src/test/incremental/issue-60629.rs b/src/test/incremental/issue-60629.rs new file mode 100644 index 000000000000..4807af4b3cf7 --- /dev/null +++ b/src/test/incremental/issue-60629.rs @@ -0,0 +1,10 @@ +// revisions:rpass1 rpass2 + +struct A; + +#[cfg(rpass2)] +impl From for () { + fn from(_: A) {} +} + +fn main() {} From aeee1fb1f250accccd85f8d7f7a501ed81db68e8 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 10 May 2019 16:57:15 +0300 Subject: [PATCH 063/239] syntax_pos: Optimize symbol interner pre-filling slightly --- src/libsyntax_pos/symbol.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 20759217b54a..23ab3e2bf945 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -453,15 +453,16 @@ pub struct Interner { impl Interner { fn prefill(init: &[&str]) -> Self { let mut this = Interner::default(); - for &string in init { - if string == "" { - // We can't allocate empty strings in the arena, so handle this here. - let name = Symbol::new(this.strings.len() as u32); - this.names.insert("", name); - this.strings.push(""); - } else { - this.intern(string); - } + this.names.reserve(init.len()); + this.strings.reserve(init.len()); + + // We can't allocate empty strings in the arena, so handle this here. + assert!(keywords::Invalid.name().as_u32() == 0 && init[0].is_empty()); + this.names.insert("", keywords::Invalid.name()); + this.strings.push(""); + + for string in &init[1..] { + this.intern(string); } this } From f74debbe7d2bf43171270d5f3f5b42f2cc2e6243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Thu, 2 May 2019 17:22:14 +0200 Subject: [PATCH 064/239] Make tests compatible with musl host --- src/bootstrap/test.rs | 4 ++++ src/ci/docker/dist-x86_64-musl/Dockerfile | 6 ++---- src/ci/docker/scripts/musl-toolchain.sh | 7 +++++++ src/test/run-make-fulldeps/link-cfg/Makefile | 2 +- .../linker-output-non-utf8/Makefile | 2 +- .../run-make-fulldeps/reproducible-build/Makefile | 4 ++++ src/test/run-make/rustc-macro-dep-files/Makefile | 5 ++++- src/tools/compiletest/src/runtest.rs | 15 ++++++++++++++- 8 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index a3d96836aad5..9867113e48f4 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1870,6 +1870,10 @@ impl Step for CrateRustdoc { cargo.arg("--"); cargo.args(&builder.config.cmd.test_args()); + if self.host.contains("musl") { + cargo.arg("'-Ctarget-feature=-crt-static'"); + } + if !builder.config.verbose_tests { cargo.arg("--quiet"); } diff --git a/src/ci/docker/dist-x86_64-musl/Dockerfile b/src/ci/docker/dist-x86_64-musl/Dockerfile index 39ad785b41ac..bc3a3bd6fbc6 100644 --- a/src/ci/docker/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/dist-x86_64-musl/Dockerfile @@ -35,10 +35,7 @@ ENV RUST_CONFIGURE_ARGS \ --enable-extended \ --disable-docs \ --set target.x86_64-unknown-linux-musl.crt-static=false \ - --build $HOSTS \ - --set target.x86_64-unknown-linux-musl.cc=x86_64-linux-musl-gcc \ - --set target.x86_64-unknown-linux-musl.cxx=x86_64-linux-musl-g++ \ - --set target.x86_64-unknown-linux-musl.linker=x86_64-linux-musl-gcc + --build $HOSTS # Newer binutils broke things on some vms/distros (i.e., linking against # unknown relocs disabled by the following flag), so we need to go out of our @@ -49,4 +46,5 @@ ENV RUST_CONFIGURE_ARGS \ ENV CFLAGS_x86_64_unknown_linux_musl="-Wa,-mrelax-relocations=no -Wa,--compress-debug-sections=none \ -Wl,--compress-debug-sections=none" +# To run native tests replace `dist` below with `test` ENV SCRIPT python2.7 ../x.py dist --build $HOSTS diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index 8cdbfebea4dd..e132615738ba 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -45,6 +45,13 @@ cd - ln -s $OUTPUT/$TARGET/lib/libc.so /lib/ld-musl-$ARCH.so.1 echo $OUTPUT/$TARGET/lib >> /etc/ld-musl-$ARCH.path +# Now when musl bootstraps itself create proper toolchain symlinks to make build and tests easier +for exec in cc gcc; do + ln -s $TARGET-gcc /usr/local/bin/$exec +done +for exec in cpp c++ g++; do + ln -s $TARGET-g++ /usr/local/bin/$exec +done export CC=$TARGET-gcc export CXX=$TARGET-g++ diff --git a/src/test/run-make-fulldeps/link-cfg/Makefile b/src/test/run-make-fulldeps/link-cfg/Makefile index 188cba5fe412..2701b4a593cc 100644 --- a/src/test/run-make-fulldeps/link-cfg/Makefile +++ b/src/test/run-make-fulldeps/link-cfg/Makefile @@ -2,7 +2,7 @@ all: $(call DYLIB,return1) $(call DYLIB,return2) $(call NATIVE_STATICLIB,return3) ls $(TMPDIR) - $(RUSTC) --print cfg --target x86_64-unknown-linux-musl | $(CGREP) crt-static + $(BARE_RUSTC) --print cfg --target x86_64-unknown-linux-musl | $(CGREP) crt-static $(RUSTC) no-deps.rs --cfg foo $(call RUN,no-deps) diff --git a/src/test/run-make-fulldeps/linker-output-non-utf8/Makefile b/src/test/run-make-fulldeps/linker-output-non-utf8/Makefile index 3fffd1e7aa2a..b47ce17ec8ba 100644 --- a/src/test/run-make-fulldeps/linker-output-non-utf8/Makefile +++ b/src/test/run-make-fulldeps/linker-output-non-utf8/Makefile @@ -20,4 +20,4 @@ all: $(RUSTC) library.rs mkdir $(bad_dir) mv $(TMPDIR)/liblibrary.a $(bad_dir) - LIBRARY_PATH=$(bad_dir) $(RUSTC) exec.rs 2>&1 | $(CGREP) this_symbol_not_defined + $(RUSTC) -L $(bad_dir) exec.rs 2>&1 | $(CGREP) this_symbol_not_defined diff --git a/src/test/run-make-fulldeps/reproducible-build/Makefile b/src/test/run-make-fulldeps/reproducible-build/Makefile index ca76a5e5d77b..a17ec212cfd5 100644 --- a/src/test/run-make-fulldeps/reproducible-build/Makefile +++ b/src/test/run-make-fulldeps/reproducible-build/Makefile @@ -1,4 +1,8 @@ -include ../tools.mk + +# ignore-musl +# Objects are reproducible but their path is not. + all: \ smoke \ debug \ diff --git a/src/test/run-make/rustc-macro-dep-files/Makefile b/src/test/run-make/rustc-macro-dep-files/Makefile index 0420a389168f..a08a63fb44bf 100644 --- a/src/test/run-make/rustc-macro-dep-files/Makefile +++ b/src/test/run-make/rustc-macro-dep-files/Makefile @@ -2,7 +2,10 @@ # FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC` # instead of hardcoding them everywhere they're needed. +ifeq ($(IS_MUSL_HOST),1) +ADDITIONAL_ARGS := $(RUSTFLAGS) +endif all: - $(BARE_RUSTC) foo.rs --out-dir $(TMPDIR) + $(BARE_RUSTC) $(ADDITIONAL_ARGS) foo.rs --out-dir $(TMPDIR) $(RUSTC) bar.rs --target $(TARGET) --emit dep-info $(CGREP) -v "proc-macro source" < $(TMPDIR)/bar.d diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 3689946c055e..10b8133326bb 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1650,7 +1650,9 @@ impl<'test> TestCx<'test> { (true, None) } else if self.config.target.contains("cloudabi") || self.config.target.contains("emscripten") - || (self.config.target.contains("musl") && !aux_props.force_host) + || (self.config.target.contains("musl") + && !aux_props.force_host + && !self.config.host.contains("musl")) || self.config.target.contains("wasm32") || self.config.target.contains("nvptx") { @@ -1932,6 +1934,11 @@ impl<'test> TestCx<'test> { } } + // Use dynamic musl for tests because static doesn't allow creating dylibs + if self.config.host.contains("musl") { + rustc.arg("-Ctarget-feature=-crt-static"); + } + rustc.args(&self.props.compile_flags); rustc @@ -2725,6 +2732,12 @@ impl<'test> TestCx<'test> { // compiler flags set in the test cases: cmd.env_remove("RUSTFLAGS"); + // Use dynamic musl for tests because static doesn't allow creating dylibs + if self.config.host.contains("musl") { + cmd.env("RUSTFLAGS", "-Ctarget-feature=-crt-static") + .env("IS_MUSL_HOST", "1"); + } + if self.config.target.contains("msvc") && self.config.cc != "" { // We need to pass a path to `lib.exe`, so assume that `cc` is `cl.exe` // and that `lib.exe` lives next to it. From 0caa251da2d7272fdecb32aae6e0a9e1c3ec0756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Fri, 10 May 2019 16:12:32 +0200 Subject: [PATCH 065/239] Conditionally provide cc in musl-toolchain.sh --- src/ci/docker/dist-x86_64-musl/Dockerfile | 2 +- src/ci/docker/scripts/musl-toolchain.sh | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/ci/docker/dist-x86_64-musl/Dockerfile b/src/ci/docker/dist-x86_64-musl/Dockerfile index bc3a3bd6fbc6..385eefde846c 100644 --- a/src/ci/docker/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/dist-x86_64-musl/Dockerfile @@ -23,7 +23,7 @@ COPY scripts/musl-toolchain.sh /build/ # We need to mitigate rust-lang/rust#34978 when compiling musl itself as well RUN CFLAGS="-Wa,-mrelax-relocations=no -Wa,--compress-debug-sections=none -Wl,--compress-debug-sections=none" \ CXXFLAGS="-Wa,-mrelax-relocations=no -Wa,--compress-debug-sections=none -Wl,--compress-debug-sections=none" \ - bash musl-toolchain.sh x86_64 && rm -rf build + REPLACE_CC=1 bash musl-toolchain.sh x86_64 && rm -rf build COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index e132615738ba..d5988a25671a 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -46,12 +46,14 @@ ln -s $OUTPUT/$TARGET/lib/libc.so /lib/ld-musl-$ARCH.so.1 echo $OUTPUT/$TARGET/lib >> /etc/ld-musl-$ARCH.path # Now when musl bootstraps itself create proper toolchain symlinks to make build and tests easier -for exec in cc gcc; do - ln -s $TARGET-gcc /usr/local/bin/$exec -done -for exec in cpp c++ g++; do - ln -s $TARGET-g++ /usr/local/bin/$exec -done +if [ "$REPLACE_CC" = "1" ]; then + for exec in cc gcc; do + ln -s $TARGET-gcc /usr/local/bin/$exec + done + for exec in cpp c++ g++; do + ln -s $TARGET-g++ /usr/local/bin/$exec + done +fi export CC=$TARGET-gcc export CXX=$TARGET-g++ From 8fbe1ed6c79b630b366848cf979e724c27ba6510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Fri, 10 May 2019 16:47:25 +0200 Subject: [PATCH 066/239] Update mailmap for mati865 --- .mailmap | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.mailmap b/.mailmap index 679e9d79847c..63a49cd41328 100644 --- a/.mailmap +++ b/.mailmap @@ -155,6 +155,8 @@ Mark Sinclair =Mark Sinclair <=125axel125@gmail.com> Markus Westerlind Markus Martin Hafskjold Thoresen Matej Lach Matej Ľach +Mateusz Mikuła +Mateusz Mikuła Matt Brubeck Matthew Auld Matthew McPherrin From 5b6bda33543a8db601690350c585515a5273975d Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Tue, 7 May 2019 17:58:58 -0500 Subject: [PATCH 067/239] turn a couple of fixmes into span_bugs --- src/libsyntax/ext/tt/transcribe.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 0cefcf1ce034..e3586c1854c1 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -170,10 +170,9 @@ pub fn transcribe( } LockstepIterSize::Contradiction(ref msg) => { - // FIXME: this should be impossible. I (mark-i-m) believe it would - // represent a bug in the macro_parser. - // FIXME #2887 blame macro invoker instead - cx.span_fatal(seq.span(), &msg[..]); + // This should never happen because the macro parser should generate + // properly-sized matches for all meta-vars. + cx.span_bug(seq.span(), &msg[..]); } LockstepIterSize::Constraint(len, _) => { @@ -188,14 +187,13 @@ pub fn transcribe( // Is the repetition empty? if len == 0 { if seq.op == quoted::KleeneOp::OneOrMore { - // FIXME: this should be impossible because we check for this in - // macro_parser.rs - // FIXME #2887 blame invoker - cx.span_fatal(sp.entire(), "this must repeat at least once"); + // This should be impossible because the macro parser would not + // match the given macro arm. + cx.span_bug(sp.entire(), "this must repeat at least once"); } } else { // 0 is the initial counter (we have done 0 repretitions so far). `len` - // is the total number of reptitions we should generate. + // is the total number of reptitions we should generate. repeats.push((0, len)); // The first time we encounter the sequence we push it to the stack. It From 1ea7c5fb2039933c67af8ba8629694733c0cd36e Mon Sep 17 00:00:00 2001 From: topecongiro Date: Sat, 11 May 2019 00:22:18 +0900 Subject: [PATCH 068/239] Update ui test --- src/test/ui/feature-gate/await-macro.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/feature-gate/await-macro.stderr b/src/test/ui/feature-gate/await-macro.stderr index b6833655f6d8..699a7a8886e8 100644 --- a/src/test/ui/feature-gate/await-macro.stderr +++ b/src/test/ui/feature-gate/await-macro.stderr @@ -2,7 +2,7 @@ error[E0658]: `await!()` macro syntax is unstable, and will soon be remove --> $DIR/await-macro.rs:9:5 | LL | await!(bar()); - | ^^^^^ + | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/50547 = help: add #![feature(await_macro)] to the crate attributes to enable From 0db087e6840cc865bcf8be09ff940f2ac13341ac Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 4 May 2019 01:15:26 +0100 Subject: [PATCH 069/239] Add uninhabitedness tests w/ `#[non_exhaustive]`. This commit adds tests checking that uninhabited non-exhaustive types are considered inhabited when used in another crate. --- .../auxiliary/uninhabited.rs | 25 +++++++ .../ui/rfc-2008-non-exhaustive/uninhabited.rs | 59 +++++++++++++++ .../uninhabited_same_crate.rs | 71 +++++++++++++++++++ .../uninhabited_same_crate.stderr | 38 ++++++++++ 4 files changed, 193 insertions(+) create mode 100644 src/test/ui/rfc-2008-non-exhaustive/auxiliary/uninhabited.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr diff --git a/src/test/ui/rfc-2008-non-exhaustive/auxiliary/uninhabited.rs b/src/test/ui/rfc-2008-non-exhaustive/auxiliary/uninhabited.rs new file mode 100644 index 000000000000..a4b936e376d8 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/auxiliary/uninhabited.rs @@ -0,0 +1,25 @@ +#![crate_type = "rlib"] +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub enum PartiallyInhabitedVariants { + Tuple(u8), + #[non_exhaustive] Struct { x: ! } +} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs new file mode 100644 index 000000000000..97061310d19e --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs @@ -0,0 +1,59 @@ +// aux-build:uninhabited.rs +// compile-pass +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] + +extern crate uninhabited; + +use uninhabited::{ + PartiallyInhabitedVariants, + UninhabitedEnum, + UninhabitedStruct, + UninhabitedTupleStruct, + UninhabitedVariants, +}; + +fn uninhabited_enum() -> Option { + None +} + +fn uninhabited_variant() -> Option { + None +} + +fn partially_inhabited_variant() -> PartiallyInhabitedVariants { + PartiallyInhabitedVariants::Tuple(3) +} + +fn uninhabited_struct() -> Option { + None +} + +fn uninhabited_tuple_struct() -> Option { + None +} + +// This test checks that non-exhaustive types that would normally be considered uninhabited within +// the defining crate are not considered uninhabited from extern crates. + +fn main() { + match uninhabited_enum() { + Some(_x) => (), // This line would normally error. + None => (), + } + + match uninhabited_variant() { + Some(_x) => (), // This line would normally error. + None => (), + } + + // This line would normally error. + while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() { + } + + while let Some(_x) = uninhabited_struct() { // This line would normally error. + } + + while let Some(_x) = uninhabited_tuple_struct() { // This line would normally error. + } +} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs new file mode 100644 index 000000000000..302a35cab5f9 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs @@ -0,0 +1,71 @@ +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub enum PartiallyInhabitedVariants { + Tuple(u8), + #[non_exhaustive] Struct { x: ! } +} + +fn uninhabited_enum() -> Option { + None +} + +fn uninhabited_variant() -> Option { + None +} + +fn partially_inhabited_variant() -> PartiallyInhabitedVariants { + PartiallyInhabitedVariants::Tuple(3) +} + +fn uninhabited_struct() -> Option { + None +} + +fn uninhabited_tuple_struct() -> Option { + None +} + +// This test checks that non-exhaustive types that would normally be considered uninhabited within +// the defining crate are still considered uninhabited. + +fn main() { + match uninhabited_enum() { + Some(_x) => (), //~ ERROR unreachable pattern + None => (), + } + + match uninhabited_variant() { + Some(_x) => (), //~ ERROR unreachable pattern + None => (), + } + + while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { + //~^ ERROR unreachable pattern + } + + while let Some(_x) = uninhabited_struct() { //~ ERROR unreachable pattern + } + + while let Some(_x) = uninhabited_tuple_struct() { //~ ERROR unreachable pattern + } +} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr new file mode 100644 index 000000000000..942f004c3cfd --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr @@ -0,0 +1,38 @@ +error: unreachable pattern + --> $DIR/uninhabited_same_crate.rs:53:9 + | +LL | Some(_x) => (), + | ^^^^^^^^ + | +note: lint level defined here + --> $DIR/uninhabited_same_crate.rs:1:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_same_crate.rs:58:9 + | +LL | Some(_x) => (), + | ^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_same_crate.rs:62:15 + | +LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_same_crate.rs:66:15 + | +LL | while let Some(_x) = uninhabited_struct() { + | ^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_same_crate.rs:69:15 + | +LL | while let Some(_x) = uninhabited_tuple_struct() { + | ^^^^^^^^ + +error: aborting due to 5 previous errors + From 0d034a2e4dd9418fa41aba4ebdd1ebc31a08c9e9 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 4 May 2019 01:17:26 +0100 Subject: [PATCH 070/239] Fix inhabitedness of non-exhaustive variants. This commit ensures that non-exhaustive variants are considered inhabited when used in extern crates. --- src/librustc/ty/inhabitedness/mod.rs | 11 +++++++--- src/librustc_mir/hair/pattern/_match.rs | 27 ++++++++++++++++++++---- src/test/ui/pattern/const-pat-ice.stderr | 2 +- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs index 197d3325f51c..2fc07fb20bf1 100644 --- a/src/librustc/ty/inhabitedness/mod.rs +++ b/src/librustc/ty/inhabitedness/mod.rs @@ -134,9 +134,14 @@ impl<'a, 'gcx, 'tcx> VariantDef { AdtKind::Enum => true, AdtKind::Struct => false, }; - DefIdForest::union(tcx, self.fields.iter().map(|f| { - f.uninhabited_from(tcx, substs, is_enum) - })) + // Non-exhaustive variants from other crates are always considered inhabited. + if self.is_field_list_non_exhaustive() && !self.def_id.is_local() { + DefIdForest::empty() + } else { + DefIdForest::union(tcx, self.fields.iter().map(|f| { + f.uninhabited_from(tcx, substs, is_enum) + })) + } } } diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index edd36abc0b8a..fd4416fc2b76 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -388,6 +388,18 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { } } + fn is_non_exhaustive_variant<'p>(&self, pattern: &'p Pattern<'tcx>) -> bool + where 'a: 'p + { + match *pattern.kind { + PatternKind::Variant { adt_def, variant_index, .. } => { + let ref variant = adt_def.variants[variant_index]; + variant.is_field_list_non_exhaustive() + } + _ => false, + } + } + fn is_non_exhaustive_enum(&self, ty: Ty<'tcx>) -> bool { match ty.sty { ty::Adt(adt_def, ..) => adt_def.is_variant_list_non_exhaustive(), @@ -1097,10 +1109,17 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, debug!("is_useful_expand_first_col: pcx={:#?}, expanding {:#?}", pcx, v[0]); if let Some(constructors) = pat_constructors(cx, v[0], pcx) { - debug!("is_useful - expanding constructors: {:#?}", constructors); - split_grouped_constructors(cx.tcx, constructors, matrix, pcx.ty).into_iter().map(|c| - is_useful_specialized(cx, matrix, v, c, pcx.ty, witness) - ).find(|result| result.is_useful()).unwrap_or(NotUseful) + let is_declared_nonexhaustive = cx.is_non_exhaustive_variant(v[0]) && !cx.is_local(pcx.ty); + debug!("is_useful - expanding constructors: {:#?}, is_declared_nonexhaustive: {:?}", + constructors, is_declared_nonexhaustive); + + if is_declared_nonexhaustive { + Useful + } else { + split_grouped_constructors(cx.tcx, constructors, matrix, pcx.ty).into_iter().map(|c| + is_useful_specialized(cx, matrix, v, c, pcx.ty, witness) + ).find(|result| result.is_useful()).unwrap_or(NotUseful) + } } else { debug!("is_useful - expanding wildcard"); diff --git a/src/test/ui/pattern/const-pat-ice.stderr b/src/test/ui/pattern/const-pat-ice.stderr index 261e95229a76..260c2e04d74f 100644 --- a/src/test/ui/pattern/const-pat-ice.stderr +++ b/src/test/ui/pattern/const-pat-ice.stderr @@ -1,4 +1,4 @@ -thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir/hair/pattern/_match.rs:1071:5 +thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir/hair/pattern/_match.rs:1083:5 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. error: internal compiler error: unexpected panic From 8838b9130e2f6551077f432dddd5a8077ae4d2e1 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 4 May 2019 11:03:06 +0100 Subject: [PATCH 071/239] Fix uninhabitedness of non-exhaustive enums. This commit ensures that non-exhaustive enums are considered inhabited when used in extern crates. --- src/librustc/ty/inhabitedness/mod.rs | 11 ++- src/librustc_mir/hair/pattern/check_match.rs | 6 +- .../ui/rfc-2008-non-exhaustive/uninhabited.rs | 55 +++++--------- .../uninhabited.stderr | 47 ++++++++++++ .../uninhabited_match.rs | 19 +++++ .../uninhabited_match.stderr | 11 +++ .../uninhabited_match_same_crate.rs | 18 +++++ ...nhabited_match_with_exhaustive_patterns.rs | 22 ++++++ ...ited_match_with_exhaustive_patterns.stderr | 11 +++ ...tch_with_exhaustive_patterns_same_crate.rs | 21 ++++++ .../uninhabited_patterns.rs | 59 +++++++++++++++ .../uninhabited_patterns_same_crate.rs | 71 +++++++++++++++++++ .../uninhabited_patterns_same_crate.stderr | 38 ++++++++++ .../uninhabited_same_crate.rs | 57 +++++---------- .../uninhabited_same_crate.stderr | 65 +++++++++-------- 15 files changed, 400 insertions(+), 111 deletions(-) create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs index 2fc07fb20bf1..be1d973c2cdd 100644 --- a/src/librustc/ty/inhabitedness/mod.rs +++ b/src/librustc/ty/inhabitedness/mod.rs @@ -113,9 +113,14 @@ impl<'a, 'gcx, 'tcx> AdtDef { tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: SubstsRef<'tcx>) -> DefIdForest { - DefIdForest::intersection(tcx, self.variants.iter().map(|v| { - v.uninhabited_from(tcx, substs, self.adt_kind()) - })) + // Non-exhaustive ADTs from other crates are always considered inhabited. + if self.is_variant_list_non_exhaustive() && !self.did.is_local() { + DefIdForest::empty() + } else { + DefIdForest::intersection(tcx, self.variants.iter().map(|v| { + v.uninhabited_from(tcx, substs, self.adt_kind()) + })) + } } } diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 1a7266859ad9..8c7155e1df35 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -208,7 +208,11 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { .map(|variant| variant.ident) .collect(); } - def.variants.is_empty() + + let is_non_exhaustive_and_non_local = + def.is_variant_list_non_exhaustive() && !def.did.is_local(); + + !(is_non_exhaustive_and_non_local) && def.variants.is_empty() }, _ => false } diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs index 97061310d19e..80b9dc4c1c33 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs @@ -1,59 +1,38 @@ // aux-build:uninhabited.rs -// compile-pass -#![deny(unreachable_patterns)] -#![feature(exhaustive_patterns)] +#![feature(never_type)] extern crate uninhabited; use uninhabited::{ - PartiallyInhabitedVariants, UninhabitedEnum, UninhabitedStruct, UninhabitedTupleStruct, UninhabitedVariants, }; -fn uninhabited_enum() -> Option { - None +// This test checks that uninhabited non-exhaustive types cannot coerce to any type, as the never +// type can. + +struct A; + +fn can_coerce_never_type_to_anything(x: !) -> A { + x } -fn uninhabited_variant() -> Option { - None +fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { + x //~ ERROR mismatched types } -fn partially_inhabited_variant() -> PartiallyInhabitedVariants { - PartiallyInhabitedVariants::Tuple(3) +fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + x //~ ERROR mismatched types } -fn uninhabited_struct() -> Option { - None +fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { + x //~ ERROR mismatched types } -fn uninhabited_tuple_struct() -> Option { - None +fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { + x //~ ERROR mismatched types } -// This test checks that non-exhaustive types that would normally be considered uninhabited within -// the defining crate are not considered uninhabited from extern crates. - -fn main() { - match uninhabited_enum() { - Some(_x) => (), // This line would normally error. - None => (), - } - - match uninhabited_variant() { - Some(_x) => (), // This line would normally error. - None => (), - } - - // This line would normally error. - while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() { - } - - while let Some(_x) = uninhabited_struct() { // This line would normally error. - } - - while let Some(_x) = uninhabited_tuple_struct() { // This line would normally error. - } -} +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr new file mode 100644 index 000000000000..490a6c101179 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr @@ -0,0 +1,47 @@ +error[E0308]: mismatched types + --> $DIR/uninhabited.rs:23:5 + | +LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found enum `uninhabited::UninhabitedEnum` + | + = note: expected type `A` + found type `uninhabited::UninhabitedEnum` + +error[E0308]: mismatched types + --> $DIR/uninhabited.rs:27:5 + | +LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found struct `uninhabited::UninhabitedTupleStruct` + | + = note: expected type `A` + found type `uninhabited::UninhabitedTupleStruct` + +error[E0308]: mismatched types + --> $DIR/uninhabited.rs:31:5 + | +LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found struct `uninhabited::UninhabitedStruct` + | + = note: expected type `A` + found type `uninhabited::UninhabitedStruct` + +error[E0308]: mismatched types + --> $DIR/uninhabited.rs:35:5 + | +LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found enum `uninhabited::UninhabitedVariants` + | + = note: expected type `A` + found type `uninhabited::UninhabitedVariants` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs new file mode 100644 index 000000000000..0166b2e46cbf --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs @@ -0,0 +1,19 @@ +// aux-build:uninhabited.rs +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + UninhabitedEnum, +}; + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate +// will not compile. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr new file mode 100644 index 000000000000..3000e1b09306 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr @@ -0,0 +1,11 @@ +error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty + --> $DIR/uninhabited_match.rs:16:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs new file mode 100644 index 000000000000..d8b1c3810f33 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs @@ -0,0 +1,18 @@ +// compile-pass +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate +// will compile. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs new file mode 100644 index 000000000000..d82010158ccc --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs @@ -0,0 +1,22 @@ +// aux-build:uninhabited.rs +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + UninhabitedEnum, +}; + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate +// will not compile. In particular, this enables the `exhaustive_patterns` feature as this can +// change the branch used in the compiler to determine this. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.stderr new file mode 100644 index 000000000000..73d9e689b55f --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.stderr @@ -0,0 +1,11 @@ +error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty + --> $DIR/uninhabited_match_with_exhaustive_patterns.rs:19:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs new file mode 100644 index 000000000000..da814a70a75c --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs @@ -0,0 +1,21 @@ +// compile-pass +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate +// will compile. In particular, this enables the `exhaustive_patterns` feature as this can +// change the branch used in the compiler to determine this. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs new file mode 100644 index 000000000000..97061310d19e --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs @@ -0,0 +1,59 @@ +// aux-build:uninhabited.rs +// compile-pass +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] + +extern crate uninhabited; + +use uninhabited::{ + PartiallyInhabitedVariants, + UninhabitedEnum, + UninhabitedStruct, + UninhabitedTupleStruct, + UninhabitedVariants, +}; + +fn uninhabited_enum() -> Option { + None +} + +fn uninhabited_variant() -> Option { + None +} + +fn partially_inhabited_variant() -> PartiallyInhabitedVariants { + PartiallyInhabitedVariants::Tuple(3) +} + +fn uninhabited_struct() -> Option { + None +} + +fn uninhabited_tuple_struct() -> Option { + None +} + +// This test checks that non-exhaustive types that would normally be considered uninhabited within +// the defining crate are not considered uninhabited from extern crates. + +fn main() { + match uninhabited_enum() { + Some(_x) => (), // This line would normally error. + None => (), + } + + match uninhabited_variant() { + Some(_x) => (), // This line would normally error. + None => (), + } + + // This line would normally error. + while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() { + } + + while let Some(_x) = uninhabited_struct() { // This line would normally error. + } + + while let Some(_x) = uninhabited_tuple_struct() { // This line would normally error. + } +} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs new file mode 100644 index 000000000000..302a35cab5f9 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs @@ -0,0 +1,71 @@ +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub enum PartiallyInhabitedVariants { + Tuple(u8), + #[non_exhaustive] Struct { x: ! } +} + +fn uninhabited_enum() -> Option { + None +} + +fn uninhabited_variant() -> Option { + None +} + +fn partially_inhabited_variant() -> PartiallyInhabitedVariants { + PartiallyInhabitedVariants::Tuple(3) +} + +fn uninhabited_struct() -> Option { + None +} + +fn uninhabited_tuple_struct() -> Option { + None +} + +// This test checks that non-exhaustive types that would normally be considered uninhabited within +// the defining crate are still considered uninhabited. + +fn main() { + match uninhabited_enum() { + Some(_x) => (), //~ ERROR unreachable pattern + None => (), + } + + match uninhabited_variant() { + Some(_x) => (), //~ ERROR unreachable pattern + None => (), + } + + while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { + //~^ ERROR unreachable pattern + } + + while let Some(_x) = uninhabited_struct() { //~ ERROR unreachable pattern + } + + while let Some(_x) = uninhabited_tuple_struct() { //~ ERROR unreachable pattern + } +} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr new file mode 100644 index 000000000000..8e995632b2ff --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr @@ -0,0 +1,38 @@ +error: unreachable pattern + --> $DIR/uninhabited_patterns_same_crate.rs:53:9 + | +LL | Some(_x) => (), + | ^^^^^^^^ + | +note: lint level defined here + --> $DIR/uninhabited_patterns_same_crate.rs:1:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_patterns_same_crate.rs:58:9 + | +LL | Some(_x) => (), + | ^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_patterns_same_crate.rs:62:15 + | +LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_patterns_same_crate.rs:66:15 + | +LL | while let Some(_x) = uninhabited_struct() { + | ^^^^^^^^ + +error: unreachable pattern + --> $DIR/uninhabited_patterns_same_crate.rs:69:15 + | +LL | while let Some(_x) = uninhabited_tuple_struct() { + | ^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs index 302a35cab5f9..803a542f8aa4 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs @@ -1,5 +1,3 @@ -#![deny(unreachable_patterns)] -#![feature(exhaustive_patterns)] #![feature(never_type)] #![feature(non_exhaustive)] @@ -20,52 +18,29 @@ pub enum UninhabitedVariants { #[non_exhaustive] Struct { x: ! } } -pub enum PartiallyInhabitedVariants { - Tuple(u8), - #[non_exhaustive] Struct { x: ! } +struct A; + +// This test checks that uninhabited non-exhaustive types defined in the same crate cannot coerce +// to any type, as the never type can. + +fn can_coerce_never_type_to_anything(x: !) -> A { + x } -fn uninhabited_enum() -> Option { - None +fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { + x //~ ERROR mismatched types } -fn uninhabited_variant() -> Option { - None +fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + x //~ ERROR mismatched types } -fn partially_inhabited_variant() -> PartiallyInhabitedVariants { - PartiallyInhabitedVariants::Tuple(3) +fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { + x //~ ERROR mismatched types } -fn uninhabited_struct() -> Option { - None +fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { + x //~ ERROR mismatched types } -fn uninhabited_tuple_struct() -> Option { - None -} - -// This test checks that non-exhaustive types that would normally be considered uninhabited within -// the defining crate are still considered uninhabited. - -fn main() { - match uninhabited_enum() { - Some(_x) => (), //~ ERROR unreachable pattern - None => (), - } - - match uninhabited_variant() { - Some(_x) => (), //~ ERROR unreachable pattern - None => (), - } - - while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { - //~^ ERROR unreachable pattern - } - - while let Some(_x) = uninhabited_struct() { //~ ERROR unreachable pattern - } - - while let Some(_x) = uninhabited_tuple_struct() { //~ ERROR unreachable pattern - } -} +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr index 942f004c3cfd..ea79e7105d54 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr @@ -1,38 +1,47 @@ -error: unreachable pattern - --> $DIR/uninhabited_same_crate.rs:53:9 +error[E0308]: mismatched types + --> $DIR/uninhabited_same_crate.rs:31:5 | -LL | Some(_x) => (), - | ^^^^^^^^ +LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found enum `UninhabitedEnum` | -note: lint level defined here - --> $DIR/uninhabited_same_crate.rs:1:9 - | -LL | #![deny(unreachable_patterns)] - | ^^^^^^^^^^^^^^^^^^^^ + = note: expected type `A` + found type `UninhabitedEnum` -error: unreachable pattern - --> $DIR/uninhabited_same_crate.rs:58:9 +error[E0308]: mismatched types + --> $DIR/uninhabited_same_crate.rs:35:5 | -LL | Some(_x) => (), - | ^^^^^^^^ - -error: unreachable pattern - --> $DIR/uninhabited_same_crate.rs:62:15 +LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found struct `UninhabitedTupleStruct` | -LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected type `A` + found type `UninhabitedTupleStruct` -error: unreachable pattern - --> $DIR/uninhabited_same_crate.rs:66:15 +error[E0308]: mismatched types + --> $DIR/uninhabited_same_crate.rs:39:5 | -LL | while let Some(_x) = uninhabited_struct() { - | ^^^^^^^^ - -error: unreachable pattern - --> $DIR/uninhabited_same_crate.rs:69:15 +LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found struct `UninhabitedStruct` | -LL | while let Some(_x) = uninhabited_tuple_struct() { - | ^^^^^^^^ + = note: expected type `A` + found type `UninhabitedStruct` -error: aborting due to 5 previous errors +error[E0308]: mismatched types + --> $DIR/uninhabited_same_crate.rs:43:5 + | +LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { + | - expected `A` because of return type +LL | x + | ^ expected struct `A`, found enum `UninhabitedVariants` + | + = note: expected type `A` + found type `UninhabitedVariants` +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. From 214f977fee19aeeb4f5ab4df8e0b5d37e611cb48 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 4 May 2019 11:08:57 +0100 Subject: [PATCH 072/239] Move uninhabited tests into subdirectory. This commit just tries to tidy up a little. --- .../{ => uninhabited}/auxiliary/uninhabited.rs | 0 .../{uninhabited.rs => uninhabited/coercions.rs} | 0 .../coercions.stderr} | 8 ++++---- .../coercions_same_crate.rs} | 0 .../coercions_same_crate.stderr} | 8 ++++---- .../{uninhabited_match.rs => uninhabited/match.rs} | 0 .../match.stderr} | 2 +- .../match_same_crate.rs} | 0 .../match_with_exhaustive_patterns.rs} | 0 .../match_with_exhaustive_patterns.stderr} | 2 +- .../match_with_exhaustive_patterns_same_crate.rs} | 0 .../patterns.rs} | 0 .../patterns_same_crate.rs} | 0 .../patterns_same_crate.stderr} | 12 ++++++------ 14 files changed, 16 insertions(+), 16 deletions(-) rename src/test/ui/rfc-2008-non-exhaustive/{ => uninhabited}/auxiliary/uninhabited.rs (100%) rename src/test/ui/rfc-2008-non-exhaustive/{uninhabited.rs => uninhabited/coercions.rs} (100%) rename src/test/ui/rfc-2008-non-exhaustive/{uninhabited.stderr => uninhabited/coercions.stderr} (93%) rename src/test/ui/rfc-2008-non-exhaustive/{uninhabited_same_crate.rs => uninhabited/coercions_same_crate.rs} (100%) rename src/test/ui/rfc-2008-non-exhaustive/{uninhabited_same_crate.stderr => uninhabited/coercions_same_crate.stderr} (90%) rename src/test/ui/rfc-2008-non-exhaustive/{uninhabited_match.rs => uninhabited/match.rs} (100%) rename src/test/ui/rfc-2008-non-exhaustive/{uninhabited_match.stderr => uninhabited/match.stderr} (90%) rename src/test/ui/rfc-2008-non-exhaustive/{uninhabited_match_same_crate.rs => uninhabited/match_same_crate.rs} (100%) rename src/test/ui/rfc-2008-non-exhaustive/{uninhabited_match_with_exhaustive_patterns.rs => uninhabited/match_with_exhaustive_patterns.rs} (100%) rename src/test/ui/rfc-2008-non-exhaustive/{uninhabited_match_with_exhaustive_patterns.stderr => uninhabited/match_with_exhaustive_patterns.stderr} (84%) rename src/test/ui/rfc-2008-non-exhaustive/{uninhabited_match_with_exhaustive_patterns_same_crate.rs => uninhabited/match_with_exhaustive_patterns_same_crate.rs} (100%) rename src/test/ui/rfc-2008-non-exhaustive/{uninhabited_patterns.rs => uninhabited/patterns.rs} (100%) rename src/test/ui/rfc-2008-non-exhaustive/{uninhabited_patterns_same_crate.rs => uninhabited/patterns_same_crate.rs} (100%) rename src/test/ui/rfc-2008-non-exhaustive/{uninhabited_patterns_same_crate.stderr => uninhabited/patterns_same_crate.stderr} (70%) diff --git a/src/test/ui/rfc-2008-non-exhaustive/auxiliary/uninhabited.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs similarity index 100% rename from src/test/ui/rfc-2008-non-exhaustive/auxiliary/uninhabited.rs rename to src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs similarity index 100% rename from src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs rename to src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.stderr similarity index 93% rename from src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr rename to src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.stderr index 490a6c101179..d05ee1d39ec3 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/uninhabited.rs:23:5 + --> $DIR/coercions.rs:23:5 | LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { | - expected `A` because of return type @@ -10,7 +10,7 @@ LL | x found type `uninhabited::UninhabitedEnum` error[E0308]: mismatched types - --> $DIR/uninhabited.rs:27:5 + --> $DIR/coercions.rs:27:5 | LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { | - expected `A` because of return type @@ -21,7 +21,7 @@ LL | x found type `uninhabited::UninhabitedTupleStruct` error[E0308]: mismatched types - --> $DIR/uninhabited.rs:31:5 + --> $DIR/coercions.rs:31:5 | LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { | - expected `A` because of return type @@ -32,7 +32,7 @@ LL | x found type `uninhabited::UninhabitedStruct` error[E0308]: mismatched types - --> $DIR/uninhabited.rs:35:5 + --> $DIR/coercions.rs:35:5 | LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { | - expected `A` because of return type diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs similarity index 100% rename from src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs rename to src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr similarity index 90% rename from src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr rename to src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr index ea79e7105d54..8f6b709bb1f3 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/uninhabited_same_crate.rs:31:5 + --> $DIR/coercions_same_crate.rs:31:5 | LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { | - expected `A` because of return type @@ -10,7 +10,7 @@ LL | x found type `UninhabitedEnum` error[E0308]: mismatched types - --> $DIR/uninhabited_same_crate.rs:35:5 + --> $DIR/coercions_same_crate.rs:35:5 | LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { | - expected `A` because of return type @@ -21,7 +21,7 @@ LL | x found type `UninhabitedTupleStruct` error[E0308]: mismatched types - --> $DIR/uninhabited_same_crate.rs:39:5 + --> $DIR/coercions_same_crate.rs:39:5 | LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { | - expected `A` because of return type @@ -32,7 +32,7 @@ LL | x found type `UninhabitedStruct` error[E0308]: mismatched types - --> $DIR/uninhabited_same_crate.rs:43:5 + --> $DIR/coercions_same_crate.rs:43:5 | LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { | - expected `A` because of return type diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs similarity index 100% rename from src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs rename to src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr similarity index 90% rename from src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr rename to src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr index 3000e1b09306..356c6fba32d5 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty - --> $DIR/uninhabited_match.rs:16:11 + --> $DIR/match.rs:16:11 | LL | match x {} | ^ diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs similarity index 100% rename from src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs rename to src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs similarity index 100% rename from src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs rename to src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr similarity index 84% rename from src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.stderr rename to src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr index 73d9e689b55f..ec2e9d0995b1 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty - --> $DIR/uninhabited_match_with_exhaustive_patterns.rs:19:11 + --> $DIR/match_with_exhaustive_patterns.rs:19:11 | LL | match x {} | ^ diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs similarity index 100% rename from src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs rename to src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs similarity index 100% rename from src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs rename to src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs similarity index 100% rename from src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs rename to src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr similarity index 70% rename from src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr rename to src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr index 8e995632b2ff..72f37d9a60ba 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr @@ -1,35 +1,35 @@ error: unreachable pattern - --> $DIR/uninhabited_patterns_same_crate.rs:53:9 + --> $DIR/patterns_same_crate.rs:53:9 | LL | Some(_x) => (), | ^^^^^^^^ | note: lint level defined here - --> $DIR/uninhabited_patterns_same_crate.rs:1:9 + --> $DIR/patterns_same_crate.rs:1:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/uninhabited_patterns_same_crate.rs:58:9 + --> $DIR/patterns_same_crate.rs:58:9 | LL | Some(_x) => (), | ^^^^^^^^ error: unreachable pattern - --> $DIR/uninhabited_patterns_same_crate.rs:62:15 + --> $DIR/patterns_same_crate.rs:62:15 | LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/uninhabited_patterns_same_crate.rs:66:15 + --> $DIR/patterns_same_crate.rs:66:15 | LL | while let Some(_x) = uninhabited_struct() { | ^^^^^^^^ error: unreachable pattern - --> $DIR/uninhabited_patterns_same_crate.rs:69:15 + --> $DIR/patterns_same_crate.rs:69:15 | LL | while let Some(_x) = uninhabited_tuple_struct() { | ^^^^^^^^ From 1f0fb0391caf232dacabdf73fbbb84f2452b25c1 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 4 May 2019 12:07:04 +0100 Subject: [PATCH 073/239] Add a bunch more tests. --- .../uninhabited/auxiliary/uninhabited.rs | 8 +++ .../uninhabited/indirect_match.rs | 36 +++++++++++ .../uninhabited/indirect_match.stderr | 35 +++++++++++ .../uninhabited/indirect_match_same_crate.rs | 52 ++++++++++++++++ .../indirect_match_same_crate.stderr | 59 +++++++++++++++++++ ...indirect_match_with_exhaustive_patterns.rs | 40 +++++++++++++ ...rect_match_with_exhaustive_patterns.stderr | 35 +++++++++++ ...tch_with_exhaustive_patterns_same_crate.rs | 58 ++++++++++++++++++ .../uninhabited/match.rs | 15 +++++ .../uninhabited/match.stderr | 28 ++++++++- .../uninhabited/match_same_crate.rs | 26 +++++++- .../uninhabited/match_same_crate.stderr | 49 +++++++++++++++ .../match_with_exhaustive_patterns.rs | 15 +++++ .../match_with_exhaustive_patterns.stderr | 28 ++++++++- ...tch_with_exhaustive_patterns_same_crate.rs | 27 +++++++++ 15 files changed, 506 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs create mode 100644 src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs index a4b936e376d8..8cb9a8cf1f61 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs @@ -23,3 +23,11 @@ pub enum PartiallyInhabitedVariants { Tuple(u8), #[non_exhaustive] Struct { x: ! } } + +pub struct IndirectUninhabitedEnum(UninhabitedEnum); + +pub struct IndirectUninhabitedStruct(UninhabitedStruct); + +pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct); + +pub struct IndirectUninhabitedVariants(UninhabitedVariants); diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs new file mode 100644 index 000000000000..98a7fdbc5049 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs @@ -0,0 +1,36 @@ +// aux-build:uninhabited.rs +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + IndirectUninhabitedEnum, + IndirectUninhabitedStruct, + IndirectUninhabitedTupleStruct, + IndirectUninhabitedVariants, +}; + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type through a level of +// indirection from an extern crate will not compile. + +fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything( + x: IndirectUninhabitedVariants, +) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr new file mode 100644 index 000000000000..af82022e1da9 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr @@ -0,0 +1,35 @@ +error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedEnum` of type `uninhabited::IndirectUninhabitedEnum` is not handled + --> $DIR/indirect_match.rs:19:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedStruct` of type `uninhabited::IndirectUninhabitedStruct` is not handled + --> $DIR/indirect_match.rs:23:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedTupleStruct` of type `uninhabited::IndirectUninhabitedTupleStruct` is not handled + --> $DIR/indirect_match.rs:27:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedVariants` of type `uninhabited::IndirectUninhabitedVariants` is not handled + --> $DIR/indirect_match.rs:33:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs new file mode 100644 index 000000000000..3c8d495e12cb --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs @@ -0,0 +1,52 @@ +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub struct IndirectUninhabitedEnum(UninhabitedEnum); + +pub struct IndirectUninhabitedStruct(UninhabitedStruct); + +pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct); + +pub struct IndirectUninhabitedVariants(UninhabitedVariants); + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type through a level of +// indirection from the defining crate will not compile without `#![feature(exhaustive_patterns)]`. + +fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything( + x: IndirectUninhabitedVariants, +) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr new file mode 100644 index 000000000000..27b120792d6d --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr @@ -0,0 +1,59 @@ +error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedEnum` of type `IndirectUninhabitedEnum` is not handled + --> $DIR/indirect_match_same_crate.rs:35:11 + | +LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum); + | ---------------------------------------------------- + | | | + | | variant not covered + | `IndirectUninhabitedEnum` defined here +... +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedStruct` of type `IndirectUninhabitedStruct` is not handled + --> $DIR/indirect_match_same_crate.rs:39:11 + | +LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct); + | -------------------------------------------------------- + | | | + | | variant not covered + | `IndirectUninhabitedStruct` defined here +... +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedTupleStruct` of type `IndirectUninhabitedTupleStruct` is not handled + --> $DIR/indirect_match_same_crate.rs:43:11 + | +LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct); + | ------------------------------------------------------------------ + | | | + | | variant not covered + | `IndirectUninhabitedTupleStruct` defined here +... +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedVariants` of type `IndirectUninhabitedVariants` is not handled + --> $DIR/indirect_match_same_crate.rs:49:11 + | +LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants); + | ------------------------------------------------------------ + | | | + | | variant not covered + | `IndirectUninhabitedVariants` defined here +... +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs new file mode 100644 index 000000000000..be86519ecb15 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs @@ -0,0 +1,40 @@ +// aux-build:uninhabited.rs +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + IndirectUninhabitedEnum, + IndirectUninhabitedStruct, + IndirectUninhabitedTupleStruct, + IndirectUninhabitedVariants, +}; + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type through a level of +// indirection from an extern crate will not compile. In particular, this enables the +// `exhaustive_patterns` feature as this can change the branch used in the compiler to determine +// this. + +fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything( + x: IndirectUninhabitedVariants, +) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr new file mode 100644 index 000000000000..17a8d0100720 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr @@ -0,0 +1,35 @@ +error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedEnum` is non-empty + --> $DIR/indirect_match_with_exhaustive_patterns.rs:23:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedStruct` is non-empty + --> $DIR/indirect_match_with_exhaustive_patterns.rs:27:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedTupleStruct` is non-empty + --> $DIR/indirect_match_with_exhaustive_patterns.rs:31:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedVariants` is non-empty + --> $DIR/indirect_match_with_exhaustive_patterns.rs:37:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs new file mode 100644 index 000000000000..5dbd38e07df0 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs @@ -0,0 +1,58 @@ +// compile-pass +// skip-codegen +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub struct IndirectUninhabitedEnum(UninhabitedEnum); + +pub struct IndirectUninhabitedStruct(UninhabitedStruct); + +pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct); + +pub struct IndirectUninhabitedVariants(UninhabitedVariants); + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate +// will compile. In particular, this enables the `exhaustive_patterns` feature as this can +// change the branch used in the compiler to determine this. +// Codegen is skipped because tests with long names can cause issues on Windows CI, see #60648. + +fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A { + match x {} +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A { + match x {} +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A { + match x {} +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything( + x: IndirectUninhabitedVariants, +) -> A { + match x {} +} + +fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs index 0166b2e46cbf..e54098d4d48b 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs @@ -5,6 +5,9 @@ extern crate uninhabited; use uninhabited::{ UninhabitedEnum, + UninhabitedStruct, + UninhabitedTupleStruct, + UninhabitedVariants, }; struct A; @@ -16,4 +19,16 @@ fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { match x {} //~ ERROR non-exhaustive patterns } +fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr index 356c6fba32d5..de39688f45a4 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr @@ -1,11 +1,35 @@ error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty - --> $DIR/match.rs:16:11 + --> $DIR/match.rs:19:11 | LL | match x {} | ^ | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error: aborting due to previous error +error[E0004]: non-exhaustive patterns: pattern `UninhabitedStruct` of type `uninhabited::UninhabitedStruct` is not handled + --> $DIR/match.rs:23:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: pattern `UninhabitedTupleStruct` of type `uninhabited::UninhabitedTupleStruct` is not handled + --> $DIR/match.rs:27:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: multiple patterns of type `uninhabited::UninhabitedVariants` are not handled + --> $DIR/match.rs:31:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs index d8b1c3810f33..6405dd3bd65b 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs @@ -1,4 +1,3 @@ -// compile-pass #![feature(never_type)] #![feature(non_exhaustive)] @@ -6,6 +5,19 @@ pub enum UninhabitedEnum { } +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + struct A; // This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate @@ -15,4 +27,16 @@ fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { match x {} } +fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr new file mode 100644 index 000000000000..410285a39a94 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr @@ -0,0 +1,49 @@ +error[E0004]: non-exhaustive patterns: pattern `UninhabitedStruct` of type `UninhabitedStruct` is not handled + --> $DIR/match_same_crate.rs:31:11 + | +LL | pub struct UninhabitedStruct { + | - ----------------- variant not covered + | _| + | | +LL | | _priv: !, +LL | | } + | |_- `UninhabitedStruct` defined here +... +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: pattern `UninhabitedTupleStruct` of type `UninhabitedTupleStruct` is not handled + --> $DIR/match_same_crate.rs:35:11 + | +LL | pub struct UninhabitedTupleStruct(!); + | ------------------------------------- + | | | + | | variant not covered + | `UninhabitedTupleStruct` defined here +... +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: multiple patterns of type `UninhabitedVariants` are not handled + --> $DIR/match_same_crate.rs:39:11 + | +LL | / pub enum UninhabitedVariants { +LL | | #[non_exhaustive] Tuple(!), + | | ----- variant not covered +LL | | #[non_exhaustive] Struct { x: ! } + | | ------ variant not covered +LL | | } + | |_- `UninhabitedVariants` defined here +... +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs index d82010158ccc..900dfff652ea 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs @@ -7,6 +7,9 @@ extern crate uninhabited; use uninhabited::{ UninhabitedEnum, + UninhabitedStruct, + UninhabitedTupleStruct, + UninhabitedVariants, }; struct A; @@ -19,4 +22,16 @@ fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { match x {} //~ ERROR non-exhaustive patterns } +fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { + match x {} //~ ERROR non-exhaustive patterns +} + fn main() {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr index ec2e9d0995b1..48a888bc50be 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr @@ -1,11 +1,35 @@ error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty - --> $DIR/match_with_exhaustive_patterns.rs:19:11 + --> $DIR/match_with_exhaustive_patterns.rs:22:11 | LL | match x {} | ^ | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error: aborting due to previous error +error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedStruct` is non-empty + --> $DIR/match_with_exhaustive_patterns.rs:26:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedTupleStruct` is non-empty + --> $DIR/match_with_exhaustive_patterns.rs:30:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedVariants` is non-empty + --> $DIR/match_with_exhaustive_patterns.rs:34:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs index da814a70a75c..74922d4bcb5d 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs @@ -1,4 +1,5 @@ // compile-pass +// skip-codegen #![deny(unreachable_patterns)] #![feature(exhaustive_patterns)] #![feature(never_type)] @@ -8,14 +9,40 @@ pub enum UninhabitedEnum { } +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + struct A; // This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate // will compile. In particular, this enables the `exhaustive_patterns` feature as this can // change the branch used in the compiler to determine this. +// Codegen is skipped because tests with long names can cause issues on Windows CI, see #60648. fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { match x {} } +fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A { + match x {} +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + match x {} +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { + match x {} +} + fn main() {} From 5cccda1770f76b8184ea55e4735ce88f824f7fd8 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 11 Mar 2019 16:43:27 +0100 Subject: [PATCH 074/239] Remove hir::ExprKind::If and replace it with lowering to hir::ExprKind::Match. --- src/librustc/cfg/construct.rs | 41 -- src/librustc/hir/intravisit.rs | 5 - src/librustc/hir/lowering.rs | 122 ++--- src/librustc/hir/mod.rs | 10 +- src/librustc/hir/print.rs | 63 --- src/librustc/ich/impls_syntax.rs | 1 + src/librustc/middle/expr_use_visitor.rs | 8 - src/librustc/middle/liveness.rs | 25 +- src/librustc/middle/mem_categorization.rs | 2 +- src/librustc/middle/region.rs | 11 - src/librustc_errors/diagnostic_builder.rs | 12 + src/librustc_mir/build/expr/as_place.rs | 1 - src/librustc_mir/build/expr/as_rvalue.rs | 1 - src/librustc_mir/build/expr/category.rs | 1 - src/librustc_mir/build/expr/into.rs | 37 -- src/librustc_mir/hair/cx/expr.rs | 7 - src/librustc_mir/hair/mod.rs | 5 - src/librustc_mir/hair/pattern/check_match.rs | 1 + src/librustc_passes/rvalue_promotion.rs | 9 - src/librustc_typeck/check/_match.rs | 517 +++++++++++++------ src/librustc_typeck/check/coercion.rs | 8 +- src/librustc_typeck/check/mod.rs | 229 +------- src/libsyntax_pos/hygiene.rs | 5 + 23 files changed, 461 insertions(+), 660 deletions(-) diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 2592af7d4ad5..2e54165be1f1 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -166,47 +166,6 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { self.add_ast_node(expr.hir_id.local_id, &[blk_exit]) } - hir::ExprKind::If(ref cond, ref then, None) => { - // - // [pred] - // | - // v 1 - // [cond] - // | - // / \ - // / \ - // v 2 * - // [then] | - // | | - // v 3 v 4 - // [..expr..] - // - let cond_exit = self.expr(&cond, pred); // 1 - let then_exit = self.expr(&then, cond_exit); // 2 - self.add_ast_node(expr.hir_id.local_id, &[cond_exit, then_exit]) // 3,4 - } - - hir::ExprKind::If(ref cond, ref then, Some(ref otherwise)) => { - // - // [pred] - // | - // v 1 - // [cond] - // | - // / \ - // / \ - // v 2 v 3 - // [then][otherwise] - // | | - // v 4 v 5 - // [..expr..] - // - let cond_exit = self.expr(&cond, pred); // 1 - let then_exit = self.expr(&then, cond_exit); // 2 - let else_exit = self.expr(&otherwise, cond_exit); // 3 - self.add_ast_node(expr.hir_id.local_id, &[then_exit, else_exit]) // 4, 5 - } - hir::ExprKind::While(ref cond, ref body, _) => { // // [pred] diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 0c73d97394fd..38d6d710868c 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -1032,11 +1032,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { ExprKind::DropTemps(ref subexpression) => { visitor.visit_expr(subexpression); } - ExprKind::If(ref head_expression, ref if_block, ref optional_else) => { - visitor.visit_expr(head_expression); - visitor.visit_expr(if_block); - walk_list!(visitor, visit_expr, optional_else); - } ExprKind::While(ref subexpression, ref block, ref opt_label) => { walk_list!(visitor, visit_label, opt_label); visitor.visit_expr(subexpression); diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 4d5707560b04..7ccfb826e37b 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -62,6 +62,7 @@ use syntax::ext::hygiene::Mark; use syntax::print::pprust; use syntax::ptr::P; use syntax::source_map::{respan, CompilerDesugaringKind, Spanned}; +use syntax::source_map::CompilerDesugaringKind::IfTemporary; use syntax::std_inject; use syntax::symbol::{keywords, Symbol}; use syntax::tokenstream::{TokenStream, TokenTree}; @@ -4115,31 +4116,46 @@ impl<'a> LoweringContext<'a> { } // More complicated than you might expect because the else branch // might be `if let`. - ExprKind::If(ref cond, ref blk, ref else_opt) => { - let else_opt = else_opt.as_ref().map(|els| { - match els.node { + ExprKind::If(ref cond, ref then, ref else_opt) => { + // `true => then`: + let then_pat = self.pat_bool(e.span, true); + let then_blk = self.lower_block(then, false); + let then_expr = self.expr_block(then_blk, ThinVec::new()); + let then_arm = self.arm(hir_vec![then_pat], P(then_expr)); + + // `_ => else_block` where `else_block` is `{}` if there's `None`: + let else_pat = self.pat_wild(e.span); + let else_expr = match else_opt { + None => self.expr_block_empty(e.span), + Some(els) => match els.node { ExprKind::IfLet(..) => { // Wrap the `if let` expr in a block. - let span = els.span; - let els = P(self.lower_expr(els)); - let blk = P(hir::Block { - stmts: hir_vec![], - expr: Some(els), - hir_id: self.next_id(), - rules: hir::DefaultBlock, - span, - targeted_by_break: false, - }); - P(self.expr_block(blk, ThinVec::new())) + let els = self.lower_expr(els); + let blk = self.block_all(els.span, hir_vec![], Some(P(els))); + self.expr_block(P(blk), ThinVec::new()) } - _ => P(self.lower_expr(els)), + _ => self.lower_expr(els), } - }); + }; + let else_arm = self.arm(hir_vec![else_pat], P(else_expr)); - let then_blk = self.lower_block(blk, false); - let then_expr = self.expr_block(then_blk, ThinVec::new()); + // Lower condition: + let span_block = self + .sess + .source_map() + .mark_span_with_reason(IfTemporary, cond.span, None); + let cond = self.lower_expr(cond); + // Wrap in a construct equivalent to `{ let _t = $cond; _t }` to preserve drop + // semantics since `if cond { ... }` don't let temporaries live outside of `cond`. + let cond = self.expr_drop_temps(span_block, P(cond), ThinVec::new()); - hir::ExprKind::If(P(self.lower_expr(cond)), P(then_expr), else_opt) + hir::ExprKind::Match( + P(cond), + vec![then_arm, else_arm].into(), + hir::MatchSource::IfDesugar { + contains_else_clause: else_opt.is_some() + }, + ) } ExprKind::While(ref cond, ref body, opt_label) => self.with_loop_scope(e.id, |this| { hir::ExprKind::While( @@ -4486,16 +4502,16 @@ impl<'a> LoweringContext<'a> { arms.push(self.arm(pats, body_expr)); } - // _ => [|()] + // _ => [|{}] { let wildcard_arm: Option<&Expr> = else_opt.as_ref().map(|p| &**p); let wildcard_pattern = self.pat_wild(e.span); let body = if let Some(else_expr) = wildcard_arm { - P(self.lower_expr(else_expr)) + self.lower_expr(else_expr) } else { - P(self.expr_tuple(e.span, hir_vec![])) + self.expr_block_empty(e.span) }; - arms.push(self.arm(hir_vec![wildcard_pattern], body)); + arms.push(self.arm(hir_vec![wildcard_pattern], P(body))); } let contains_else_clause = else_opt.is_some(); @@ -4658,11 +4674,7 @@ impl<'a> LoweringContext<'a> { ThinVec::new(), )) }; - let match_stmt = hir::Stmt { - hir_id: self.next_id(), - node: hir::StmtKind::Expr(match_expr), - span: head_sp, - }; + let match_stmt = self.stmt(head_sp, hir::StmtKind::Expr(match_expr)); let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat_hid)); @@ -4685,11 +4697,7 @@ impl<'a> LoweringContext<'a> { let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false)); let body_expr = P(self.expr_block(body_block, ThinVec::new())); - let body_stmt = hir::Stmt { - hir_id: self.next_id(), - node: hir::StmtKind::Expr(body_expr), - span: body.span, - }; + let body_stmt = self.stmt(body.span, hir::StmtKind::Expr(body_expr)); let loop_block = P(self.block_all( e.span, @@ -4869,12 +4877,7 @@ impl<'a> LoweringContext<'a> { .into_iter() .map(|item_id| { let item_id = hir::ItemId { id: self.lower_node_id(item_id) }; - - hir::Stmt { - hir_id: self.next_id(), - node: hir::StmtKind::Item(item_id), - span: s.span, - } + self.stmt(s.span, hir::StmtKind::Item(item_id)) }) .collect(); ids.push({ @@ -5174,28 +5177,32 @@ impl<'a> LoweringContext<'a> { } } + fn stmt(&mut self, span: Span, node: hir::StmtKind) -> hir::Stmt { + hir::Stmt { span, node, hir_id: self.next_id() } + } + fn stmt_let_pat( &mut self, - sp: Span, - ex: Option>, + span: Span, + init: Option>, pat: P, source: hir::LocalSource, ) -> hir::Stmt { let local = hir::Local { pat, ty: None, - init: ex, + init, hir_id: self.next_id(), - span: sp, - attrs: ThinVec::new(), + span, source, + attrs: ThinVec::new() }; + self.stmt(span, hir::StmtKind::Local(P(local))) + } - hir::Stmt { - hir_id: self.next_id(), - node: hir::StmtKind::Local(P(local)), - span: sp - } + fn expr_block_empty(&mut self, span: Span) -> hir::Expr { + let blk = self.block_all(span, hir_vec![], None); + self.expr_block(P(blk), ThinVec::new()) } fn block_expr(&mut self, expr: P) -> hir::Block { @@ -5235,6 +5242,13 @@ impl<'a> LoweringContext<'a> { ) } + /// Constructs a `true` or `false` literal pattern. + fn pat_bool(&mut self, span: Span, val: bool) -> P { + let lit = Spanned { span, node: LitKind::Bool(val) }; + let expr = self.expr(span, hir::ExprKind::Lit(lit), ThinVec::new()); + self.pat(span, hir::PatKind::Lit(P(expr))) + } + fn pat_ok(&mut self, span: Span, pat: P) -> P { self.pat_std_enum(span, &["result", "Result", "Ok"], hir_vec![pat]) } @@ -5622,15 +5636,7 @@ impl<'a> LoweringContext<'a> { &["task", "Poll", "Pending"], hir_vec![], ); - let empty_block = P(hir::Block { - stmts: hir_vec![], - expr: None, - hir_id: self.next_id(), - rules: hir::DefaultBlock, - span, - targeted_by_break: false, - }); - let empty_block = P(self.expr_block(empty_block, ThinVec::new())); + let empty_block = P(self.expr_block_empty(span)); self.arm(hir_vec![pending_pat], empty_block) }; diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 01de7917e6e2..9f7fa6c5557e 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1368,7 +1368,6 @@ impl Expr { ExprKind::Lit(_) => ExprPrecedence::Lit, ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast, ExprKind::DropTemps(ref expr, ..) => expr.precedence(), - ExprKind::If(..) => ExprPrecedence::If, ExprKind::While(..) => ExprPrecedence::While, ExprKind::Loop(..) => ExprPrecedence::Loop, ExprKind::Match(..) => ExprPrecedence::Match, @@ -1421,7 +1420,6 @@ impl Expr { ExprKind::MethodCall(..) | ExprKind::Struct(..) | ExprKind::Tup(..) | - ExprKind::If(..) | ExprKind::Match(..) | ExprKind::Closure(..) | ExprKind::Block(..) | @@ -1498,10 +1496,6 @@ pub enum ExprKind { /// This construct only exists to tweak the drop order in HIR lowering. /// An example of that is the desugaring of `for` loops. DropTemps(P), - /// An `if` block, with an optional else block. - /// - /// I.e., `if { } else { }`. - If(P, P, Option>), /// A while loop, with an optional label /// /// I.e., `'label: while expr { }`. @@ -1615,6 +1609,10 @@ pub enum LocalSource { pub enum MatchSource { /// A `match _ { .. }`. Normal, + /// An `if _ { .. }` (optionally with `else { .. }`). + IfDesugar { + contains_else_clause: bool, + }, /// An `if let _ = _ { .. }` (optionally with `else { .. }`). IfLetDesugar { contains_else_clause: bool, diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 54816316f0bf..c42d8f3cb3c3 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1093,65 +1093,6 @@ impl<'a> State<'a> { self.ann.post(self, AnnNode::Block(blk)) } - fn print_else(&mut self, els: Option<&hir::Expr>) -> io::Result<()> { - match els { - Some(_else) => { - match _else.node { - // "another else-if" - hir::ExprKind::If(ref i, ref then, ref e) => { - self.cbox(indent_unit - 1)?; - self.ibox(0)?; - self.s.word(" else if ")?; - self.print_expr_as_cond(&i)?; - self.s.space()?; - self.print_expr(&then)?; - self.print_else(e.as_ref().map(|e| &**e)) - } - // "final else" - hir::ExprKind::Block(ref b, _) => { - self.cbox(indent_unit - 1)?; - self.ibox(0)?; - self.s.word(" else ")?; - self.print_block(&b) - } - // BLEAH, constraints would be great here - _ => { - panic!("print_if saw if with weird alternative"); - } - } - } - _ => Ok(()), - } - } - - pub fn print_if(&mut self, - test: &hir::Expr, - blk: &hir::Expr, - elseopt: Option<&hir::Expr>) - -> io::Result<()> { - self.head("if")?; - self.print_expr_as_cond(test)?; - self.s.space()?; - self.print_expr(blk)?; - self.print_else(elseopt) - } - - pub fn print_if_let(&mut self, - pat: &hir::Pat, - expr: &hir::Expr, - blk: &hir::Block, - elseopt: Option<&hir::Expr>) - -> io::Result<()> { - self.head("if let")?; - self.print_pat(pat)?; - self.s.space()?; - self.word_space("=")?; - self.print_expr_as_cond(expr)?; - self.s.space()?; - self.print_block(blk)?; - self.print_else(elseopt) - } - pub fn print_anon_const(&mut self, constant: &hir::AnonConst) -> io::Result<()> { self.ann.nested(self, Nested::Body(constant.body)) } @@ -1406,9 +1347,6 @@ impl<'a> State<'a> { // Print `}`: self.bclose_maybe_open(expr.span, indent_unit, true)?; } - hir::ExprKind::If(ref test, ref blk, ref elseopt) => { - self.print_if(&test, &blk, elseopt.as_ref().map(|e| &**e))?; - } hir::ExprKind::While(ref test, ref blk, opt_label) => { if let Some(label) = opt_label { self.print_ident(label.ident)?; @@ -2414,7 +2352,6 @@ impl<'a> State<'a> { /// isn't parsed as (if true {...} else {...} | x) | 5 fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool { match e.node { - hir::ExprKind::If(..) | hir::ExprKind::Match(..) | hir::ExprKind::Block(..) | hir::ExprKind::While(..) | diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 90dd5099cbfd..35df43ef25ef 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -395,6 +395,7 @@ impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnFormat { }); impl_stable_hash_for!(enum ::syntax_pos::hygiene::CompilerDesugaringKind { + IfTemporary, Async, Await, QuestionMark, diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 93ba4241c472..d46bba92f3fc 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -424,14 +424,6 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { self.consume_exprs(exprs); } - hir::ExprKind::If(ref cond_expr, ref then_expr, ref opt_else_expr) => { - self.consume_expr(&cond_expr); - self.walk_expr(&then_expr); - if let Some(ref else_expr) = *opt_else_expr { - self.consume_expr(&else_expr); - } - } - hir::ExprKind::Match(ref discr, ref arms, _) => { let discr_cmt = Rc::new(return_if_err!(self.mc.cat_expr(&discr))); let r = self.tcx().lifetimes.re_empty; diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 4b458e474b29..a142b220f31a 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -500,7 +500,6 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) { } // live nodes required for interesting control flow: - hir::ExprKind::If(..) | hir::ExprKind::Match(..) | hir::ExprKind::While(..) | hir::ExprKind::Loop(..) => { @@ -1040,28 +1039,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { }) } - hir::ExprKind::If(ref cond, ref then, ref els) => { - // - // (cond) - // | - // v - // (expr) - // / \ - // | | - // v v - // (then)(els) - // | | - // v v - // ( succ ) - // - let else_ln = self.propagate_through_opt_expr(els.as_ref().map(|e| &**e), succ); - let then_ln = self.propagate_through_expr(&then, succ); - let ln = self.live_node(expr.hir_id, expr.span); - self.init_from_succ(ln, else_ln); - self.merge_from_succ(ln, then_ln, false); - self.propagate_through_expr(&cond, ln) - } - hir::ExprKind::While(ref cond, ref blk, _) => { self.propagate_through_loop(expr, WhileLoop(&cond), &blk, succ) } @@ -1523,7 +1500,7 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) { } // no correctness conditions related to liveness - hir::ExprKind::Call(..) | hir::ExprKind::MethodCall(..) | hir::ExprKind::If(..) | + hir::ExprKind::Call(..) | hir::ExprKind::MethodCall(..) | hir::ExprKind::Match(..) | hir::ExprKind::While(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Index(..) | hir::ExprKind::Field(..) | hir::ExprKind::Array(..) | hir::ExprKind::Tup(..) | hir::ExprKind::Binary(..) | diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 7edd5c5a9de1..85c7f4379033 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -678,7 +678,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { hir::ExprKind::Closure(..) | hir::ExprKind::Ret(..) | hir::ExprKind::Unary(..) | hir::ExprKind::Yield(..) | hir::ExprKind::MethodCall(..) | hir::ExprKind::Cast(..) | hir::ExprKind::DropTemps(..) | - hir::ExprKind::Array(..) | hir::ExprKind::Tup(..) | hir::ExprKind::If(..) | + hir::ExprKind::Array(..) | hir::ExprKind::Tup(..) | hir::ExprKind::Binary(..) | hir::ExprKind::While(..) | hir::ExprKind::Block(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Match(..) | hir::ExprKind::Lit(..) | hir::ExprKind::Break(..) | diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 2b88f273adce..8ef4e9ac8f45 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -884,17 +884,6 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, expr: terminating(r.hir_id.local_id); } - hir::ExprKind::If(ref expr, ref then, Some(ref otherwise)) => { - terminating(expr.hir_id.local_id); - terminating(then.hir_id.local_id); - terminating(otherwise.hir_id.local_id); - } - - hir::ExprKind::If(ref expr, ref then, None) => { - terminating(expr.hir_id.local_id); - terminating(then.hir_id.local_id); - } - hir::ExprKind::Loop(ref body, _, _) => { terminating(body.hir_id.local_id); } diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index f74dcd6070c7..31f697a724a0 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -100,6 +100,18 @@ impl<'a> DiagnosticBuilder<'a> { self.cancel(); } + /// Emit the diagnostic unless `delay` is true, + /// in which case the emission will be delayed as a bug. + /// + /// See `emit` and `delay_as_bug` for details. + pub fn emit_unless(&mut self, delay: bool) { + if delay { + self.delay_as_bug() + } else { + self.emit() + } + } + /// Buffers the diagnostic for later emission, unless handler /// has disabled such buffering. pub fn buffer(mut self, buffered_diagnostics: &mut Vec) { diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 713e3fe0218b..5f444d4ceeb8 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -192,7 +192,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { | ExprKind::Pointer { .. } | ExprKind::Repeat { .. } | ExprKind::Borrow { .. } - | ExprKind::If { .. } | ExprKind::Match { .. } | ExprKind::Loop { .. } | ExprKind::Block { .. } diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index e745ee0f190d..fbc4835a6557 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -345,7 +345,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::Literal { .. } | ExprKind::Block { .. } | ExprKind::Match { .. } - | ExprKind::If { .. } | ExprKind::NeverToAny { .. } | ExprKind::Use { .. } | ExprKind::Loop { .. } diff --git a/src/librustc_mir/build/expr/category.rs b/src/librustc_mir/build/expr/category.rs index 4e24b6853d6e..222ce6d1c968 100644 --- a/src/librustc_mir/build/expr/category.rs +++ b/src/librustc_mir/build/expr/category.rs @@ -45,7 +45,6 @@ impl Category { | ExprKind::ValueTypeAscription { .. } => Some(Category::Place), ExprKind::LogicalOp { .. } - | ExprKind::If { .. } | ExprKind::Match { .. } | ExprKind::NeverToAny { .. } | ExprKind::Use { .. } diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 30ed9cef36f7..15795a64e3b7 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -76,43 +76,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { end_block.unit() } } - ExprKind::If { - condition: cond_expr, - then: then_expr, - otherwise: else_expr, - } => { - let operand = unpack!(block = this.as_local_operand(block, cond_expr)); - - let mut then_block = this.cfg.start_new_block(); - let mut else_block = this.cfg.start_new_block(); - let term = TerminatorKind::if_(this.hir.tcx(), operand, then_block, else_block); - this.cfg.terminate(block, source_info, term); - - unpack!(then_block = this.into(destination, then_block, then_expr)); - else_block = if let Some(else_expr) = else_expr { - unpack!(this.into(destination, else_block, else_expr)) - } else { - // Body of the `if` expression without an `else` clause must return `()`, thus - // we implicitly generate a `else {}` if it is not specified. - this.cfg - .push_assign_unit(else_block, source_info, destination); - else_block - }; - - let join_block = this.cfg.start_new_block(); - this.cfg.terminate( - then_block, - source_info, - TerminatorKind::Goto { target: join_block }, - ); - this.cfg.terminate( - else_block, - source_info, - TerminatorKind::Goto { target: join_block }, - ); - - join_block.unit() - } ExprKind::LogicalOp { op, lhs, rhs } => { // And: // diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 5e646a49e0e4..50140880a368 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -601,13 +601,6 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, arms: arms.iter().map(|a| convert_arm(cx, a)).collect(), } } - hir::ExprKind::If(ref cond, ref then, ref otherwise) => { - ExprKind::If { - condition: cond.to_ref(), - then: then.to_ref(), - otherwise: otherwise.to_ref(), - } - } hir::ExprKind::While(ref cond, ref body, _) => { ExprKind::Loop { condition: Some(cond.to_ref()), diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 2e53bee3f3d7..d4f139e103a6 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -185,11 +185,6 @@ pub enum ExprKind<'tcx> { cast: PointerCast, source: ExprRef<'tcx>, }, - If { - condition: ExprRef<'tcx>, - then: ExprRef<'tcx>, - otherwise: Option>, - }, Loop { condition: Option>, body: ExprRef<'tcx>, diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 1a7266859ad9..b58f8dd49242 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -365,6 +365,7 @@ fn check_arms<'a, 'tcx>( match is_useful(cx, &seen, &v, LeaveOutWitness) { NotUseful => { match source { + hir::MatchSource::IfDesugar { .. } => bug!(), hir::MatchSource::IfLetDesugar { .. } => { cx.tcx.lint_hir( lint::builtin::IRREFUTABLE_LET_PATTERNS, diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 0f651fafcd2a..2d35a0de7953 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -518,15 +518,6 @@ fn check_expr_kind<'a, 'tcx>( NotPromotable } - hir::ExprKind::If(ref lhs, ref rhs, ref option_expr) => { - let _ = v.check_expr(lhs); - let _ = v.check_expr(rhs); - if let Some(ref expr) = option_expr { - let _ = v.check_expr(&expr); - } - NotPromotable - } - // Loops (not very meaningful in constants). hir::ExprKind::While(ref expr, ref box_block, ref _option_label) => { let _ = v.check_expr(expr); diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index e9e202ce3799..e8af2f40b87a 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -2,12 +2,12 @@ use crate::check::{FnCtxt, Expectation, Diverges, Needs}; use crate::check::coercion::CoerceMany; use crate::util::nodemap::FxHashMap; use errors::{Applicability, DiagnosticBuilder}; -use rustc::hir::{self, PatKind, Pat}; +use rustc::hir::{self, PatKind, Pat, ExprKind}; use rustc::hir::def::{Res, DefKind, CtorKind}; use rustc::hir::pat_util::EnumerateAndAdjustIterator; use rustc::infer; use rustc::infer::type_variable::TypeVariableOrigin; -use rustc::traits::ObligationCauseCode; +use rustc::traits::{ObligationCause, ObligationCauseCode}; use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::subst::Kind; use syntax::ast; @@ -15,6 +15,7 @@ use syntax::source_map::Spanned; use syntax::ptr::P; use syntax::util::lev_distance::find_best_match_for_name; use syntax_pos::Span; +use syntax_pos::hygiene::CompilerDesugaringKind; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::cmp; @@ -22,10 +23,9 @@ use std::cmp; use super::report_unexpected_variant_res; impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { - /// `match_discrim_span` argument having a `Span` indicates that this pattern is part of - /// a match expression arm guard, and it points to the match discriminant to add context - /// in type errors. In the folloowing example, `match_discrim_span` corresponds to the - /// `a + b` expression: + /// `discrim_span` argument having a `Span` indicates that this pattern is part of a match + /// expression arm guard, and it points to the match discriminant to add context in type errors. + /// In the following example, `discrim_span` corresponds to the `a + b` expression: /// /// ```text /// error[E0308]: mismatched types @@ -44,7 +44,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pat: &'gcx hir::Pat, mut expected: Ty<'tcx>, mut def_bm: ty::BindingMode, - match_discrim_span: Option, + discrim_span: Option, ) { let tcx = self.tcx; @@ -176,7 +176,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // &'static str <: expected // // that's equivalent to there existing a LUB. - self.demand_suptype(pat.span, expected, pat_ty); + if let Some(mut err) = self.demand_suptype_diag(pat.span, expected, pat_ty) { + err.emit_unless(discrim_span + .filter(|&s| s.is_compiler_desugaring(CompilerDesugaringKind::IfTemporary)) + .is_some()); + } + pat_ty } PatKind::Range(ref begin, ref end, _) => { @@ -224,8 +229,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let common_type = self.resolve_type_vars_if_possible(&lhs_ty); // subtyping doesn't matter here, as the value is some kind of scalar - self.demand_eqtype_pat(pat.span, expected, lhs_ty, match_discrim_span); - self.demand_eqtype_pat(pat.span, expected, rhs_ty, match_discrim_span); + self.demand_eqtype_pat(pat.span, expected, lhs_ty, discrim_span); + self.demand_eqtype_pat(pat.span, expected, rhs_ty, discrim_span); common_type } PatKind::Binding(ba, var_id, _, ref sub) => { @@ -254,13 +259,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is // required. However, we use equality, which is stronger. See (*) for // an explanation. - self.demand_eqtype_pat(pat.span, region_ty, local_ty, match_discrim_span); + self.demand_eqtype_pat(pat.span, region_ty, local_ty, discrim_span); } // otherwise the type of x is the expected type T ty::BindByValue(_) => { // As above, `T <: typeof(x)` is required but we // use equality, see (*) below. - self.demand_eqtype_pat(pat.span, expected, local_ty, match_discrim_span); + self.demand_eqtype_pat(pat.span, expected, local_ty, discrim_span); } } @@ -268,11 +273,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // what the type of the binding `x` ought to be if var_id != pat.hir_id { let vt = self.local_ty(pat.span, var_id).decl_ty; - self.demand_eqtype_pat(pat.span, vt, local_ty, match_discrim_span); + self.demand_eqtype_pat(pat.span, vt, local_ty, discrim_span); } if let Some(ref p) = *sub { - self.check_pat_walk(&p, expected, def_bm, match_discrim_span); + self.check_pat_walk(&p, expected, def_bm, discrim_span); } local_ty @@ -285,14 +290,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ddpos, expected, def_bm, - match_discrim_span, + discrim_span, ) } PatKind::Path(ref qpath) => { self.check_pat_path(pat, qpath, expected) } PatKind::Struct(ref qpath, ref fields, etc) => { - self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, match_discrim_span) + self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, discrim_span) } PatKind::Tuple(ref elements, ddpos) => { let mut expected_len = elements.len(); @@ -318,7 +323,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // further errors being emitted when using the bindings. #50333 let element_tys_iter = (0..max_len).map(|_| tcx.types.err); for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { - self.check_pat_walk(elem, &tcx.types.err, def_bm, match_discrim_span); + self.check_pat_walk(elem, &tcx.types.err, def_bm, discrim_span); } tcx.mk_tup(element_tys_iter) } else { @@ -327,7 +332,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { elem, &element_tys[i].expect_ty(), def_bm, - match_discrim_span, + discrim_span, ); } pat_ty @@ -341,11 +346,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Here, `demand::subtype` is good enough, but I don't // think any errors can be introduced by using // `demand::eqtype`. - self.demand_eqtype_pat(pat.span, expected, uniq_ty, match_discrim_span); - self.check_pat_walk(&inner, inner_ty, def_bm, match_discrim_span); + self.demand_eqtype_pat(pat.span, expected, uniq_ty, discrim_span); + self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span); uniq_ty } else { - self.check_pat_walk(&inner, tcx.types.err, def_bm, match_discrim_span); + self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span); tcx.types.err } } @@ -384,10 +389,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } }; - self.check_pat_walk(&inner, inner_ty, def_bm, match_discrim_span); + self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span); rptr_ty } else { - self.check_pat_walk(&inner, tcx.types.err, def_bm, match_discrim_span); + self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span); tcx.types.err } } @@ -445,13 +450,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; for elt in before { - self.check_pat_walk(&elt, inner_ty, def_bm, match_discrim_span); + self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span); } if let Some(ref slice) = *slice { - self.check_pat_walk(&slice, slice_ty, def_bm, match_discrim_span); + self.check_pat_walk(&slice, slice_ty, def_bm, discrim_span); } for elt in after { - self.check_pat_walk(&elt, inner_ty, def_bm, match_discrim_span); + self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span); } expected_ty } @@ -595,6 +600,321 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); ) -> Ty<'tcx> { let tcx = self.tcx; + use hir::MatchSource::*; + let (source_if, if_no_else, if_desugar) = match match_src { + IfDesugar { contains_else_clause } => (true, !contains_else_clause, true), + IfLetDesugar { contains_else_clause } => (true, !contains_else_clause, false), + _ => (false, false, false), + }; + + // Type check the descriminant and get its type. + let discrim_ty = if if_desugar { + // Here we want to ensure: + // + // 1. That default match bindings are *not* accepted in the condition of an + // `if` expression. E.g. given `fn foo() -> &bool;` we reject `if foo() { .. }`. + // + // 2. By expecting `bool` for `expr` we get nice diagnostics for e.g. `if x = y { .. }`. + self.check_expr_has_type_or_error(discrim, self.tcx.types.bool) + } else { + self.demand_discriminant_type(arms, discrim) + }; + + // If there are no arms, that is a diverging match; a special case. + if arms.is_empty() { + self.diverges.set(self.diverges.get() | Diverges::Always); + return tcx.types.never; + } + + self.warn_arms_when_scrutinee_diverges(arms, source_if); + + // Otherwise, we have to union together the types that the + // arms produce and so forth. + let discrim_diverges = self.diverges.get(); + self.diverges.set(Diverges::Maybe); + + // rust-lang/rust#55810: Typecheck patterns first (via eager + // collection into `Vec`), so we get types for all bindings. + let all_arm_pats_diverge: Vec<_> = arms.iter().map(|arm| { + let mut all_pats_diverge = Diverges::WarnedAlways; + for p in &arm.pats { + self.diverges.set(Diverges::Maybe); + let binding_mode = ty::BindingMode::BindByValue(hir::Mutability::MutImmutable); + self.check_pat_walk(&p, discrim_ty, binding_mode, Some(discrim.span)); + all_pats_diverge &= self.diverges.get(); + } + + // As discussed with @eddyb, this is for disabling unreachable_code + // warnings on patterns (they're now subsumed by unreachable_patterns + // warnings). + match all_pats_diverge { + Diverges::Maybe => Diverges::Maybe, + Diverges::Always | Diverges::WarnedAlways => Diverges::WarnedAlways, + } + }).collect(); + + // Now typecheck the blocks. + // + // The result of the match is the common supertype of all the + // arms. Start out the value as bottom, since it's the, well, + // bottom the type lattice, and we'll be moving up the lattice as + // we process each arm. (Note that any match with 0 arms is matching + // on any empty type and is therefore unreachable; should the flow + // of execution reach it, we will panic, so bottom is an appropriate + // type in that case) + let mut all_arms_diverge = Diverges::WarnedAlways; + + let expected = expected.adjust_for_branches(self); + + let mut coercion = { + let coerce_first = match expected { + // We don't coerce to `()` so that if the match expression is a + // statement it's branches can have any consistent type. That allows + // us to give better error messages (pointing to a usually better + // arm for inconsistent arms or to the whole match when a `()` type + // is required). + Expectation::ExpectHasType(ety) if ety != self.tcx.mk_unit() => ety, + _ => self.next_ty_var(TypeVariableOrigin::MiscVariable(expr.span)), + }; + CoerceMany::with_coercion_sites(coerce_first, arms) + }; + + let mut other_arms = vec![]; // used only for diagnostics + let mut prior_arm_ty = None; + for (i, (arm, pats_diverge)) in arms.iter().zip(all_arm_pats_diverge).enumerate() { + if let Some(g) = &arm.guard { + self.diverges.set(pats_diverge); + match g { + hir::Guard::If(e) => self.check_expr_has_type_or_error(e, tcx.types.bool), + }; + } + + self.diverges.set(pats_diverge); + let arm_ty = self.check_expr_with_expectation(&arm.body, expected); + all_arms_diverge &= self.diverges.get(); + + let span = expr.span; + + if source_if { + let then_expr = &arms[0].body; + match (i, if_no_else) { + (0, _) => coercion.coerce(self, &self.misc(span), then_expr, arm_ty), + (_, true) => self.if_fallback_coercion(span, then_expr, &mut coercion), + (_, _) => { + let then_ty = prior_arm_ty.unwrap(); + let cause = self.if_cause(span, then_expr, &arm.body, then_ty, arm_ty); + coercion.coerce(self, &cause, &arm.body, arm_ty); + } + } + } else { + let arm_span = if let hir::ExprKind::Block(blk, _) = &arm.body.node { + // Point at the block expr instead of the entire block + blk.expr.as_ref().map(|e| e.span).unwrap_or(arm.body.span) + } else { + arm.body.span + }; + let (span, code) = match i { + // The reason for the first arm to fail is not that the match arms diverge, + // but rather that there's a prior obligation that doesn't hold. + 0 => (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)), + _ => (span, ObligationCauseCode::MatchExpressionArm { + arm_span, + source: match_src, + prior_arms: other_arms.clone(), + last_ty: prior_arm_ty.unwrap(), + discrim_hir_id: discrim.hir_id, + }), + }; + let cause = self.cause(span, code); + coercion.coerce(self, &cause, &arm.body, arm_ty); + other_arms.push(arm_span); + if other_arms.len() > 5 { + other_arms.remove(0); + } + } + prior_arm_ty = Some(arm_ty); + } + + // We won't diverge unless the discriminant or all arms diverge. + self.diverges.set(discrim_diverges | all_arms_diverge); + + coercion.complete(self) + } + + /// When the previously checked expression (the scrutinee) diverges, + /// warn the user about the match arms being unreachable. + fn warn_arms_when_scrutinee_diverges(&self, arms: &'gcx [hir::Arm], source_if: bool) { + if self.diverges.get().always() { + let msg = if source_if { "block in `if` expression" } else { "arm" }; + for arm in arms { + self.warn_if_unreachable(arm.body.hir_id, arm.body.span, msg); + } + } + } + + /// Handle the fallback arm of a desugared if(-let) like a missing else. + fn if_fallback_coercion( + &self, + span: Span, + then_expr: &'gcx hir::Expr, + coercion: &mut CoerceMany<'gcx, 'tcx, '_, rustc::hir::Arm>, + ) { + // If this `if` expr is the parent's function return expr, + // the cause of the type coercion is the return type, point at it. (#25228) + let ret_reason = self.maybe_get_coercion_reason(then_expr.hir_id, span); + let cause = self.cause(span, ObligationCauseCode::IfExpressionWithNoElse); + coercion.coerce_forced_unit(self, &cause, &mut |err| { + if let Some((span, msg)) = &ret_reason { + err.span_label(*span, msg.as_str()); + } else if let ExprKind::Block(block, _) = &then_expr.node { + if let Some(expr) = &block.expr { + err.span_label(expr.span, "found here".to_string()); + } + } + err.note("`if` expressions without `else` evaluate to `()`"); + err.help("consider adding an `else` block that evaluates to the expected type"); + }, ret_reason.is_none()); + } + + fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, span: Span) -> Option<(Span, String)> { + use hir::Node::{Block, Item, Local}; + + let node = self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_node_by_hir_id( + self.tcx.hir().get_parent_node_by_hir_id(hir_id), + )); + if let Block(block) = node { + // check that the body's parent is an fn + let parent = self.tcx.hir().get_by_hir_id( + self.tcx.hir().get_parent_node_by_hir_id( + self.tcx.hir().get_parent_node_by_hir_id(block.hir_id), + ), + ); + if let (Some(expr), Item(hir::Item { + node: hir::ItemKind::Fn(..), .. + })) = (&block.expr, parent) { + // check that the `if` expr without `else` is the fn body's expr + if expr.span == span { + return self.get_fn_decl(hir_id).map(|(fn_decl, _)| ( + fn_decl.output.span(), + format!("expected `{}` because of this return type", fn_decl.output), + )); + } + } + } + if let Local(hir::Local { ty: Some(_), pat, .. }) = node { + return Some((pat.span, "expected because of this assignment".to_string())); + } + None + } + + fn if_cause( + &self, + span: Span, + then_expr: &'gcx hir::Expr, + else_expr: &'gcx hir::Expr, + then_ty: Ty<'tcx>, + else_ty: Ty<'tcx>, + ) -> ObligationCause<'tcx> { + let mut outer_sp = if self.tcx.sess.source_map().is_multiline(span) { + // The `if`/`else` isn't in one line in the output, include some context to make it + // clear it is an if/else expression: + // ``` + // LL | let x = if true { + // | _____________- + // LL || 10i32 + // || ----- expected because of this + // LL || } else { + // LL || 10u32 + // || ^^^^^ expected i32, found u32 + // LL || }; + // ||_____- if and else have incompatible types + // ``` + Some(span) + } else { + // The entire expression is in one line, only point at the arms + // ``` + // LL | let x = if true { 10i32 } else { 10u32 }; + // | ----- ^^^^^ expected i32, found u32 + // | | + // | expected because of this + // ``` + None + }; + + let mut remove_semicolon = None; + let error_sp = if let ExprKind::Block(block, _) = &else_expr.node { + if let Some(expr) = &block.expr { + expr.span + } else if let Some(stmt) = block.stmts.last() { + // possibly incorrect trailing `;` in the else arm + remove_semicolon = self.could_remove_semicolon(block, then_ty); + stmt.span + } else { // empty block, point at its entirety + // Avoid overlapping spans that aren't as readable: + // ``` + // 2 | let x = if true { + // | _____________- + // 3 | | 3 + // | | - expected because of this + // 4 | | } else { + // | |____________^ + // 5 | || + // 6 | || }; + // | || ^ + // | ||_____| + // | |______if and else have incompatible types + // | expected integer, found () + // ``` + // by not pointing at the entire expression: + // ``` + // 2 | let x = if true { + // | ------- if and else have incompatible types + // 3 | 3 + // | - expected because of this + // 4 | } else { + // | ____________^ + // 5 | | + // 6 | | }; + // | |_____^ expected integer, found () + // ``` + if outer_sp.is_some() { + outer_sp = Some(self.tcx.sess.source_map().def_span(span)); + } + else_expr.span + } + } else { // shouldn't happen unless the parser has done something weird + else_expr.span + }; + + // Compute `Span` of `then` part of `if`-expression: + let then_sp = if let ExprKind::Block(block, _) = &then_expr.node { + if let Some(expr) = &block.expr { + expr.span + } else if let Some(stmt) = block.stmts.last() { + // possibly incorrect trailing `;` in the else arm + remove_semicolon = remove_semicolon.or(self.could_remove_semicolon(block, else_ty)); + stmt.span + } else { // empty block, point at its entirety + outer_sp = None; // same as in `error_sp`, cleanup output + then_expr.span + } + } else { // shouldn't happen unless the parser has done something weird + then_expr.span + }; + + // Finally construct the cause: + self.cause(error_sp, ObligationCauseCode::IfExpression { + then: then_sp, + outer: outer_sp, + semicolon: remove_semicolon, + }) + } + + fn demand_discriminant_type( + &self, + arms: &'gcx [hir::Arm], + discrim: &'gcx hir::Expr, + ) -> Ty<'tcx> { // Not entirely obvious: if matches may create ref bindings, we want to // use the *precise* type of the discriminant, *not* some supertype, as // the "discriminant type" (issue #23116). @@ -653,143 +973,17 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); hir::MutMutable => 1, hir::MutImmutable => 0, }); - let discrim_ty; + if let Some(m) = contains_ref_bindings { - discrim_ty = self.check_expr_with_needs(discrim, Needs::maybe_mut_place(m)); + self.check_expr_with_needs(discrim, Needs::maybe_mut_place(m)) } else { // ...but otherwise we want to use any supertype of the // discriminant. This is sort of a workaround, see note (*) in // `check_pat` for some details. - discrim_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(discrim.span)); + let discrim_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(discrim.span)); self.check_expr_has_type_or_error(discrim, discrim_ty); - }; - - // If there are no arms, that is a diverging match; a special case. - if arms.is_empty() { - self.diverges.set(self.diverges.get() | Diverges::Always); - return tcx.types.never; + discrim_ty } - - if self.diverges.get().always() { - for arm in arms { - self.warn_if_unreachable(arm.body.hir_id, arm.body.span, "arm"); - } - } - - // Otherwise, we have to union together the types that the - // arms produce and so forth. - let discrim_diverges = self.diverges.get(); - self.diverges.set(Diverges::Maybe); - - // rust-lang/rust#55810: Typecheck patterns first (via eager - // collection into `Vec`), so we get types for all bindings. - let all_arm_pats_diverge: Vec<_> = arms.iter().map(|arm| { - let mut all_pats_diverge = Diverges::WarnedAlways; - for p in &arm.pats { - self.diverges.set(Diverges::Maybe); - self.check_pat_walk( - &p, - discrim_ty, - ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), - Some(discrim.span), - ); - all_pats_diverge &= self.diverges.get(); - } - - // As discussed with @eddyb, this is for disabling unreachable_code - // warnings on patterns (they're now subsumed by unreachable_patterns - // warnings). - match all_pats_diverge { - Diverges::Maybe => Diverges::Maybe, - Diverges::Always | Diverges::WarnedAlways => Diverges::WarnedAlways, - } - }).collect(); - - // Now typecheck the blocks. - // - // The result of the match is the common supertype of all the - // arms. Start out the value as bottom, since it's the, well, - // bottom the type lattice, and we'll be moving up the lattice as - // we process each arm. (Note that any match with 0 arms is matching - // on any empty type and is therefore unreachable; should the flow - // of execution reach it, we will panic, so bottom is an appropriate - // type in that case) - let mut all_arms_diverge = Diverges::WarnedAlways; - - let expected = expected.adjust_for_branches(self); - - let mut coercion = { - let coerce_first = match expected { - // We don't coerce to `()` so that if the match expression is a - // statement it's branches can have any consistent type. That allows - // us to give better error messages (pointing to a usually better - // arm for inconsistent arms or to the whole match when a `()` type - // is required). - Expectation::ExpectHasType(ety) if ety != self.tcx.mk_unit() => ety, - _ => self.next_ty_var(TypeVariableOrigin::MiscVariable(expr.span)), - }; - CoerceMany::with_coercion_sites(coerce_first, arms) - }; - - let mut other_arms = vec![]; // used only for diagnostics - let mut prior_arm_ty = None; - for (i, (arm, pats_diverge)) in arms.iter().zip(all_arm_pats_diverge).enumerate() { - if let Some(ref g) = arm.guard { - self.diverges.set(pats_diverge); - match g { - hir::Guard::If(e) => self.check_expr_has_type_or_error(e, tcx.types.bool), - }; - } - - self.diverges.set(pats_diverge); - let arm_ty = self.check_expr_with_expectation(&arm.body, expected); - all_arms_diverge &= self.diverges.get(); - - // Handle the fallback arm of a desugared if-let like a missing else. - let is_if_let_fallback = match match_src { - hir::MatchSource::IfLetDesugar { contains_else_clause: false } => { - i == arms.len() - 1 && arm_ty.is_unit() - } - _ => false - }; - - let arm_span = if let hir::ExprKind::Block(ref blk, _) = arm.body.node { - // Point at the block expr instead of the entire block - blk.expr.as_ref().map(|e| e.span).unwrap_or(arm.body.span) - } else { - arm.body.span - }; - if is_if_let_fallback { - let cause = self.cause(expr.span, ObligationCauseCode::IfExpressionWithNoElse); - assert!(arm_ty.is_unit()); - coercion.coerce_forced_unit(self, &cause, &mut |_| (), true); - } else { - let cause = if i == 0 { - // The reason for the first arm to fail is not that the match arms diverge, - // but rather that there's a prior obligation that doesn't hold. - self.cause(arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)) - } else { - self.cause(expr.span, ObligationCauseCode::MatchExpressionArm { - arm_span, - source: match_src, - prior_arms: other_arms.clone(), - last_ty: prior_arm_ty.unwrap(), - discrim_hir_id: discrim.hir_id, - }) - }; - coercion.coerce(self, &cause, &arm.body, arm_ty); - } - other_arms.push(arm_span); - if other_arms.len() > 5 { - other_arms.remove(0); - } - prior_arm_ty = Some(arm_ty); - } - - // We won't diverge unless the discriminant or all arms diverge. - self.diverges.set(discrim_diverges | all_arms_diverge); - - coercion.complete(self) } fn check_pat_struct( @@ -800,7 +994,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); etc: bool, expected: Ty<'tcx>, def_bm: ty::BindingMode, - match_discrim_span: Option, + discrim_span: Option, ) -> Ty<'tcx> { // Resolve the path and check the definition for errors. @@ -809,18 +1003,13 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); variant_ty } else { for field in fields { - self.check_pat_walk( - &field.node.pat, - self.tcx.types.err, - def_bm, - match_discrim_span, - ); + self.check_pat_walk(&field.node.pat, self.tcx.types.err, def_bm, discrim_span); } return self.tcx.types.err; }; // Type-check the path. - self.demand_eqtype_pat(pat.span, expected, pat_ty, match_discrim_span); + self.demand_eqtype_pat(pat.span, expected, pat_ty, discrim_span); // Type-check subpatterns. if self.check_struct_pat_fields(pat_ty, pat.hir_id, pat.span, variant, fields, etc, def_bm) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index d21ceb983f8f..008975068e58 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1248,12 +1248,8 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> augment_error(&mut db); } - if expression.filter(|e| fcx.is_assign_to_bool(e, expected)).is_some() { - // Error reported in `check_assign` so avoid emitting error again. - db.delay_as_bug(); - } else { - db.emit(); - } + // Error possibly reported in `check_assign` so avoid emitting error again. + db.emit_unless(expression.filter(|e| fcx.is_assign_to_bool(e, expected)).is_some()); self.final_ty = Some(fcx.tcx.types.err); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 965f52be31cd..2b519731eeed 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -117,6 +117,7 @@ use rustc::ty::subst::{UnpackedKind, Subst, InternalSubsts, SubstsRef, UserSelfT use rustc::ty::util::{Representability, IntTypeExt, Discr}; use rustc::ty::layout::VariantIdx; use syntax_pos::{self, BytePos, Span, MultiSpan}; +use syntax_pos::hygiene::CompilerDesugaringKind; use syntax::ast; use syntax::attr; use syntax::feature_gate::{GateIssue, emit_feature_err}; @@ -1086,12 +1087,8 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, // Add formal parameters. for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) { // Check the pattern. - fcx.check_pat_walk( - &arg.pat, - arg_ty, - ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), - None, - ); + let binding_mode = ty::BindingMode::BindByValue(hir::Mutability::MutImmutable); + fcx.check_pat_walk(&arg.pat, arg_ty, binding_mode, None); // Check that argument is Sized. // The check for a non-trivial pattern is a hack to avoid duplicate warnings @@ -2045,15 +2042,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// Produces warning on the given node, if the current point in the /// function is unreachable, and there hasn't been another warning. fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) { - if self.diverges.get() == Diverges::Always { + if self.diverges.get() == Diverges::Always && + // If span arose from a desugaring of `if` then it is the condition itself, + // which diverges, that we are about to lint on. This gives suboptimal diagnostics + // and so we stop here and allow the block of the `if`-expression to be linted instead. + !span.is_compiler_desugaring(CompilerDesugaringKind::IfTemporary) { self.diverges.set(Diverges::WarnedAlways); debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind); - self.tcx().lint_hir( - lint::builtin::UNREACHABLE_CODE, - id, span, - &format!("unreachable {}", kind)); + let msg = format!("unreachable {}", kind); + self.tcx().lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, &msg); } } @@ -3161,13 +3160,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) { - if self.is_assign_to_bool(expr, expected_ty) { - // Error reported in `check_assign` so avoid emitting error again. - // FIXME(centril): Consider removing if/when `if` desugars to `match`. - err.delay_as_bug(); - } else { - err.emit(); - } + let expr = match &expr.node { + ExprKind::DropTemps(expr) => expr, + _ => expr, + }; + // Error possibly reported in `check_assign` so avoid emitting error again. + err.emit_unless(self.is_assign_to_bool(expr, expected_ty)); } ty } @@ -3330,194 +3328,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { return_expr_ty); } - // A generic function for checking the 'then' and 'else' clauses in an 'if' - // or 'if-else' expression. - fn check_then_else(&self, - cond_expr: &'gcx hir::Expr, - then_expr: &'gcx hir::Expr, - opt_else_expr: Option<&'gcx hir::Expr>, - sp: Span, - expected: Expectation<'tcx>) -> Ty<'tcx> { - let cond_ty = self.check_expr_has_type_or_error(cond_expr, self.tcx.types.bool); - let cond_diverges = self.diverges.get(); - self.diverges.set(Diverges::Maybe); - - let expected = expected.adjust_for_branches(self); - let then_ty = self.check_expr_with_expectation(then_expr, expected); - let then_diverges = self.diverges.get(); - self.diverges.set(Diverges::Maybe); - - // We've already taken the expected type's preferences - // into account when typing the `then` branch. To figure - // out the initial shot at a LUB, we thus only consider - // `expected` if it represents a *hard* constraint - // (`only_has_type`); otherwise, we just go with a - // fresh type variable. - let coerce_to_ty = expected.coercion_target_type(self, sp); - let mut coerce: DynamicCoerceMany<'_, '_> = CoerceMany::new(coerce_to_ty); - - coerce.coerce(self, &self.misc(sp), then_expr, then_ty); - - if let Some(else_expr) = opt_else_expr { - let else_ty = self.check_expr_with_expectation(else_expr, expected); - let else_diverges = self.diverges.get(); - - let mut outer_sp = if self.tcx.sess.source_map().is_multiline(sp) { - // The `if`/`else` isn't in one line in the output, include some context to make it - // clear it is an if/else expression: - // ``` - // LL | let x = if true { - // | _____________- - // LL || 10i32 - // || ----- expected because of this - // LL || } else { - // LL || 10u32 - // || ^^^^^ expected i32, found u32 - // LL || }; - // ||_____- if and else have incompatible types - // ``` - Some(sp) - } else { - // The entire expression is in one line, only point at the arms - // ``` - // LL | let x = if true { 10i32 } else { 10u32 }; - // | ----- ^^^^^ expected i32, found u32 - // | | - // | expected because of this - // ``` - None - }; - let mut remove_semicolon = None; - let error_sp = if let ExprKind::Block(block, _) = &else_expr.node { - if let Some(expr) = &block.expr { - expr.span - } else if let Some(stmt) = block.stmts.last() { - // possibly incorrect trailing `;` in the else arm - remove_semicolon = self.could_remove_semicolon(block, then_ty); - stmt.span - } else { // empty block, point at its entirety - // Avoid overlapping spans that aren't as readable: - // ``` - // 2 | let x = if true { - // | _____________- - // 3 | | 3 - // | | - expected because of this - // 4 | | } else { - // | |____________^ - // 5 | || - // 6 | || }; - // | || ^ - // | ||_____| - // | |______if and else have incompatible types - // | expected integer, found () - // ``` - // by not pointing at the entire expression: - // ``` - // 2 | let x = if true { - // | ------- if and else have incompatible types - // 3 | 3 - // | - expected because of this - // 4 | } else { - // | ____________^ - // 5 | | - // 6 | | }; - // | |_____^ expected integer, found () - // ``` - if outer_sp.is_some() { - outer_sp = Some(self.tcx.sess.source_map().def_span(sp)); - } - else_expr.span - } - } else { // shouldn't happen unless the parser has done something weird - else_expr.span - }; - let then_sp = if let ExprKind::Block(block, _) = &then_expr.node { - if let Some(expr) = &block.expr { - expr.span - } else if let Some(stmt) = block.stmts.last() { - // possibly incorrect trailing `;` in the else arm - remove_semicolon = remove_semicolon.or( - self.could_remove_semicolon(block, else_ty)); - stmt.span - } else { // empty block, point at its entirety - outer_sp = None; // same as in `error_sp`, cleanup output - then_expr.span - } - } else { // shouldn't happen unless the parser has done something weird - then_expr.span - }; - - let if_cause = self.cause(error_sp, ObligationCauseCode::IfExpression { - then: then_sp, - outer: outer_sp, - semicolon: remove_semicolon, - }); - - coerce.coerce(self, &if_cause, else_expr, else_ty); - - // We won't diverge unless both branches do (or the condition does). - self.diverges.set(cond_diverges | then_diverges & else_diverges); - } else { - // If this `if` expr is the parent's function return expr, the cause of the type - // coercion is the return type, point at it. (#25228) - let ret_reason = self.maybe_get_coercion_reason(then_expr.hir_id, sp); - - let else_cause = self.cause(sp, ObligationCauseCode::IfExpressionWithNoElse); - coerce.coerce_forced_unit(self, &else_cause, &mut |err| { - if let Some((sp, msg)) = &ret_reason { - err.span_label(*sp, msg.as_str()); - } else if let ExprKind::Block(block, _) = &then_expr.node { - if let Some(expr) = &block.expr { - err.span_label(expr.span, "found here".to_string()); - } - } - err.note("`if` expressions without `else` evaluate to `()`"); - err.help("consider adding an `else` block that evaluates to the expected type"); - }, ret_reason.is_none()); - - // If the condition is false we can't diverge. - self.diverges.set(cond_diverges); - } - - let result_ty = coerce.complete(self); - if cond_ty.references_error() { - self.tcx.types.err - } else { - result_ty - } - } - - fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, sp: Span) -> Option<(Span, String)> { - let node = self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_node_by_hir_id( - self.tcx.hir().get_parent_node_by_hir_id(hir_id), - )); - if let Node::Block(block) = node { - // check that the body's parent is an fn - let parent = self.tcx.hir().get_by_hir_id( - self.tcx.hir().get_parent_node_by_hir_id( - self.tcx.hir().get_parent_node_by_hir_id(block.hir_id), - ), - ); - if let (Some(expr), Node::Item(hir::Item { - node: hir::ItemKind::Fn(..), .. - })) = (&block.expr, parent) { - // check that the `if` expr without `else` is the fn body's expr - if expr.span == sp { - return self.get_fn_decl(hir_id).map(|(fn_decl, _)| ( - fn_decl.output.span(), - format!("expected `{}` because of this return type", fn_decl.output), - )); - } - } - } - if let Node::Local(hir::Local { - ty: Some(_), pat, .. - }) = node { - return Some((pat.span, "expected because of this assignment".to_string())); - } - None - } - // Check field access expressions fn check_field(&self, expr: &'gcx hir::Expr, @@ -4062,7 +3872,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match expr.node { ExprKind::Block(..) | ExprKind::Loop(..) | ExprKind::While(..) | - ExprKind::If(..) | ExprKind::Match(..) => {} + ExprKind::Match(..) => {} _ => self.warn_if_unreachable(expr.hir_id, expr.span, "expression") } @@ -4444,10 +4254,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ExprKind::Assign(ref lhs, ref rhs) => { self.check_assign(expr, expected, lhs, rhs) } - ExprKind::If(ref cond, ref then_expr, ref opt_else_expr) => { - self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e), - expr.span, expected) - } ExprKind::While(ref cond, ref body, _) => { let ctxt = BreakableCtxt { // cannot use break with a value from a while loop @@ -5261,7 +5067,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match expression.node { ExprKind::Call(..) | ExprKind::MethodCall(..) | - ExprKind::If(..) | ExprKind::While(..) | ExprKind::Loop(..) | ExprKind::Match(..) | diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index a901afdff43e..1d9dc26bf609 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -591,6 +591,10 @@ impl ExpnFormat { /// The kind of compiler desugaring. #[derive(Clone, Copy, Hash, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)] pub enum CompilerDesugaringKind { + /// We desugar `if c { i } else { e }` to `match $ExprKind::Use(c) { true => i, _ => e }`. + /// However, we do not want to blame `c` for unreachability but rather say that `i` + /// is unreachable. This desugaring kind allows us to avoid blaming `c`. + IfTemporary, QuestionMark, TryBlock, /// Desugaring of an `impl Trait` in return type position @@ -605,6 +609,7 @@ pub enum CompilerDesugaringKind { impl CompilerDesugaringKind { pub fn name(self) -> Symbol { Symbol::intern(match self { + CompilerDesugaringKind::IfTemporary => "if", CompilerDesugaringKind::Async => "async", CompilerDesugaringKind::Await => "await", CompilerDesugaringKind::QuestionMark => "?", From 99039689f0c097703c7258c339b05d1c88e54ff8 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 24 Apr 2019 12:50:05 +0200 Subject: [PATCH 075/239] Adjust mir-opt tests for new HIR without If --- src/test/mir-opt/issue-38669.rs | 8 ++++--- src/test/mir-opt/loop_test.rs | 21 ++++++++++--------- .../mir-opt/nll/region-subtyping-basic.rs | 6 +++--- src/test/mir-opt/simplify_if.rs | 12 ++++++----- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/test/mir-opt/issue-38669.rs b/src/test/mir-opt/issue-38669.rs index 047e623941b7..e8ab690bb464 100644 --- a/src/test/mir-opt/issue-38669.rs +++ b/src/test/mir-opt/issue-38669.rs @@ -27,15 +27,17 @@ fn main() { // bb3: { // StorageLive(_4); // _4 = _1; -// switchInt(move _4) -> [false: bb5, otherwise: bb4]; +// FakeRead(ForMatchedPlace, _4); +// switchInt(_4) -> [false: bb5, otherwise: bb4]; // } -// bb4: { +// ... +// bb7: { // _0 = (); // StorageDead(_4); // StorageDead(_1); // return; // } -// bb5: { +// bb8: { // _3 = (); // StorageDead(_4); // _1 = const true; diff --git a/src/test/mir-opt/loop_test.rs b/src/test/mir-opt/loop_test.rs index 34891ee70b5c..e75955b9b244 100644 --- a/src/test/mir-opt/loop_test.rs +++ b/src/test/mir-opt/loop_test.rs @@ -22,19 +22,20 @@ fn main() { // resume; // } // ... -// bb3: { // Entry into the loop +// bb6: { // Entry into the loop // _1 = (); -// goto -> bb4; +// StorageDead(_2); +// goto -> bb7; // } -// bb4: { // The loop_block -// falseUnwind -> [real: bb5, cleanup: bb1]; +// bb7: { // The loop_block +// falseUnwind -> [real: bb8, cleanup: bb1]; // } -// bb5: { // The loop body (body_block) -// StorageLive(_5); -// _5 = const 1i32; -// FakeRead(ForLet, _5); -// StorageDead(_5); -// goto -> bb4; +// bb8: { // The loop body (body_block) +// StorageLive(_6); +// _6 = const 1i32; +// FakeRead(ForLet, _6); +// StorageDead(_6); +// goto -> bb7; // } // ... // END rustc.main.SimplifyCfg-qualify-consts.after.mir diff --git a/src/test/mir-opt/nll/region-subtyping-basic.rs b/src/test/mir-opt/nll/region-subtyping-basic.rs index bb27461bb1e0..622cc9998300 100644 --- a/src/test/mir-opt/nll/region-subtyping-basic.rs +++ b/src/test/mir-opt/nll/region-subtyping-basic.rs @@ -22,9 +22,9 @@ fn main() { // END RUST SOURCE // START rustc.main.nll.0.mir -// | '_#2r | U0 | {bb2[0..=5], bb3[0..=1]} -// | '_#3r | U0 | {bb2[1..=5], bb3[0..=1]} -// | '_#4r | U0 | {bb2[4..=5], bb3[0..=1]} +// | '_#2r | U0 | {bb2[0..=8], bb3[0], bb6[0..=1]} +// | '_#3r | U0 | {bb2[1..=8], bb3[0], bb6[0..=1]} +// | '_#4r | U0 | {bb2[4..=8], bb3[0], bb6[0..=1]} // END rustc.main.nll.0.mir // START rustc.main.nll.0.mir // let _2: &'_#3r usize; diff --git a/src/test/mir-opt/simplify_if.rs b/src/test/mir-opt/simplify_if.rs index f6e6c6baf7a4..b2a99a6d446b 100644 --- a/src/test/mir-opt/simplify_if.rs +++ b/src/test/mir-opt/simplify_if.rs @@ -5,13 +5,15 @@ fn main() { } // END RUST SOURCE -// START rustc.main.SimplifyBranches-initial.before.mir +// START rustc.main.SimplifyBranches-after-copy-prop.before.mir // bb0: { -// switchInt(const false) -> [false: bb3, otherwise: bb2]; +// ... +// switchInt(const false) -> [false: bb3, otherwise: bb1]; // } -// END rustc.main.SimplifyBranches-initial.before.mir -// START rustc.main.SimplifyBranches-initial.after.mir +// END rustc.main.SimplifyBranches-after-copy-prop.before.mir +// START rustc.main.SimplifyBranches-after-copy-prop.after.mir // bb0: { +// ... // goto -> bb3; // } -// END rustc.main.SimplifyBranches-initial.after.mir +// END rustc.main.SimplifyBranches-after-copy-prop.after.mir From 8d1e5b8b396e06778583ad62177430d2b95015f5 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 19 Mar 2019 04:47:07 +0100 Subject: [PATCH 076/239] Various test changes --- src/test/incremental/hashes/if_expressions.rs | 4 +- src/test/run-pass/if-ret.stderr | 8 ++ src/test/ui/if/if-let-arm-types.rs | 5 +- src/test/ui/if/if-let-arm-types.stderr | 8 +- src/test/ui/if/if-without-else-as-fn-expr.rs | 30 +++++ .../ui/if/if-without-else-as-fn-expr.stderr | 123 +++++++++++++++++- src/test/ui/issues/issue-19991.stderr | 3 + src/test/ui/issues/issue-50577.rs | 1 + src/test/ui/issues/issue-50577.stderr | 15 ++- src/test/ui/reachable/expr_if.rs | 2 +- src/test/ui/reachable/expr_if.stderr | 20 ++- 11 files changed, 200 insertions(+), 19 deletions(-) create mode 100644 src/test/run-pass/if-ret.stderr diff --git a/src/test/incremental/hashes/if_expressions.rs b/src/test/incremental/hashes/if_expressions.rs index fba7869af42f..6bc7d286e3ad 100644 --- a/src/test/incremental/hashes/if_expressions.rs +++ b/src/test/incremental/hashes/if_expressions.rs @@ -94,7 +94,7 @@ pub fn add_else_branch(x: bool) -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,typeck_tables_of")] +#[rustc_clean(cfg="cfail2", except="HirBody")] #[rustc_clean(cfg="cfail3")] pub fn add_else_branch(x: bool) -> u32 { let mut ret = 1; @@ -191,7 +191,7 @@ pub fn add_else_branch_if_let(x: Option) -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,typeck_tables_of")] +#[rustc_clean(cfg="cfail2", except="HirBody")] #[rustc_clean(cfg="cfail3")] pub fn add_else_branch_if_let(x: Option) -> u32 { let mut ret = 1; diff --git a/src/test/run-pass/if-ret.stderr b/src/test/run-pass/if-ret.stderr new file mode 100644 index 000000000000..a64281833e5c --- /dev/null +++ b/src/test/run-pass/if-ret.stderr @@ -0,0 +1,8 @@ +warning: unreachable block in `if` expression + --> $DIR/if-ret.rs:4:24 + | +LL | fn foo() { if (return) { } } + | ^^^ + | + = note: #[warn(unreachable_code)] on by default + diff --git a/src/test/ui/if/if-let-arm-types.rs b/src/test/ui/if/if-let-arm-types.rs index 819f5dd1cfc3..0f8815f0479f 100644 --- a/src/test/ui/if/if-let-arm-types.rs +++ b/src/test/ui/if/if-let-arm-types.rs @@ -1,11 +1,12 @@ fn main() { if let Some(b) = None { - //~^ NOTE if let` arms have incompatible types + //~^ NOTE if and else have incompatible types () + //~^ NOTE expected because of this } else { 1 }; - //~^^ ERROR: `if let` arms have incompatible types + //~^^ ERROR: if and else have incompatible types //~| NOTE expected (), found integer //~| NOTE expected type `()` } diff --git a/src/test/ui/if/if-let-arm-types.stderr b/src/test/ui/if/if-let-arm-types.stderr index b986973fe91f..ff88de20f76c 100644 --- a/src/test/ui/if/if-let-arm-types.stderr +++ b/src/test/ui/if/if-let-arm-types.stderr @@ -1,14 +1,16 @@ -error[E0308]: `if let` arms have incompatible types - --> $DIR/if-let-arm-types.rs:6:9 +error[E0308]: if and else have incompatible types + --> $DIR/if-let-arm-types.rs:7:9 | LL | / if let Some(b) = None { LL | | LL | | () + | | -- expected because of this +LL | | LL | | } else { LL | | 1 | | ^ expected (), found integer LL | | }; - | |_____- `if let` arms have incompatible types + | |_____- if and else have incompatible types | = note: expected type `()` found type `{integer}` diff --git a/src/test/ui/if/if-without-else-as-fn-expr.rs b/src/test/ui/if/if-without-else-as-fn-expr.rs index 67e4445629f8..15892de83854 100644 --- a/src/test/ui/if/if-without-else-as-fn-expr.rs +++ b/src/test/ui/if/if-without-else-as-fn-expr.rs @@ -3,6 +3,7 @@ fn foo(bar: usize) -> usize { return 3; } //~^^^ ERROR if may be missing an else clause + //~| ERROR mismatched types [E0308] } fn foo2(bar: usize) -> usize { @@ -10,6 +11,7 @@ fn foo2(bar: usize) -> usize { return 3; }; //~^^^ ERROR if may be missing an else clause + //~| ERROR mismatched types [E0308] x } @@ -18,8 +20,36 @@ fn foo3(bar: usize) -> usize { 3 } //~^^^ ERROR if may be missing an else clause + //~| ERROR mismatched types [E0308] } +fn foo_let(bar: usize) -> usize { + if let 0 = 1 { + return 3; + } + //~^^^ ERROR if may be missing an else clause + //~| ERROR mismatched types [E0308] +} + +fn foo2_let(bar: usize) -> usize { + let x: usize = if let 0 = 1 { + return 3; + }; + //~^^^ ERROR if may be missing an else clause + //~| ERROR mismatched types [E0308] + x +} + +fn foo3_let(bar: usize) -> usize { + if let 0 = 1 { + 3 + } + //~^^^ ERROR if may be missing an else clause + //~| ERROR mismatched types [E0308] +} + +// FIXME(60254): deduplicate first error in favor of second. + fn main() { let _ = foo(1); } diff --git a/src/test/ui/if/if-without-else-as-fn-expr.stderr b/src/test/ui/if/if-without-else-as-fn-expr.stderr index 0ba72726ca78..06600b1cb9ae 100644 --- a/src/test/ui/if/if-without-else-as-fn-expr.stderr +++ b/src/test/ui/if/if-without-else-as-fn-expr.stderr @@ -1,3 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/if-without-else-as-fn-expr.rs:2:5 + | +LL | / if bar % 5 == 0 { +LL | | return 3; +LL | | } + | |_____^ expected usize, found () + | + = note: expected type `usize` + found type `()` + error[E0317]: if may be missing an else clause --> $DIR/if-without-else-as-fn-expr.rs:2:5 | @@ -13,8 +24,20 @@ LL | | } = note: `if` expressions without `else` evaluate to `()` = help: consider adding an `else` block that evaluates to the expected type +error[E0308]: mismatched types + --> $DIR/if-without-else-as-fn-expr.rs:10:20 + | +LL | let x: usize = if bar % 5 == 0 { + | ____________________^ +LL | | return 3; +LL | | }; + | |_____^ expected usize, found () + | + = note: expected type `usize` + found type `()` + error[E0317]: if may be missing an else clause - --> $DIR/if-without-else-as-fn-expr.rs:9:20 + --> $DIR/if-without-else-as-fn-expr.rs:10:20 | LL | let x: usize = if bar % 5 == 0 { | _________-__________^ @@ -29,8 +52,19 @@ LL | | }; = note: `if` expressions without `else` evaluate to `()` = help: consider adding an `else` block that evaluates to the expected type +error[E0308]: mismatched types + --> $DIR/if-without-else-as-fn-expr.rs:19:5 + | +LL | / if bar % 5 == 0 { +LL | | 3 +LL | | } + | |_____^ expected usize, found () + | + = note: expected type `usize` + found type `()` + error[E0317]: if may be missing an else clause - --> $DIR/if-without-else-as-fn-expr.rs:17:5 + --> $DIR/if-without-else-as-fn-expr.rs:19:5 | LL | fn foo3(bar: usize) -> usize { | ----- expected `usize` because of this return type @@ -44,6 +78,87 @@ LL | | } = note: `if` expressions without `else` evaluate to `()` = help: consider adding an `else` block that evaluates to the expected type -error: aborting due to 3 previous errors +error[E0308]: mismatched types + --> $DIR/if-without-else-as-fn-expr.rs:27:5 + | +LL | / if let 0 = 1 { +LL | | return 3; +LL | | } + | |_____^ expected usize, found () + | + = note: expected type `usize` + found type `()` -For more information about this error, try `rustc --explain E0317`. +error[E0317]: if may be missing an else clause + --> $DIR/if-without-else-as-fn-expr.rs:27:5 + | +LL | fn foo_let(bar: usize) -> usize { + | ----- expected `usize` because of this return type +LL | / if let 0 = 1 { +LL | | return 3; +LL | | } + | |_____^ expected usize, found () + | + = note: expected type `usize` + found type `()` + = note: `if` expressions without `else` evaluate to `()` + = help: consider adding an `else` block that evaluates to the expected type + +error[E0308]: mismatched types + --> $DIR/if-without-else-as-fn-expr.rs:35:20 + | +LL | let x: usize = if let 0 = 1 { + | ____________________^ +LL | | return 3; +LL | | }; + | |_____^ expected usize, found () + | + = note: expected type `usize` + found type `()` + +error[E0317]: if may be missing an else clause + --> $DIR/if-without-else-as-fn-expr.rs:35:20 + | +LL | let x: usize = if let 0 = 1 { + | _________-__________^ + | | | + | | expected because of this assignment +LL | | return 3; +LL | | }; + | |_____^ expected usize, found () + | + = note: expected type `usize` + found type `()` + = note: `if` expressions without `else` evaluate to `()` + = help: consider adding an `else` block that evaluates to the expected type + +error[E0308]: mismatched types + --> $DIR/if-without-else-as-fn-expr.rs:44:5 + | +LL | / if let 0 = 1 { +LL | | 3 +LL | | } + | |_____^ expected usize, found () + | + = note: expected type `usize` + found type `()` + +error[E0317]: if may be missing an else clause + --> $DIR/if-without-else-as-fn-expr.rs:44:5 + | +LL | fn foo3_let(bar: usize) -> usize { + | ----- expected `usize` because of this return type +LL | / if let 0 = 1 { +LL | | 3 +LL | | } + | |_____^ expected usize, found () + | + = note: expected type `usize` + found type `()` + = note: `if` expressions without `else` evaluate to `()` + = help: consider adding an `else` block that evaluates to the expected type + +error: aborting due to 12 previous errors + +Some errors have detailed explanations: E0308, E0317. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-19991.stderr b/src/test/ui/issues/issue-19991.stderr index 4c6d150229a3..d9ea910adef5 100644 --- a/src/test/ui/issues/issue-19991.stderr +++ b/src/test/ui/issues/issue-19991.stderr @@ -6,11 +6,14 @@ LL | | LL | | LL | | LL | | 765 + | | --- found here LL | | }; | |_____^ expected (), found integer | = note: expected type `()` found type `{integer}` + = note: `if` expressions without `else` evaluate to `()` + = help: consider adding an `else` block that evaluates to the expected type error: aborting due to previous error diff --git a/src/test/ui/issues/issue-50577.rs b/src/test/ui/issues/issue-50577.rs index f0f1dc6c2866..bf892a8daa27 100644 --- a/src/test/ui/issues/issue-50577.rs +++ b/src/test/ui/issues/issue-50577.rs @@ -2,5 +2,6 @@ fn main() { enum Foo { Drop = assert_eq!(1, 1) //~^ ERROR if may be missing an else clause + //~| ERROR mismatched types [E0308] } } diff --git a/src/test/ui/issues/issue-50577.stderr b/src/test/ui/issues/issue-50577.stderr index 0c3ba2ea4f94..413c8c5c80b5 100644 --- a/src/test/ui/issues/issue-50577.stderr +++ b/src/test/ui/issues/issue-50577.stderr @@ -1,3 +1,13 @@ +error[E0308]: mismatched types + --> $DIR/issue-50577.rs:3:16 + | +LL | Drop = assert_eq!(1, 1) + | ^^^^^^^^^^^^^^^^ expected isize, found () + | + = note: expected type `isize` + found type `()` + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + error[E0317]: if may be missing an else clause --> $DIR/issue-50577.rs:3:16 | @@ -13,6 +23,7 @@ LL | Drop = assert_eq!(1, 1) = help: consider adding an `else` block that evaluates to the expected type = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0317`. +Some errors have detailed explanations: E0308, E0317. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/reachable/expr_if.rs b/src/test/ui/reachable/expr_if.rs index ed43bd8c6895..a3d54892de5b 100644 --- a/src/test/ui/reachable/expr_if.rs +++ b/src/test/ui/reachable/expr_if.rs @@ -4,7 +4,7 @@ #![deny(unreachable_code)] fn foo() { - if {return} { + if {return} { //~ ERROR unreachable block in `if` expression println!("Hello, world!"); } } diff --git a/src/test/ui/reachable/expr_if.stderr b/src/test/ui/reachable/expr_if.stderr index d11471da1a6a..f1690e595e5d 100644 --- a/src/test/ui/reachable/expr_if.stderr +++ b/src/test/ui/reachable/expr_if.stderr @@ -1,15 +1,25 @@ -error: unreachable statement - --> $DIR/expr_if.rs:27:5 +error: unreachable block in `if` expression + --> $DIR/expr_if.rs:7:17 | -LL | println!("But I am."); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | if {return} { + | _________________^ +LL | | println!("Hello, world!"); +LL | | } + | |_____^ | note: lint level defined here --> $DIR/expr_if.rs:4:9 | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ + +error: unreachable statement + --> $DIR/expr_if.rs:27:5 + | +LL | println!("But I am."); + | ^^^^^^^^^^^^^^^^^^^^^^ + | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: aborting due to previous error +error: aborting due to 2 previous errors From efd3733f9d33e814629c6d14ddee92d44f62205c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 25 Apr 2019 05:48:26 +0200 Subject: [PATCH 077/239] add test checking that 'if cond { .. }' where 'cond: &mut? bool' isn't accepted. --- src/test/ui/if/if-no-match-bindings.rs | 22 ++++++++++++ src/test/ui/if/if-no-match-bindings.stderr | 39 ++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/test/ui/if/if-no-match-bindings.rs create mode 100644 src/test/ui/if/if-no-match-bindings.stderr diff --git a/src/test/ui/if/if-no-match-bindings.rs b/src/test/ui/if/if-no-match-bindings.rs new file mode 100644 index 000000000000..581ce18c1d61 --- /dev/null +++ b/src/test/ui/if/if-no-match-bindings.rs @@ -0,0 +1,22 @@ +// Checks for `if` expressions with respect to default match bindings. +// Specifically, we do not accept `if cond { ... }` where `cond: &mut? bool`. +// Meanwhile, `match cond { true => ..., _ => ... }` does accept that. + +// FIXME(@rust-lang/lang-team): consider relaxing this? + +fn b_ref<'a>() -> &'a bool { &true } +fn b_mut_ref<'a>() -> &'a mut bool { &mut true } + +fn main() { + // This is OK: + match b_ref() { true => {}, _ => {} } + match b_mut_ref() { true => {}, _ => {} } + match &true { true => {}, _ => {} } + match &mut true { true => {}, _ => {} } + + // This is NOT: + if b_ref() {} //~ ERROR mismatched types [E0308] + if b_mut_ref() {} //~ ERROR mismatched types [E0308] + if &true {} //~ ERROR mismatched types [E0308] + if &mut true {} //~ ERROR mismatched types [E0308] +} diff --git a/src/test/ui/if/if-no-match-bindings.stderr b/src/test/ui/if/if-no-match-bindings.stderr new file mode 100644 index 000000000000..7b0b472121fc --- /dev/null +++ b/src/test/ui/if/if-no-match-bindings.stderr @@ -0,0 +1,39 @@ +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:18:8 + | +LL | if b_ref() {} + | ^^^^^^^ expected bool, found &bool + | + = note: expected type `bool` + found type `&bool` + +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:19:8 + | +LL | if b_mut_ref() {} + | ^^^^^^^^^^^ expected bool, found &mut bool + | + = note: expected type `bool` + found type `&mut bool` + +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:20:8 + | +LL | if &true {} + | ^^^^^ expected bool, found &bool + | + = note: expected type `bool` + found type `&bool` + +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:21:8 + | +LL | if &mut true {} + | ^^^^^^^^^ expected bool, found &mut bool + | + = note: expected type `bool` + found type `&mut bool` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. From f9cc5a65d24270fac44a7ccf709d7a7efd7b525d Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Fri, 10 May 2019 19:55:52 +0200 Subject: [PATCH 078/239] check_match: add FIXME for removing of hack. --- src/librustc_typeck/check/_match.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index e8af2f40b87a..a69f639e8941 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -615,6 +615,8 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); // `if` expression. E.g. given `fn foo() -> &bool;` we reject `if foo() { .. }`. // // 2. By expecting `bool` for `expr` we get nice diagnostics for e.g. `if x = y { .. }`. + // + // FIXME(60707): Consider removing hack with principled solution. self.check_expr_has_type_or_error(discrim, self.tcx.types.bool) } else { self.demand_discriminant_type(arms, discrim) From 385d012d9e3479397482558e1750205f70b62ffc Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 May 2019 20:53:21 +0100 Subject: [PATCH 079/239] Make const parent errors delay_span_bugs --- src/librustc_typeck/collect.rs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4185999fdd6d..c3b6a74bb824 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1404,7 +1404,13 @@ pub fn checked_type_of<'a, 'tcx>( if !fail { return None; } - bug!("unexpected const parent path def {:?}", x); + tcx.sess.delay_span_bug( + DUMMY_SP, + &format!( + "unexpected const parent path def {:?}", x + ), + ); + tcx.types.err } } } @@ -1412,7 +1418,13 @@ pub fn checked_type_of<'a, 'tcx>( if !fail { return None; } - bug!("unexpected const parent path {:?}", x); + tcx.sess.delay_span_bug( + DUMMY_SP, + &format!( + "unexpected const parent path {:?}", x + ), + ); + tcx.types.err } } } @@ -1421,7 +1433,13 @@ pub fn checked_type_of<'a, 'tcx>( if !fail { return None; } - bug!("unexpected const parent in type_of_def_id(): {:?}", x); + tcx.sess.delay_span_bug( + DUMMY_SP, + &format!( + "unexpected const parent in type_of_def_id(): {:?}", x + ), + ); + tcx.types.err } } } From 531080106235515c3a21e9771f39b8b2733a972b Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 May 2019 20:53:35 +0100 Subject: [PATCH 080/239] Add a test for invalid const arguments --- .../invalid-const-arg-for-type-param.rs | 9 +++++++ .../invalid-const-arg-for-type-param.stderr | 25 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/test/ui/const-generics/invalid-const-arg-for-type-param.rs create mode 100644 src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr diff --git a/src/test/ui/const-generics/invalid-const-arg-for-type-param.rs b/src/test/ui/const-generics/invalid-const-arg-for-type-param.rs new file mode 100644 index 000000000000..b069cd89680c --- /dev/null +++ b/src/test/ui/const-generics/invalid-const-arg-for-type-param.rs @@ -0,0 +1,9 @@ +use std::convert::TryInto; + +struct S; + +fn main() { + let _: u32 = 5i32.try_into::<32>().unwrap(); //~ ERROR wrong number of const arguments + S.f::<0>(); //~ ERROR no method named `f` + S::<0>; //~ ERROR wrong number of const arguments +} diff --git a/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr b/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr new file mode 100644 index 000000000000..8f3f91651edf --- /dev/null +++ b/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr @@ -0,0 +1,25 @@ +error[E0107]: wrong number of const arguments: expected 0, found 1 + --> $DIR/invalid-const-arg-for-type-param.rs:6:34 + | +LL | let _: u32 = 5i32.try_into::<32>().unwrap(); + | ^^ unexpected const argument + +error[E0599]: no method named `f` found for type `S` in the current scope + --> $DIR/invalid-const-arg-for-type-param.rs:7:7 + | +LL | struct S; + | --------- method `f` not found for this +... +LL | S.f::<0>(); + | ^ + +error[E0107]: wrong number of const arguments: expected 0, found 1 + --> $DIR/invalid-const-arg-for-type-param.rs:8:9 + | +LL | S::<0>; + | ^ unexpected const argument + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0599. +For more information about an error, try `rustc --explain E0107`. From 0f792abf00490066a8743e9b9686fecaad5dcac8 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 May 2019 20:53:46 +0100 Subject: [PATCH 081/239] Add a test for failed inference of const types --- .../cannot-infer-type-for-const-param.rs | 11 +++++++++++ .../cannot-infer-type-for-const-param.stderr | 15 +++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/test/ui/const-generics/cannot-infer-type-for-const-param.rs create mode 100644 src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs new file mode 100644 index 000000000000..c3f5e360fe28 --- /dev/null +++ b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs @@ -0,0 +1,11 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +// We should probably be able to infer the types here. However, this test is checking that we don't +// get an ICE in this case. It may be modified later to not be an error. + +struct Foo(pub [u8; NUM_BYTES]); + +fn main() { + let _ = Foo::<3>([1, 2, 3]); //~ ERROR type annotations needed +} diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr b/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr new file mode 100644 index 000000000000..a0641bd2fdc9 --- /dev/null +++ b/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr @@ -0,0 +1,15 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/cannot-infer-type-for-const-param.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + +error[E0282]: type annotations needed + --> $DIR/cannot-infer-type-for-const-param.rs:10:19 + | +LL | let _ = Foo::<3>([1, 2, 3]); + | ^ cannot infer type for `{integer}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. From 26afc4fb91827a174b044ab210cbb2fef1792b5b Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 May 2019 22:06:03 +0100 Subject: [PATCH 082/239] Allow fallible `lift_to_global` in existential type writeback --- src/librustc_typeck/check/writeback.rs | 43 +++++++++++++++----------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index f9d83146e30c..bf978352faee 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -611,26 +611,33 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { } } - let new = ty::ResolvedOpaqueTy { - concrete_type: definition_ty, - substs: self.tcx().lift_to_global(&opaque_defn.substs).unwrap(), - }; + if let Some(substs) = self.tcx().lift_to_global(&opaque_defn.substs) { + let new = ty::ResolvedOpaqueTy { + concrete_type: definition_ty, + substs, + }; - let old = self.tables - .concrete_existential_types - .insert(def_id, new); - if let Some(old) = old { - if old.concrete_type != definition_ty || old.substs != opaque_defn.substs { - span_bug!( - span, - "visit_opaque_types tried to write \ - different types for the same existential type: {:?}, {:?}, {:?}, {:?}", - def_id, - definition_ty, - opaque_defn, - old, - ); + let old = self.tables + .concrete_existential_types + .insert(def_id, new); + if let Some(old) = old { + if old.concrete_type != definition_ty || old.substs != opaque_defn.substs { + span_bug!( + span, + "visit_opaque_types tried to write \ + different types for the same existential type: {:?}, {:?}, {:?}, {:?}", + def_id, + definition_ty, + opaque_defn, + old, + ); + } } + } else { + self.tcx().sess.delay_span_bug( + span, + "cannot lift `opaque_defn` substs to global type context", + ); } } } From aa9369c7a4f463ea9e2d1f5ceecccbeb026baa41 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 May 2019 22:11:19 +0100 Subject: [PATCH 083/239] Add test --- src/test/ui/existential-type/issue-60371.rs | 15 ++++++++++ .../ui/existential-type/issue-60371.stderr | 29 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/test/ui/existential-type/issue-60371.rs create mode 100644 src/test/ui/existential-type/issue-60371.stderr diff --git a/src/test/ui/existential-type/issue-60371.rs b/src/test/ui/existential-type/issue-60371.rs new file mode 100644 index 000000000000..f9def11d1932 --- /dev/null +++ b/src/test/ui/existential-type/issue-60371.rs @@ -0,0 +1,15 @@ +trait Bug { + type Item: Bug; + + const FUN: fn() -> Self::Item; +} + +impl Bug for &() { + existential type Item: Bug; //~ ERROR existential types are unstable + //~^ ERROR the trait bound `(): Bug` is not satisfied + //~^^ ERROR could not find defining uses + + const FUN: fn() -> Self::Item = || (); +} + +fn main() {} diff --git a/src/test/ui/existential-type/issue-60371.stderr b/src/test/ui/existential-type/issue-60371.stderr new file mode 100644 index 000000000000..2560e01047aa --- /dev/null +++ b/src/test/ui/existential-type/issue-60371.stderr @@ -0,0 +1,29 @@ +error[E0658]: existential types are unstable + --> $DIR/issue-60371.rs:8:5 + | +LL | existential type Item: Bug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/34511 + = help: add #![feature(existential_type)] to the crate attributes to enable + +error[E0277]: the trait bound `(): Bug` is not satisfied + --> $DIR/issue-60371.rs:8:5 + | +LL | existential type Item: Bug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bug` is not implemented for `()` + | + = help: the following implementations were found: + <&() as Bug> + = note: the return type of a function must have a statically known size + +error: could not find defining uses + --> $DIR/issue-60371.rs:8:5 + | +LL | existential type Item: Bug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0658. +For more information about an error, try `rustc --explain E0277`. From 0686daab4ec82a4127d317c01324d46c58ef47b3 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 11 May 2019 00:08:19 +0100 Subject: [PATCH 084/239] Unwrap singleton block expressions in const arguments --- src/librustc_typeck/astconv.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 16033c6c50fd..da47ccf38a02 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1902,7 +1902,18 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { ty, }; - let expr = &tcx.hir().body(ast_const.body).value; + let mut expr = &tcx.hir().body(ast_const.body).value; + + // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments + // currently have to be wrapped in curly brackets, so it's necessary to special-case. + if let ExprKind::Block(block, _) = &expr.node { + if block.stmts.is_empty() { + if let Some(trailing) = &block.expr { + expr = &trailing; + } + } + } + if let ExprKind::Path(ref qpath) = expr.node { if let hir::QPath::Resolved(_, ref path) = qpath { if let Res::Def(DefKind::ConstParam, def_id) = path.res { From b3207d531d01c1dc6c1f3d4e7b1c20a1546fe108 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 11 May 2019 00:08:40 +0100 Subject: [PATCH 085/239] Add test for const impl --- .../const-generics/impl-const-generic-struct.rs | 16 ++++++++++++++++ .../impl-const-generic-struct.stderr | 6 ++++++ 2 files changed, 22 insertions(+) create mode 100644 src/test/ui/const-generics/impl-const-generic-struct.rs create mode 100644 src/test/ui/const-generics/impl-const-generic-struct.stderr diff --git a/src/test/ui/const-generics/impl-const-generic-struct.rs b/src/test/ui/const-generics/impl-const-generic-struct.rs new file mode 100644 index 000000000000..7a0c0f2be5d7 --- /dev/null +++ b/src/test/ui/const-generics/impl-const-generic-struct.rs @@ -0,0 +1,16 @@ +// run-pass + +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +struct S; + +impl S<{X}> { + fn x() -> u32 { + X + } +} + +fn main() { + assert_eq!(S::<19>::x(), 19); +} diff --git a/src/test/ui/const-generics/impl-const-generic-struct.stderr b/src/test/ui/const-generics/impl-const-generic-struct.stderr new file mode 100644 index 000000000000..d443e060a974 --- /dev/null +++ b/src/test/ui/const-generics/impl-const-generic-struct.stderr @@ -0,0 +1,6 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/impl-const-generic-struct.rs:3:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + From bf3c46cfc9dbe677ae801f0459cea5b8e5e5a178 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 11 May 2019 00:42:29 +0100 Subject: [PATCH 086/239] Allow subdirectories to be tested by x.py test --- src/bootstrap/test.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index a3d96836aad5..3847a2a1e464 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1184,8 +1184,13 @@ impl Step for Compiletest { Err(_) => p, } }) - .filter(|p| p.starts_with(suite_path) && p.is_file()) - .map(|p| p.strip_prefix(suite_path).unwrap().to_str().unwrap()) + .filter(|p| p.starts_with(suite_path) && (p.is_dir() || p.is_file())) + .filter_map(|p| { + match p.strip_prefix(suite_path).ok().and_then(|p| p.to_str()) { + Some(s) if s != "" => Some(s), + _ => None, + } + }) .collect(); test_args.append(&mut builder.config.cmd.test_args()); From c158a0f59270297a66058b9abac36d3e6e21ac37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 10 May 2019 16:57:03 -0700 Subject: [PATCH 087/239] Remove unnecessary unwraps --- src/librustc_typeck/check/method/suggest.rs | 57 ++++++++++++--------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index b57ae361eb69..77d2ffab8efb 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -91,14 +91,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { CandidateSource::ImplSource(impl_did) => { // Provide the best span we can. Use the item, if local to crate, else // the impl, if local to crate (item may be defaulted), else nothing. - let item = self.associated_item(impl_did, item_name, Namespace::Value) - .or_else(|| { - self.associated_item( - self.tcx.impl_trait_ref(impl_did).unwrap().def_id, - item_name, - Namespace::Value, - ) - }).unwrap(); + let item = match self.associated_item( + impl_did, + item_name, + Namespace::Value, + ).or_else(|| { + let impl_trait_ref = self.tcx.impl_trait_ref(impl_did)?; + self.associated_item( + impl_trait_ref.def_id, + item_name, + Namespace::Value, + ) + }) { + Some(item) => item, + None => continue, + }; let note_span = self.tcx.hir().span_if_local(item.def_id).or_else(|| { self.tcx.hir().span_if_local(impl_did) }); @@ -132,9 +139,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } CandidateSource::TraitSource(trait_did) => { - let item = self - .associated_item(trait_did, item_name, Namespace::Value) - .unwrap(); + let item = match self.associated_item( + trait_did, + item_name, + Namespace::Value) + { + Some(item) => item, + None => continue, + }; let item_span = self.tcx.sess.source_map() .def_span(self.tcx.def_span(item.def_id)); if sources.len() > 1 { @@ -251,8 +263,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let &QPath::Resolved(_, ref path) = &qpath { if let hir::def::Res::Local(hir_id) = path.res { let span = tcx.hir().span_by_hir_id(hir_id); - let snippet = tcx.sess.source_map().span_to_snippet(span) - .unwrap(); + let snippet = tcx.sess.source_map().span_to_snippet(span); let filename = tcx.sess.source_map().span_to_filename(span); let parent_node = self.tcx.hir().get_by_hir_id( @@ -263,12 +274,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { concrete_type, ); - match (filename, parent_node) { + match (filename, parent_node, snippet) { (FileName::Real(_), Node::Local(hir::Local { source: hir::LocalSource::Normal, ty, .. - })) => { + }), Ok(ref snippet)) => { err.span_suggestion( // account for `let x: _ = 42;` // ^^^^ @@ -375,14 +386,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.tcx.hir().get_parent_node_by_hir_id(expr.hir_id), ); - let span = call_expr.span.trim_start(item_name.span).unwrap(); - - err.span_suggestion( - span, - "remove the arguments", - String::new(), - Applicability::MaybeIncorrect, - ); + if let Some(span) = call_expr.span.trim_start(item_name.span) { + err.span_suggestion( + span, + "remove the arguments", + String::new(), + Applicability::MaybeIncorrect, + ); + } } } From 0545375ca6822b4b140cd853f368473d69b76227 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 10 May 2019 18:01:50 -0700 Subject: [PATCH 088/239] Add examples of ordered retain --- src/liballoc/collections/vec_deque.rs | 14 ++++++++++++++ src/liballoc/string.rs | 10 ++++++++++ src/liballoc/vec.rs | 10 ++++++++++ 3 files changed, 34 insertions(+) diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 82a60f924444..9a8d48083e67 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -1848,6 +1848,20 @@ impl VecDeque { /// buf.retain(|&x| x%2 == 0); /// assert_eq!(buf, [2, 4]); /// ``` + /// + /// The exact order may be useful for tracking external state, like an index. + /// + /// ``` + /// use std::collections::VecDeque; + /// + /// let mut buf = VecDeque::new(); + /// buf.extend(1..6); + /// + /// let keep = [false, true, true, false, true]; + /// let mut i = 0; + /// buf.retain(|_| (keep[i], i += 1).0); + /// assert_eq!(buf, [2, 3, 5]); + /// ``` #[stable(feature = "vec_deque_retain", since = "1.4.0")] pub fn retain(&mut self, mut f: F) where F: FnMut(&T) -> bool diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index aaa381426933..3fdcf95ccaa3 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1212,6 +1212,16 @@ impl String { /// /// assert_eq!(s, "foobar"); /// ``` + /// + /// The exact order may be useful for tracking external state, like an index. + /// + /// ``` + /// let mut s = String::from("abcde"); + /// let keep = [false, true, true, false, true]; + /// let mut i = 0; + /// s.retain(|_| (keep[i], i += 1).0); + /// assert_eq!(s, "bce"); + /// ``` #[inline] #[stable(feature = "string_retain", since = "1.26.0")] pub fn retain(&mut self, mut f: F) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index a9bc835010ff..073d3ab59370 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -947,6 +947,16 @@ impl Vec { /// vec.retain(|&x| x%2 == 0); /// assert_eq!(vec, [2, 4]); /// ``` + /// + /// The exact order may be useful for tracking external state, like an index. + /// + /// ``` + /// let mut vec = vec![1, 2, 3, 4, 5]; + /// let keep = [false, true, true, false, true]; + /// let mut i = 0; + /// vec.retain(|_| (keep[i], i += 1).0); + /// assert_eq!(vec, [2, 3, 5]); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn retain(&mut self, mut f: F) where F: FnMut(&T) -> bool From adc18eb7cfd0315a5bdba54ecc0d926176c4cd80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 10 May 2019 18:22:25 -0700 Subject: [PATCH 089/239] Avoid ICE by using delay_span_bug --- src/librustc_typeck/check/mod.rs | 5 +++-- src/test/ui/issues/issue-53498.rs | 17 +++++++++++++++++ src/test/ui/issues/issue-53498.stderr | 9 +++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/issues/issue-53498.rs create mode 100644 src/test/ui/issues/issue-53498.stderr diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 64c8ff8ff863..09ce9516fef2 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5653,10 +5653,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) { Ok(ok) => self.register_infer_ok_obligations(ok), Err(_) => { - span_bug!(span, + self.tcx.sess.delay_span_bug(span, &format!( "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?", self_ty, - impl_ty); + impl_ty, + )); } } } diff --git a/src/test/ui/issues/issue-53498.rs b/src/test/ui/issues/issue-53498.rs new file mode 100644 index 000000000000..c87d42364923 --- /dev/null +++ b/src/test/ui/issues/issue-53498.rs @@ -0,0 +1,17 @@ +pub mod test { + pub struct A; + pub struct B; + pub struct Foo(T); + + impl Foo { + fn foo() {} + } + + impl Foo { + fn foo() {} + } +} + +fn main() { + test::Foo::::foo(); //~ ERROR method `foo` is private +} diff --git a/src/test/ui/issues/issue-53498.stderr b/src/test/ui/issues/issue-53498.stderr new file mode 100644 index 000000000000..3fd48233daeb --- /dev/null +++ b/src/test/ui/issues/issue-53498.stderr @@ -0,0 +1,9 @@ +error[E0624]: method `foo` is private + --> $DIR/issue-53498.rs:16:5 + | +LL | test::Foo::::foo(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0624`. From 740a8dabb413abecd88a202f2370252b33e73a7f Mon Sep 17 00:00:00 2001 From: Thomas Heck Date: Sat, 11 May 2019 10:23:07 +0200 Subject: [PATCH 090/239] add comment to `Rc`/`Arc`'s `Eq` specialization --- src/liballoc/rc.rs | 5 +++++ src/liballoc/sync.rs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 68eecd97ea11..0dffb19476f3 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -932,6 +932,11 @@ impl RcEqIdent for Rc { } } +/// We're doing this specialization here, and not as a more general optimization on `&T`, because it +/// would otherwise add a cost to all equality checks on refs. We assume that `Rc`s are used to +/// store large values, that are slow to clone, but also heavy to check for equality, causing this +/// cost to pay off more easily. It's also more likely to have two `Rc` clones, that point to +/// the same value, than two `&T`s. #[stable(feature = "rust1", since = "1.0.0")] impl RcEqIdent for Rc { #[inline] diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 466e806663c7..90c7859b3db9 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1377,6 +1377,11 @@ impl ArcEqIdent for Arc { } } +/// We're doing this specialization here, and not as a more general optimization on `&T`, because it +/// would otherwise add a cost to all equality checks on refs. We assume that `Arc`s are used to +/// store large values, that are slow to clone, but also heavy to check for equality, causing this +/// cost to pay off more easily. It's also more likely to have two `Arc` clones, that point to +/// the same value, than two `&T`s. #[stable(feature = "rust1", since = "1.0.0")] impl ArcEqIdent for Arc { #[inline] From 28b125b83d9db4094a08b512a956c187bd29a51f Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 9 May 2019 02:00:29 +0300 Subject: [PATCH 091/239] Turn `ast::Lit` into a struct --- src/librustc/ich/impls_syntax.rs | 6 +++++- src/libsyntax/ast.rs | 6 +++++- src/libsyntax/attr/mod.rs | 12 ++++++------ src/libsyntax/ext/build.rs | 10 +++++----- src/libsyntax/parse/parser.rs | 7 +++---- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 35df43ef25ef..88a2c295a6ef 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -162,7 +162,11 @@ impl_stable_hash_for!(enum ::syntax::ast::LitIntType { Unsuffixed }); -impl_stable_hash_for_spanned!(::syntax::ast::LitKind); +impl_stable_hash_for!(struct ::syntax::ast::Lit { + node, + span +}); + impl_stable_hash_for!(enum ::syntax::ast::LitKind { Str(value, style), Err(value), diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index af2302d24f52..783792cf1977 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1351,7 +1351,11 @@ pub enum StrStyle { } /// A literal. -pub type Lit = Spanned; +#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)] +pub struct Lit { + pub node: LitKind, + pub span: Span, +} #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq)] pub enum LitIntType { diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index e00f91e39528..e331a2633544 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -16,7 +16,7 @@ use crate::ast::{AttrId, Attribute, AttrStyle, Name, Ident, Path, PathSegment}; use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem}; use crate::ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind, GenericParam}; use crate::mut_visit::visit_clobber; -use crate::source_map::{BytePos, Spanned, respan, dummy_spanned}; +use crate::source_map::{BytePos, Spanned, dummy_spanned}; use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; use crate::parse::parser::Parser; use crate::parse::{self, ParseSess, PResult}; @@ -350,11 +350,11 @@ impl Attribute { /* Constructors */ pub fn mk_name_value_item_str(ident: Ident, value: Spanned) -> MetaItem { - let value = respan(value.span, LitKind::Str(value.node, ast::StrStyle::Cooked)); + let value = Lit { node: LitKind::Str(value.node, ast::StrStyle::Cooked), span: value.span }; mk_name_value_item(ident.span.to(value.span), ident, value) } -pub fn mk_name_value_item(span: Span, ident: Ident, value: ast::Lit) -> MetaItem { +pub fn mk_name_value_item(span: Span, ident: Ident, value: Lit) -> MetaItem { MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::NameValue(value) } } @@ -417,7 +417,7 @@ pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute { let style = doc_comment_style(&text.as_str()); - let lit = respan(span, LitKind::Str(text, ast::StrStyle::Cooked)); + let lit = Lit { node: LitKind::Str(text, ast::StrStyle::Cooked), span }; Attribute { id, style, @@ -562,7 +562,7 @@ impl MetaItemKind { tokens.next(); return if let Some(TokenTree::Token(span, token)) = tokens.next() { LitKind::from_token(token) - .map(|lit| MetaItemKind::NameValue(Spanned { node: lit, span: span })) + .map(|node| MetaItemKind::NameValue(Lit { node, span })) } else { None }; @@ -609,7 +609,7 @@ impl NestedMetaItem { if let Some(TokenTree::Token(span, token)) = tokens.peek().cloned() { if let Some(node) = LitKind::from_token(token) { tokens.next(); - return Some(NestedMetaItem::Literal(respan(span, node))); + return Some(NestedMetaItem::Literal(Lit { node, span })); } } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 40dd187ed28a..0fe85361b54b 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -697,8 +697,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.expr_struct(span, self.path_ident(span, id), fields) } - fn expr_lit(&self, sp: Span, lit: ast::LitKind) -> P { - self.expr(sp, ast::ExprKind::Lit(respan(sp, lit))) + fn expr_lit(&self, span: Span, node: ast::LitKind) -> P { + self.expr(span, ast::ExprKind::Lit(ast::Lit { node, span })) } fn expr_usize(&self, span: Span, i: usize) -> P { self.expr_lit(span, ast::LitKind::Int(i as u128, @@ -1164,10 +1164,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> { attr::mk_list_item(sp, Ident::with_empty_ctxt(name).with_span_pos(sp), mis) } - fn meta_name_value(&self, sp: Span, name: ast::Name, value: ast::LitKind) + fn meta_name_value(&self, span: Span, name: ast::Name, node: ast::LitKind) -> ast::MetaItem { - attr::mk_name_value_item(sp, Ident::with_empty_ctxt(name).with_span_pos(sp), - respan(sp, value)) + attr::mk_name_value_item(span, Ident::with_empty_ctxt(name).with_span_pos(span), + ast::Lit { node, span }) } fn item_use(&self, sp: Span, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d97d1e2f0f4e..2b30d2db95e0 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2140,15 +2140,14 @@ impl<'a> Parser<'a> { /// Matches `lit = true | false | token_lit`. crate fn parse_lit(&mut self) -> PResult<'a, Lit> { let lo = self.span; - let lit = if self.eat_keyword(keywords::True) { + let node = if self.eat_keyword(keywords::True) { LitKind::Bool(true) } else if self.eat_keyword(keywords::False) { LitKind::Bool(false) } else { - let lit = self.parse_lit_token()?; - lit + self.parse_lit_token()? }; - Ok(source_map::Spanned { node: lit, span: lo.to(self.prev_span) }) + Ok(Lit { node, span: lo.to(self.prev_span) }) } /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`). From f2834a403abe78f56d750a302807eab5206bb2c5 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 9 May 2019 02:17:32 +0300 Subject: [PATCH 092/239] Keep the original token in `ast::Lit` --- src/librustc/hir/mod.rs | 2 +- src/librustc/ich/impls_syntax.rs | 33 ++++++++--------- src/librustdoc/html/highlight.rs | 2 ++ src/libsyntax/ast.rs | 3 ++ src/libsyntax/attr/mod.rs | 62 +++++++++++++++++++------------- src/libsyntax/ext/build.rs | 6 ++-- src/libsyntax/parse/mod.rs | 1 + src/libsyntax/parse/parser.rs | 30 ++++++++-------- src/libsyntax/parse/token.rs | 5 +++ src/libsyntax/print/pprust.rs | 1 + 10 files changed, 86 insertions(+), 59 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 9f7fa6c5557e..a59322bbe4da 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1353,7 +1353,7 @@ pub struct Expr { // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_arch = "x86_64")] -static_assert!(MEM_SIZE_OF_EXPR: std::mem::size_of::() == 72); +static_assert!(MEM_SIZE_OF_EXPR: std::mem::size_of::() == 80); impl Expr { pub fn precedence(&self) -> ExprPrecedence { diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 88a2c295a6ef..7ff546b7467d 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -164,6 +164,8 @@ impl_stable_hash_for!(enum ::syntax::ast::LitIntType { impl_stable_hash_for!(struct ::syntax::ast::Lit { node, + token, + suffix, span }); @@ -284,6 +286,19 @@ for tokenstream::TokenStream { } } +impl_stable_hash_for!(enum token::Lit { + Bool(val), + Byte(val), + Char(val), + Err(val), + Integer(val), + Float(val), + Str_(val), + ByteStr(val), + StrRaw(val, n), + ByteStrRaw(val, n) +}); + fn hash_token<'a, 'gcx, W: StableHasherResult>( token: &token::Token, hcx: &mut StableHashingContext<'a>, @@ -331,22 +346,8 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>( token::Token::CloseDelim(delim_token) => { std_hash::Hash::hash(&delim_token, hasher); } - token::Token::Literal(ref lit, ref opt_name) => { - mem::discriminant(lit).hash_stable(hcx, hasher); - match *lit { - token::Lit::Byte(val) | - token::Lit::Char(val) | - token::Lit::Err(val) | - token::Lit::Integer(val) | - token::Lit::Float(val) | - token::Lit::Str_(val) | - token::Lit::ByteStr(val) => val.hash_stable(hcx, hasher), - token::Lit::StrRaw(val, n) | - token::Lit::ByteStrRaw(val, n) => { - val.hash_stable(hcx, hasher); - n.hash_stable(hcx, hasher); - } - }; + token::Token::Literal(lit, opt_name) => { + lit.hash_stable(hcx, hasher); opt_name.hash_stable(hcx, hasher); } diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index d66455f91ba1..5bb06516ac49 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -318,6 +318,8 @@ impl<'a> Classifier<'a> { // Number literals. token::Integer(..) | token::Float(..) => Class::Number, + + token::Bool(..) => panic!("literal token contains `Lit::Bool`"), } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 783792cf1977..04bc146e145e 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -6,6 +6,7 @@ pub use crate::symbol::{Ident, Symbol as Name}; pub use crate::util::parser::ExprPrecedence; use crate::ext::hygiene::{Mark, SyntaxContext}; +use crate::parse::token; use crate::print::pprust; use crate::ptr::P; use crate::source_map::{dummy_spanned, respan, Spanned}; @@ -1354,6 +1355,8 @@ pub enum StrStyle { #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)] pub struct Lit { pub node: LitKind, + pub token: token::Lit, + pub suffix: Option, pub span: Span, } diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index e331a2633544..2b8745810833 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -350,7 +350,9 @@ impl Attribute { /* Constructors */ pub fn mk_name_value_item_str(ident: Ident, value: Spanned) -> MetaItem { - let value = Lit { node: LitKind::Str(value.node, ast::StrStyle::Cooked), span: value.span }; + let node = LitKind::Str(value.node, ast::StrStyle::Cooked); + let (token, suffix) = node.lit_token(); + let value = Lit { node, token, suffix, span: value.span }; mk_name_value_item(ident.span.to(value.span), ident, value) } @@ -417,7 +419,9 @@ pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute { let style = doc_comment_style(&text.as_str()); - let lit = Lit { node: LitKind::Str(text, ast::StrStyle::Cooked), span }; + let node = LitKind::Str(text, ast::StrStyle::Cooked); + let (token, suffix) = node.lit_token(); + let lit = Lit { node, token, suffix, span }; Attribute { id, style, @@ -562,7 +566,7 @@ impl MetaItemKind { tokens.next(); return if let Some(TokenTree::Token(span, token)) = tokens.next() { LitKind::from_token(token) - .map(|node| MetaItemKind::NameValue(Lit { node, span })) + .map(|(node, token, suffix)| MetaItemKind::NameValue(Lit { node, token, suffix, span })) } else { None }; @@ -607,9 +611,9 @@ impl NestedMetaItem { where I: Iterator, { if let Some(TokenTree::Token(span, token)) = tokens.peek().cloned() { - if let Some(node) = LitKind::from_token(token) { + if let Some((node, token, suffix)) = LitKind::from_token(token) { tokens.next(); - return Some(NestedMetaItem::Literal(Lit { node, span })); + return Some(NestedMetaItem::Literal(Lit { node, token, suffix, span })); } } @@ -625,28 +629,35 @@ impl Lit { impl LitKind { fn token(&self) -> Token { + match self.lit_token() { + (token::Bool(symbol), _) => Token::Ident(Ident::with_empty_ctxt(symbol), false), + (lit, suffix) => Token::Literal(lit, suffix), + } + } + + pub(crate) fn lit_token(&self) -> (token::Lit, Option) { use std::ascii; match *self { LitKind::Str(string, ast::StrStyle::Cooked) => { let escaped = string.as_str().escape_default().to_string(); - Token::Literal(token::Lit::Str_(Symbol::intern(&escaped)), None) + (token::Lit::Str_(Symbol::intern(&escaped)), None) } LitKind::Str(string, ast::StrStyle::Raw(n)) => { - Token::Literal(token::Lit::StrRaw(string, n), None) + (token::Lit::StrRaw(string, n), None) } LitKind::ByteStr(ref bytes) => { let string = bytes.iter().cloned().flat_map(ascii::escape_default) .map(Into::::into).collect::(); - Token::Literal(token::Lit::ByteStr(Symbol::intern(&string)), None) + (token::Lit::ByteStr(Symbol::intern(&string)), None) } LitKind::Byte(byte) => { let string: String = ascii::escape_default(byte).map(Into::::into).collect(); - Token::Literal(token::Lit::Byte(Symbol::intern(&string)), None) + (token::Lit::Byte(Symbol::intern(&string)), None) } LitKind::Char(ch) => { let string: String = ch.escape_default().map(Into::::into).collect(); - Token::Literal(token::Lit::Char(Symbol::intern(&string)), None) + (token::Lit::Char(Symbol::intern(&string)), None) } LitKind::Int(n, ty) => { let suffix = match ty { @@ -654,38 +665,39 @@ impl LitKind { ast::LitIntType::Signed(ty) => Some(Symbol::intern(ty.ty_to_string())), ast::LitIntType::Unsuffixed => None, }; - Token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())), suffix) + (token::Lit::Integer(Symbol::intern(&n.to_string())), suffix) } LitKind::Float(symbol, ty) => { - Token::Literal(token::Lit::Float(symbol), Some(Symbol::intern(ty.ty_to_string()))) + (token::Lit::Float(symbol), Some(Symbol::intern(ty.ty_to_string()))) } - LitKind::FloatUnsuffixed(symbol) => Token::Literal(token::Lit::Float(symbol), None), - LitKind::Bool(value) => Token::Ident(Ident::with_empty_ctxt(Symbol::intern(if value { - "true" - } else { - "false" - })), false), - LitKind::Err(val) => Token::Literal(token::Lit::Err(val), None), + LitKind::FloatUnsuffixed(symbol) => (token::Lit::Float(symbol), None), + LitKind::Bool(value) => { + let kw = if value { keywords::True } else { keywords::False }; + (token::Lit::Bool(kw.name()), None) + } + LitKind::Err(val) => (token::Lit::Err(val), None), } } - fn from_token(token: Token) -> Option { + fn from_token(token: Token) -> Option<(LitKind, token::Lit, Option)> { match token { - Token::Ident(ident, false) if ident.name == "true" => Some(LitKind::Bool(true)), - Token::Ident(ident, false) if ident.name == "false" => Some(LitKind::Bool(false)), + Token::Ident(ident, false) if ident.name == keywords::True.name() => + Some((LitKind::Bool(true), token::Bool(ident.name), None)), + Token::Ident(ident, false) if ident.name == keywords::False.name() => + Some((LitKind::Bool(false), token::Bool(ident.name), None)), Token::Interpolated(nt) => match *nt { token::NtExpr(ref v) | token::NtLiteral(ref v) => match v.node { - ExprKind::Lit(ref lit) => Some(lit.node.clone()), + ExprKind::Lit(ref lit) => Some((lit.node.clone(), lit.token, lit.suffix)), _ => None, }, _ => None, }, Token::Literal(lit, suf) => { let (suffix_illegal, result) = parse::lit_token(lit, suf, None); - if suffix_illegal && suf.is_some() { + if result.is_none() || suffix_illegal && suf.is_some() { return None; } - result + Some((result.unwrap(), lit, suf)) } _ => None, } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 0fe85361b54b..0f9977e85038 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -698,7 +698,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn expr_lit(&self, span: Span, node: ast::LitKind) -> P { - self.expr(span, ast::ExprKind::Lit(ast::Lit { node, span })) + let (token, suffix) = node.lit_token(); + self.expr(span, ast::ExprKind::Lit(ast::Lit { node, token, suffix, span })) } fn expr_usize(&self, span: Span, i: usize) -> P { self.expr_lit(span, ast::LitKind::Int(i as u128, @@ -1166,8 +1167,9 @@ impl<'a> AstBuilder for ExtCtxt<'a> { fn meta_name_value(&self, span: Span, name: ast::Name, node: ast::LitKind) -> ast::MetaItem { + let (token, suffix) = node.lit_token(); attr::mk_name_value_item(span, Ident::with_empty_ctxt(name).with_span_pos(span), - ast::Lit { node, span }) + ast::Lit { node, token, suffix, span }) } fn item_use(&self, sp: Span, diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index be44b964ba5a..4d4e99009a9d 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -376,6 +376,7 @@ crate fn lit_token(lit: token::Lit, suf: Option, diag: Option<(Span, &Ha use ast::LitKind; match lit { + token::Bool(_) => panic!("literal token contains `Lit::Bool`"), token::Byte(i) => { let lit_kind = match unescape_byte(&i.as_str()) { Ok(c) => LitKind::Byte(c), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2b30d2db95e0..b988cb1447df 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2070,11 +2070,11 @@ impl<'a> Parser<'a> { } /// Matches `token_lit = LIT_INTEGER | ...`. - fn parse_lit_token(&mut self) -> PResult<'a, LitKind> { + fn parse_lit_token(&mut self) -> PResult<'a, (LitKind, token::Lit, Option)> { let out = match self.token { token::Interpolated(ref nt) => match **nt { token::NtExpr(ref v) | token::NtLiteral(ref v) => match v.node { - ExprKind::Lit(ref lit) => { lit.node.clone() } + ExprKind::Lit(ref lit) => { (lit.node.clone(), lit.token, lit.suffix) } _ => { return self.unexpected_last(&self.token); } }, _ => { return self.unexpected_last(&self.token); } @@ -2088,19 +2088,19 @@ impl<'a> Parser<'a> { self.expect_no_suffix(sp, &format!("a {}", lit.literal_name()), suf) } - result.unwrap() + (result.unwrap(), lit, suf) } token::Dot if self.look_ahead(1, |t| match t { - token::Literal(parse::token::Lit::Integer(_) , _) => true, + token::Literal(token::Lit::Integer(_) , _) => true, _ => false, }) => { // recover from `let x = .4;` let lo = self.span; self.bump(); if let token::Literal( - parse::token::Lit::Integer(val), + token::Lit::Integer(val), suffix, ) = self.token { - let suffix = suffix.and_then(|s| { + let float_suffix = suffix.and_then(|s| { let s = s.as_str(); if s == "f32" { Some("f32") @@ -2117,14 +2117,14 @@ impl<'a> Parser<'a> { err.span_suggestion( sp, "must have an integer part", - format!("0.{}{}", val, suffix), + format!("0.{}{}", val, float_suffix), Applicability::MachineApplicable, ); err.emit(); - return Ok(match suffix { - "f32" => ast::LitKind::Float(val, ast::FloatTy::F32), - "f64" => ast::LitKind::Float(val, ast::FloatTy::F64), - _ => ast::LitKind::FloatUnsuffixed(val), + return Ok(match float_suffix { + "f32" => (ast::LitKind::Float(val, ast::FloatTy::F32), token::Float(val), suffix), + "f64" => (ast::LitKind::Float(val, ast::FloatTy::F64), token::Float(val), suffix), + _ => (ast::LitKind::FloatUnsuffixed(val), token::Float(val), suffix), }); } else { unreachable!(); @@ -2140,14 +2140,14 @@ impl<'a> Parser<'a> { /// Matches `lit = true | false | token_lit`. crate fn parse_lit(&mut self) -> PResult<'a, Lit> { let lo = self.span; - let node = if self.eat_keyword(keywords::True) { - LitKind::Bool(true) + let (node, token, suffix) = if self.eat_keyword(keywords::True) { + (LitKind::Bool(true), token::Bool(keywords::True.name()), None) } else if self.eat_keyword(keywords::False) { - LitKind::Bool(false) + (LitKind::Bool(false), token::Bool(keywords::False.name()), None) } else { self.parse_lit_token()? }; - Ok(Lit { node, span: lo.to(self.prev_span) }) + Ok(Lit { node, token, suffix, span: lo.to(self.prev_span) }) } /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`). diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index fd7a39c576da..48a949257ffb 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -61,6 +61,7 @@ impl DelimToken { #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] pub enum Lit { + Bool(ast::Name), // AST only, must never appear in a `Token` Byte(ast::Name), Char(ast::Name), Err(ast::Name), @@ -72,9 +73,13 @@ pub enum Lit { ByteStrRaw(ast::Name, u16), /* raw byte str delimited by n hash symbols */ } +#[cfg(target_arch = "x86_64")] +static_assert!(MEM_SIZE_OF_LIT: mem::size_of::() == 8); + impl Lit { crate fn literal_name(&self) -> &'static str { match *self { + Bool(_) => panic!("literal token contains `Lit::Bool`"), Byte(_) => "byte literal", Char(_) => "char literal", Err(_) => "invalid literal", diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 682621d40ab6..0e93b857708f 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -225,6 +225,7 @@ pub fn token_to_string(tok: &Token) -> String { /* Literals */ token::Literal(lit, suf) => { let mut out = match lit { + token::Bool(_) => panic!("literal token contains `Lit::Bool`"), token::Byte(b) => format!("b'{}'", b), token::Char(c) => format!("'{}'", c), token::Err(c) => format!("'{}'", c), From 751ae5af1a561a93ce61e9971be4b254a57e6576 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 9 May 2019 18:04:24 +0300 Subject: [PATCH 093/239] Introduce `hir::Lit` not keeping the original token --- src/librustc/hir/lowering.rs | 2 +- src/librustc/hir/mod.rs | 7 ++-- src/librustc/hir/print.rs | 59 ++++++++++++++++++++++++++++++++ src/librustc/ich/impls_syntax.rs | 2 ++ src/librustc_lint/types.rs | 10 +++--- src/librustc_typeck/check/mod.rs | 2 +- src/libsyntax/ast.rs | 2 +- 7 files changed, 74 insertions(+), 10 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 7ccfb826e37b..20a2a1fd49bd 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -4100,7 +4100,7 @@ impl<'a> LoweringContext<'a> { let ohs = P(self.lower_expr(ohs)); hir::ExprKind::Unary(op, ohs) } - ExprKind::Lit(ref l) => hir::ExprKind::Lit((*l).clone()), + ExprKind::Lit(ref l) => hir::ExprKind::Lit(respan(l.span, l.node.clone())), ExprKind::Cast(ref expr, ref ty) => { let expr = P(self.lower_expr(expr)); hir::ExprKind::Cast(expr, self.lower_ty(ty, ImplTraitContext::disallowed())) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index a59322bbe4da..d64589869280 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -20,7 +20,7 @@ use syntax_pos::{Span, DUMMY_SP, symbol::InternedString}; use syntax::source_map::Spanned; use rustc_target::spec::abi::Abi; use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect}; -use syntax::ast::{Attribute, Label, Lit, StrStyle, FloatTy, IntTy, UintTy}; +use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy}; use syntax::attr::{InlineAttr, OptimizeAttr}; use syntax::ext::hygiene::SyntaxContext; use syntax::ptr::P; @@ -1331,6 +1331,9 @@ impl BodyOwnerKind { } } +/// A literal. +pub type Lit = Spanned; + /// A constant (expression) that's not an item or associated item, /// but needs its own `DefId` for type-checking, const-eval, etc. /// These are usually found nested inside types (e.g., array lengths) @@ -1353,7 +1356,7 @@ pub struct Expr { // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_arch = "x86_64")] -static_assert!(MEM_SIZE_OF_EXPR: std::mem::size_of::() == 80); +static_assert!(MEM_SIZE_OF_EXPR: std::mem::size_of::() == 72); impl Expr { pub fn precedence(&self) -> ExprPrecedence { diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index c42d8f3cb3c3..b7260abb521a 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -15,6 +15,7 @@ use crate::hir; use crate::hir::{PatKind, GenericBound, TraitBoundModifier, RangeEnd}; use crate::hir::{GenericParam, GenericParamKind, GenericArg}; +use std::ascii; use std::borrow::Cow; use std::cell::Cell; use std::io::{self, Write, Read}; @@ -1276,6 +1277,64 @@ impl<'a> State<'a> { self.print_expr_maybe_paren(expr, parser::PREC_PREFIX) } + fn print_literal(&mut self, lit: &hir::Lit) -> io::Result<()> { + self.maybe_print_comment(lit.span.lo())?; + if let Some(ltrl) = self.next_lit(lit.span.lo()) { + return self.writer().word(ltrl.lit.clone()); + } + match lit.node { + hir::LitKind::Str(st, style) => self.print_string(&st.as_str(), style), + hir::LitKind::Err(st) => { + let st = st.as_str().escape_debug().to_string(); + let mut res = String::with_capacity(st.len() + 2); + res.push('\''); + res.push_str(&st); + res.push('\''); + self.writer().word(res) + } + hir::LitKind::Byte(byte) => { + let mut res = String::from("b'"); + res.extend(ascii::escape_default(byte).map(|c| c as char)); + res.push('\''); + self.writer().word(res) + } + hir::LitKind::Char(ch) => { + let mut res = String::from("'"); + res.extend(ch.escape_default()); + res.push('\''); + self.writer().word(res) + } + hir::LitKind::Int(i, t) => { + match t { + ast::LitIntType::Signed(st) => { + self.writer().word(st.val_to_string(i as i128)) + } + ast::LitIntType::Unsigned(ut) => { + self.writer().word(ut.val_to_string(i)) + } + ast::LitIntType::Unsuffixed => { + self.writer().word(i.to_string()) + } + } + } + hir::LitKind::Float(ref f, t) => { + self.writer().word(format!("{}{}", &f, t.ty_to_string())) + } + hir::LitKind::FloatUnsuffixed(ref f) => self.writer().word(f.as_str().to_string()), + hir::LitKind::Bool(val) => { + if val { self.writer().word("true") } else { self.writer().word("false") } + } + hir::LitKind::ByteStr(ref v) => { + let mut escaped: String = String::new(); + for &ch in v.iter() { + escaped.extend(ascii::escape_default(ch) + .map(|c| c as char)); + } + self.writer().word(format!("b\"{}\"", escaped)) + } + } + } + pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> { self.maybe_print_comment(expr.span.lo())?; self.print_outer_attributes(&expr.attrs)?; diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 7ff546b7467d..4e5718cc5ef2 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -181,6 +181,8 @@ impl_stable_hash_for!(enum ::syntax::ast::LitKind { Bool(value) }); +impl_stable_hash_for_spanned!(::syntax::ast::LitKind); + impl_stable_hash_for!(enum ::syntax::ast::IntTy { Isize, I8, I16, I32, I64, I128 }); impl_stable_hash_for!(enum ::syntax::ast::UintTy { Usize, U8, U16, U32, U64, U128 }); impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 }); diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index f4ebfd79fe1d..38b6e2c19793 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -62,7 +62,7 @@ impl TypeLimits { /// Returns `true` iff the lint was overridden. fn lint_overflowing_range_endpoint<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, - lit: &ast::Lit, + lit: &hir::Lit, lit_val: u128, max: u128, expr: &'tcx hir::Expr, @@ -132,7 +132,7 @@ fn uint_ty_range(uint_ty: ast::UintTy) -> (u128, u128) { } } -fn get_bin_hex_repr(cx: &LateContext<'_, '_>, lit: &ast::Lit) -> Option { +fn get_bin_hex_repr(cx: &LateContext<'_, '_>, lit: &hir::Lit) -> Option { let src = cx.sess().source_map().span_to_snippet(lit.span).ok()?; let firstch = src.chars().next()?; @@ -249,7 +249,7 @@ fn lint_int_literal<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, type_limits: &TypeLimits, e: &'tcx hir::Expr, - lit: &ast::Lit, + lit: &hir::Lit, t: ast::IntTy, v: u128, ) { @@ -301,7 +301,7 @@ fn lint_int_literal<'a, 'tcx>( fn lint_uint_literal<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, e: &'tcx hir::Expr, - lit: &ast::Lit, + lit: &hir::Lit, t: ast::UintTy, ) { let uint_type = if let ast::UintTy::Usize = t { @@ -363,7 +363,7 @@ fn lint_literal<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, type_limits: &TypeLimits, e: &'tcx hir::Expr, - lit: &ast::Lit, + lit: &hir::Lit, ) { match cx.tables.node_type(e.hir_id).sty { ty::Int(t) => { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a32745f27e1a..dc73ada1506c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3083,7 +3083,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // AST fragment checking fn check_lit(&self, - lit: &ast::Lit, + lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 04bc146e145e..a188f1a93689 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1352,7 +1352,7 @@ pub enum StrStyle { } /// A literal. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)] +#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Lit { pub node: LitKind, pub token: token::Lit, From a5b3f33cb90bf991342afa552bcd993e36f80fa7 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 9 May 2019 19:04:04 +0300 Subject: [PATCH 094/239] Eliminate `comments::Literal` --- src/librustc/hir/print.rs | 45 ++------ src/librustc_driver/pretty.rs | 6 +- src/librustdoc/clean/cfg.rs | 16 +-- src/libsyntax/attr/mod.rs | 7 +- src/libsyntax/parse/lexer/comments.rs | 29 +---- src/libsyntax/parse/parser.rs | 10 +- src/libsyntax/print/pprust.rs | 158 ++++++-------------------- 7 files changed, 61 insertions(+), 210 deletions(-) diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index b7260abb521a..6d48ad94a667 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -19,7 +19,6 @@ use std::ascii; use std::borrow::Cow; use std::cell::Cell; use std::io::{self, Write, Read}; -use std::iter::Peekable; use std::vec; pub enum AnnNode<'a> { @@ -77,7 +76,6 @@ pub struct State<'a> { pub s: pp::Printer<'a>, cm: Option<&'a SourceMap>, comments: Option>, - literals: Peekable>, cur_cmnt: usize, boxes: Vec, ann: &'a (dyn PpAnn + 'a), @@ -99,14 +97,6 @@ impl<'a> PrintState<'a> for State<'a> { fn cur_cmnt(&mut self) -> &mut usize { &mut self.cur_cmnt } - - fn cur_lit(&mut self) -> Option<&comments::Literal> { - self.literals.peek() - } - - fn bump_lit(&mut self) -> Option { - self.literals.next() - } } #[allow(non_upper_case_globals)] @@ -117,18 +107,16 @@ pub const default_columns: usize = 78; /// Requires you to pass an input filename and reader so that -/// it can scan the input text for comments and literals to -/// copy forward. +/// it can scan the input text for comments to copy forward. pub fn print_crate<'a>(cm: &'a SourceMap, sess: &ParseSess, krate: &hir::Crate, filename: FileName, input: &mut dyn Read, out: Box, - ann: &'a dyn PpAnn, - is_expanded: bool) + ann: &'a dyn PpAnn) -> io::Result<()> { - let mut s = State::new_from_input(cm, sess, filename, input, out, ann, is_expanded); + let mut s = State::new_from_input(cm, sess, filename, input, out, ann); // When printing the AST, we sometimes need to inject `#[no_std]` here. // Since you can't compile the HIR, it's not necessary. @@ -144,36 +132,21 @@ impl<'a> State<'a> { filename: FileName, input: &mut dyn Read, out: Box, - ann: &'a dyn PpAnn, - is_expanded: bool) + ann: &'a dyn PpAnn) -> State<'a> { - let (cmnts, lits) = comments::gather_comments_and_literals(sess, filename, input); - - State::new(cm, - out, - ann, - Some(cmnts), - // If the code is post expansion, don't use the table of - // literals, since it doesn't correspond with the literals - // in the AST anymore. - if is_expanded { - None - } else { - Some(lits) - }) + let comments = comments::gather_comments(sess, filename, input); + State::new(cm, out, ann, Some(comments)) } pub fn new(cm: &'a SourceMap, out: Box, ann: &'a dyn PpAnn, - comments: Option>, - literals: Option>) + comments: Option>) -> State<'a> { State { s: pp::mk_printer(out, default_columns), cm: Some(cm), comments, - literals: literals.unwrap_or_default().into_iter().peekable(), cur_cmnt: 0, boxes: Vec::new(), ann, @@ -190,7 +163,6 @@ pub fn to_string(ann: &dyn PpAnn, f: F) -> String s: pp::mk_printer(Box::new(&mut wr), default_columns), cm: None, comments: None, - literals: vec![].into_iter().peekable(), cur_cmnt: 0, boxes: Vec::new(), ann, @@ -1279,9 +1251,6 @@ impl<'a> State<'a> { fn print_literal(&mut self, lit: &hir::Lit) -> io::Result<()> { self.maybe_print_comment(lit.span.lo())?; - if let Some(ltrl) = self.next_lit(lit.span.lo()) { - return self.writer().word(ltrl.lit.clone()); - } match lit.node { hir::LitKind::Str(st, style) => self.print_string(&st.as_str(), style), hir::LitKind::Err(st) => { diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index fc8bf0baa99f..c74ed5ec30c3 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -805,8 +805,7 @@ pub fn print_after_hir_lowering<'tcx>( src_name, &mut rdr, box out, - annotation.pp_ann(), - true) + annotation.pp_ann()) }) } @@ -829,8 +828,7 @@ pub fn print_after_hir_lowering<'tcx>( src_name, &mut rdr, box out, - annotation.pp_ann(), - true); + annotation.pp_ann()); for node_id in uii.all_matching_node_ids(hir_map) { let node = hir_map.get(node_id); pp_state.print_node(node)?; diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 69445451503c..257f02af4cdd 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -414,10 +414,9 @@ impl<'a> fmt::Display for Html<'a> { mod test { use super::Cfg; - use syntax::symbol::Symbol; - use syntax::ast::*; - use syntax::source_map::dummy_spanned; use syntax_pos::DUMMY_SP; + use syntax::ast::*; + use syntax::symbol::Symbol; use syntax::with_globals; fn word_cfg(s: &str) -> Cfg { @@ -592,12 +591,11 @@ mod test { let mi = dummy_meta_item_word("all"); assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all"))); + let node = LitKind::Str(Symbol::intern("done"), StrStyle::Cooked); + let (token, suffix) = node.lit_token(); let mi = MetaItem { path: Path::from_ident(Ident::from_str("all")), - node: MetaItemKind::NameValue(dummy_spanned(LitKind::Str( - Symbol::intern("done"), - StrStyle::Cooked, - ))), + node: MetaItemKind::NameValue(Lit { node, token, suffix, span: DUMMY_SP }), span: DUMMY_SP, }; assert_eq!(Cfg::parse(&mi), Ok(name_value_cfg("all", "done"))); @@ -627,9 +625,11 @@ mod test { #[test] fn test_parse_err() { with_globals(|| { + let node = LitKind::Bool(false); + let (token, suffix) = node.lit_token(); let mi = MetaItem { path: Path::from_ident(Ident::from_str("foo")), - node: MetaItemKind::NameValue(dummy_spanned(LitKind::Bool(false))), + node: MetaItemKind::NameValue(Lit { node, token, suffix, span: DUMMY_SP }), span: DUMMY_SP, }; assert!(Cfg::parse(&mi).is_err()); diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 2b8745810833..e23c18266519 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -565,8 +565,9 @@ impl MetaItemKind { Some(TokenTree::Token(_, token::Eq)) => { tokens.next(); return if let Some(TokenTree::Token(span, token)) = tokens.next() { - LitKind::from_token(token) - .map(|(node, token, suffix)| MetaItemKind::NameValue(Lit { node, token, suffix, span })) + LitKind::from_token(token).map(|(node, token, suffix)| { + MetaItemKind::NameValue(Lit { node, token, suffix, span }) + }) } else { None }; @@ -635,7 +636,7 @@ impl LitKind { } } - pub(crate) fn lit_token(&self) -> (token::Lit, Option) { + pub fn lit_token(&self) -> (token::Lit, Option) { use std::ascii; match *self { diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs index 74fff3324eac..97d3fc002e9b 100644 --- a/src/libsyntax/parse/lexer/comments.rs +++ b/src/libsyntax/parse/lexer/comments.rs @@ -3,8 +3,7 @@ pub use CommentStyle::*; use crate::ast; use crate::source_map::SourceMap; use crate::parse::lexer::{is_block_doc_comment, is_pattern_whitespace}; -use crate::parse::lexer::{self, ParseSess, StringReader, TokenAndSpan}; -use crate::print::pprust; +use crate::parse::lexer::{self, ParseSess, StringReader}; use syntax_pos::{BytePos, CharPos, Pos, FileName}; use log::debug; @@ -339,16 +338,9 @@ fn consume_comment(rdr: &mut StringReader<'_>, debug!("<<< consume comment"); } -#[derive(Clone)] -pub struct Literal { - pub lit: String, - pub pos: BytePos, -} - // it appears this function is called only from pprust... that's // probably not a good thing. -pub fn gather_comments_and_literals(sess: &ParseSess, path: FileName, srdr: &mut dyn Read) - -> (Vec, Vec) +pub fn gather_comments(sess: &ParseSess, path: FileName, srdr: &mut dyn Read) -> Vec { let mut src = String::new(); srdr.read_to_string(&mut src).unwrap(); @@ -357,7 +349,6 @@ pub fn gather_comments_and_literals(sess: &ParseSess, path: FileName, srdr: &mut let mut rdr = lexer::StringReader::new_raw(sess, source_file, None); let mut comments: Vec = Vec::new(); - let mut literals: Vec = Vec::new(); let mut code_to_the_left = false; // Only code let mut anything_to_the_left = false; // Code or comments @@ -382,26 +373,12 @@ pub fn gather_comments_and_literals(sess: &ParseSess, path: FileName, srdr: &mut } } - let bstart = rdr.pos; rdr.next_token(); - // discard, and look ahead; we're working with internal state - let TokenAndSpan { tok, sp } = rdr.peek(); - if tok.is_lit() { - rdr.with_str_from(bstart, |s| { - debug!("tok lit: {}", s); - literals.push(Literal { - lit: s.to_string(), - pos: sp.lo(), - }); - }) - } else { - debug!("tok: {}", pprust::token_to_string(&tok)); - } code_to_the_left = true; anything_to_the_left = true; } - (comments, literals) + comments } #[cfg(test)] diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b988cb1447df..8c0c2f4b6e28 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2121,11 +2121,11 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); err.emit(); - return Ok(match float_suffix { - "f32" => (ast::LitKind::Float(val, ast::FloatTy::F32), token::Float(val), suffix), - "f64" => (ast::LitKind::Float(val, ast::FloatTy::F64), token::Float(val), suffix), - _ => (ast::LitKind::FloatUnsuffixed(val), token::Float(val), suffix), - }); + return Ok((match float_suffix { + "f32" => ast::LitKind::Float(val, ast::FloatTy::F32), + "f64" => ast::LitKind::Float(val, ast::FloatTy::F64), + _ => ast::LitKind::FloatUnsuffixed(val), + }, token::Float(val), suffix)); } else { unreachable!(); }; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 0e93b857708f..fa16a2b200ff 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -20,10 +20,8 @@ use rustc_target::spec::abi::{self, Abi}; use syntax_pos::{self, BytePos}; use syntax_pos::{DUMMY_SP, FileName}; -use std::ascii; use std::borrow::Cow; use std::io::{self, Write, Read}; -use std::iter::Peekable; use std::vec; pub enum AnnNode<'a> { @@ -49,8 +47,7 @@ impl PpAnn for NoAnn {} pub struct State<'a> { pub s: pp::Printer<'a>, cm: Option<&'a SourceMap>, - comments: Option >, - literals: Peekable>, + comments: Option>, cur_cmnt: usize, boxes: Vec, ann: &'a (dyn PpAnn+'a), @@ -62,7 +59,6 @@ fn rust_printer<'a>(writer: Box, ann: &'a dyn PpAnn) -> State<'a> s: pp::mk_printer(writer, DEFAULT_COLUMNS), cm: None, comments: None, - literals: vec![].into_iter().peekable(), cur_cmnt: 0, boxes: Vec::new(), ann, @@ -75,8 +71,7 @@ pub const INDENT_UNIT: usize = 4; pub const DEFAULT_COLUMNS: usize = 78; /// Requires you to pass an input filename and reader so that -/// it can scan the input text for comments and literals to -/// copy forward. +/// it can scan the input text for comments to copy forward. pub fn print_crate<'a>(cm: &'a SourceMap, sess: &ParseSess, krate: &ast::Crate, @@ -118,36 +113,23 @@ impl<'a> State<'a> { out: Box, ann: &'a dyn PpAnn, is_expanded: bool) -> State<'a> { - let (cmnts, lits) = comments::gather_comments_and_literals(sess, filename, input); - - State::new( - cm, - out, - ann, - Some(cmnts), - // If the code is post expansion, don't use the table of - // literals, since it doesn't correspond with the literals - // in the AST anymore. - if is_expanded { None } else { Some(lits) }, - is_expanded - ) + let comments = comments::gather_comments(sess, filename, input); + State::new(cm, out, ann, Some(comments), is_expanded) } pub fn new(cm: &'a SourceMap, out: Box, ann: &'a dyn PpAnn, comments: Option>, - literals: Option>, is_expanded: bool) -> State<'a> { State { s: pp::mk_printer(out, DEFAULT_COLUMNS), cm: Some(cm), comments, - literals: literals.unwrap_or_default().into_iter().peekable(), cur_cmnt: 0, boxes: Vec::new(), ann, - is_expanded: is_expanded + is_expanded, } } } @@ -180,6 +162,31 @@ fn binop_to_string(op: BinOpToken) -> &'static str { } } +fn literal_to_string(lit: token::Lit, suffix: Option) -> String { + let mut out = match lit { + token::Byte(b) => format!("b'{}'", b), + token::Char(c) => format!("'{}'", c), + token::Err(c) => format!("'{}'", c), + token::Bool(c) | + token::Float(c) | + token::Integer(c) => c.to_string(), + token::Str_(s) => format!("\"{}\"", s), + token::StrRaw(s, n) => format!("r{delim}\"{string}\"{delim}", + delim="#".repeat(n as usize), + string=s), + token::ByteStr(v) => format!("b\"{}\"", v), + token::ByteStrRaw(s, n) => format!("br{delim}\"{string}\"{delim}", + delim="#".repeat(n as usize), + string=s), + }; + + if let Some(suffix) = suffix { + out.push_str(&suffix.as_str()) + } + + out +} + pub fn token_to_string(tok: &Token) -> String { match *tok { token::Eq => "=".to_string(), @@ -223,30 +230,7 @@ pub fn token_to_string(tok: &Token) -> String { token::SingleQuote => "'".to_string(), /* Literals */ - token::Literal(lit, suf) => { - let mut out = match lit { - token::Bool(_) => panic!("literal token contains `Lit::Bool`"), - token::Byte(b) => format!("b'{}'", b), - token::Char(c) => format!("'{}'", c), - token::Err(c) => format!("'{}'", c), - token::Float(c) | - token::Integer(c) => c.to_string(), - token::Str_(s) => format!("\"{}\"", s), - token::StrRaw(s, n) => format!("r{delim}\"{string}\"{delim}", - delim="#".repeat(n as usize), - string=s), - token::ByteStr(v) => format!("b\"{}\"", v), - token::ByteStrRaw(s, n) => format!("br{delim}\"{string}\"{delim}", - delim="#".repeat(n as usize), - string=s), - }; - - if let Some(s) = suf { - out.push_str(&s.as_str()) - } - - out - } + token::Literal(lit, suf) => literal_to_string(lit, suf), /* Name components */ token::Ident(s, false) => s.to_string(), @@ -439,8 +423,6 @@ pub trait PrintState<'a> { fn boxes(&mut self) -> &mut Vec; fn comments(&mut self) -> &mut Option>; fn cur_cmnt(&mut self) -> &mut usize; - fn cur_lit(&mut self) -> Option<&comments::Literal>; - fn bump_lit(&mut self) -> Option; fn word_space>>(&mut self, w: S) -> io::Result<()> { self.writer().word(w)?; @@ -505,21 +487,6 @@ pub trait PrintState<'a> { self.end() } - fn next_lit(&mut self, pos: BytePos) -> Option { - while let Some(ltrl) = self.cur_lit().cloned() { - if ltrl.pos > pos { break; } - - // we don't need the value here since we're forced to clone cur_lit - // due to lack of NLL. - self.bump_lit(); - if ltrl.pos == pos { - return Some(ltrl); - } - } - - None - } - fn maybe_print_comment(&mut self, pos: BytePos) -> io::Result<()> { while let Some(ref cmnt) = self.next_comment() { if cmnt.pos < pos { @@ -607,60 +574,7 @@ pub trait PrintState<'a> { fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> { self.maybe_print_comment(lit.span.lo())?; - if let Some(ltrl) = self.next_lit(lit.span.lo()) { - return self.writer().word(ltrl.lit.clone()); - } - match lit.node { - ast::LitKind::Str(st, style) => self.print_string(&st.as_str(), style), - ast::LitKind::Err(st) => { - let st = st.as_str().escape_debug().to_string(); - let mut res = String::with_capacity(st.len() + 2); - res.push('\''); - res.push_str(&st); - res.push('\''); - self.writer().word(res) - } - ast::LitKind::Byte(byte) => { - let mut res = String::from("b'"); - res.extend(ascii::escape_default(byte).map(|c| c as char)); - res.push('\''); - self.writer().word(res) - } - ast::LitKind::Char(ch) => { - let mut res = String::from("'"); - res.extend(ch.escape_default()); - res.push('\''); - self.writer().word(res) - } - ast::LitKind::Int(i, t) => { - match t { - ast::LitIntType::Signed(st) => { - self.writer().word(st.val_to_string(i as i128)) - } - ast::LitIntType::Unsigned(ut) => { - self.writer().word(ut.val_to_string(i)) - } - ast::LitIntType::Unsuffixed => { - self.writer().word(i.to_string()) - } - } - } - ast::LitKind::Float(ref f, t) => { - self.writer().word(format!("{}{}", &f, t.ty_to_string())) - } - ast::LitKind::FloatUnsuffixed(ref f) => self.writer().word(f.as_str().to_string()), - ast::LitKind::Bool(val) => { - if val { self.writer().word("true") } else { self.writer().word("false") } - } - ast::LitKind::ByteStr(ref v) => { - let mut escaped: String = String::new(); - for &ch in v.iter() { - escaped.extend(ascii::escape_default(ch) - .map(|c| c as char)); - } - self.writer().word(format!("b\"{}\"", escaped)) - } - } + self.writer().word(literal_to_string(lit.token, lit.suffix)) } fn print_string(&mut self, st: &str, @@ -881,14 +795,6 @@ impl<'a> PrintState<'a> for State<'a> { fn cur_cmnt(&mut self) -> &mut usize { &mut self.cur_cmnt } - - fn cur_lit(&mut self) -> Option<&comments::Literal> { - self.literals.peek() - } - - fn bump_lit(&mut self) -> Option { - self.literals.next() - } } impl<'a> State<'a> { From 8739668438a40712a0bc617bc587d415c8cb42f0 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 10 May 2019 03:00:51 +0300 Subject: [PATCH 095/239] Simplify conversions between tokens and semantic literals --- src/librustc/hir/print.rs | 56 +---- src/librustdoc/clean/cfg.rs | 24 +- src/libsyntax/attr/mod.rs | 104 +++++---- src/libsyntax/ext/build.rs | 11 +- src/libsyntax/parse/mod.rs | 208 +++++++++++------- src/libsyntax/parse/parser.rs | 159 ++++--------- src/libsyntax/parse/token.rs | 7 + src/libsyntax/print/pprust.rs | 2 +- .../ui/malformed/malformed-interpolated.rs | 5 +- .../malformed/malformed-interpolated.stderr | 9 +- 10 files changed, 260 insertions(+), 325 deletions(-) diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 6d48ad94a667..475bf8d83723 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -5,7 +5,7 @@ use syntax::parse::ParseSess; use syntax::parse::lexer::comments; use syntax::print::pp::{self, Breaks}; use syntax::print::pp::Breaks::{Consistent, Inconsistent}; -use syntax::print::pprust::PrintState; +use syntax::print::pprust::{self, PrintState}; use syntax::ptr::P; use syntax::symbol::keywords; use syntax::util::parser::{self, AssocOp, Fixity}; @@ -15,7 +15,6 @@ use crate::hir; use crate::hir::{PatKind, GenericBound, TraitBoundModifier, RangeEnd}; use crate::hir::{GenericParam, GenericParamKind, GenericArg}; -use std::ascii; use std::borrow::Cow; use std::cell::Cell; use std::io::{self, Write, Read}; @@ -1251,57 +1250,8 @@ impl<'a> State<'a> { fn print_literal(&mut self, lit: &hir::Lit) -> io::Result<()> { self.maybe_print_comment(lit.span.lo())?; - match lit.node { - hir::LitKind::Str(st, style) => self.print_string(&st.as_str(), style), - hir::LitKind::Err(st) => { - let st = st.as_str().escape_debug().to_string(); - let mut res = String::with_capacity(st.len() + 2); - res.push('\''); - res.push_str(&st); - res.push('\''); - self.writer().word(res) - } - hir::LitKind::Byte(byte) => { - let mut res = String::from("b'"); - res.extend(ascii::escape_default(byte).map(|c| c as char)); - res.push('\''); - self.writer().word(res) - } - hir::LitKind::Char(ch) => { - let mut res = String::from("'"); - res.extend(ch.escape_default()); - res.push('\''); - self.writer().word(res) - } - hir::LitKind::Int(i, t) => { - match t { - ast::LitIntType::Signed(st) => { - self.writer().word(st.val_to_string(i as i128)) - } - ast::LitIntType::Unsigned(ut) => { - self.writer().word(ut.val_to_string(i)) - } - ast::LitIntType::Unsuffixed => { - self.writer().word(i.to_string()) - } - } - } - hir::LitKind::Float(ref f, t) => { - self.writer().word(format!("{}{}", &f, t.ty_to_string())) - } - hir::LitKind::FloatUnsuffixed(ref f) => self.writer().word(f.as_str().to_string()), - hir::LitKind::Bool(val) => { - if val { self.writer().word("true") } else { self.writer().word("false") } - } - hir::LitKind::ByteStr(ref v) => { - let mut escaped: String = String::new(); - for &ch in v.iter() { - escaped.extend(ascii::escape_default(ch) - .map(|c| c as char)); - } - self.writer().word(format!("b\"{}\"", escaped)) - } - } + let (token, suffix) = lit.node.to_lit_token(); + self.writer().word(pprust::literal_to_string(token, suffix)) } pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> { diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 257f02af4cdd..51fe26b37431 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -591,13 +591,10 @@ mod test { let mi = dummy_meta_item_word("all"); assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all"))); - let node = LitKind::Str(Symbol::intern("done"), StrStyle::Cooked); - let (token, suffix) = node.lit_token(); - let mi = MetaItem { - path: Path::from_ident(Ident::from_str("all")), - node: MetaItemKind::NameValue(Lit { node, token, suffix, span: DUMMY_SP }), - span: DUMMY_SP, - }; + let mi = attr::mk_name_value_item_str( + Ident::from_str("all"), + dummy_spanned(Symbol::intern("done")) + ); assert_eq!(Cfg::parse(&mi), Ok(name_value_cfg("all", "done"))); let mi = dummy_meta_item_list!(all, [a, b]); @@ -625,13 +622,12 @@ mod test { #[test] fn test_parse_err() { with_globals(|| { - let node = LitKind::Bool(false); - let (token, suffix) = node.lit_token(); - let mi = MetaItem { - path: Path::from_ident(Ident::from_str("foo")), - node: MetaItemKind::NameValue(Lit { node, token, suffix, span: DUMMY_SP }), - span: DUMMY_SP, - }; + let mi = attr::mk_name_value_item( + DUMMY_SP, + Ident::from_str("foo"), + LitKind::Bool(false), + DUMMY_SP, + ); assert!(Cfg::parse(&mi).is_err()); let mi = dummy_meta_item_list!(not, [a, b]); diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index e23c18266519..c122e1994e74 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -14,7 +14,7 @@ pub use StabilityLevel::*; use crate::ast; use crate::ast::{AttrId, Attribute, AttrStyle, Name, Ident, Path, PathSegment}; use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem}; -use crate::ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind, GenericParam}; +use crate::ast::{Lit, LitKind, Expr, Item, Local, Stmt, StmtKind, GenericParam}; use crate::mut_visit::visit_clobber; use crate::source_map::{BytePos, Spanned, dummy_spanned}; use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; @@ -27,9 +27,11 @@ use crate::ThinVec; use crate::tokenstream::{TokenStream, TokenTree, DelimSpan}; use crate::GLOBALS; +use errors::Handler; use log::debug; use syntax_pos::{FileName, Span}; +use std::ascii; use std::iter; use std::ops::DerefMut; @@ -350,14 +352,13 @@ impl Attribute { /* Constructors */ pub fn mk_name_value_item_str(ident: Ident, value: Spanned) -> MetaItem { - let node = LitKind::Str(value.node, ast::StrStyle::Cooked); - let (token, suffix) = node.lit_token(); - let value = Lit { node, token, suffix, span: value.span }; - mk_name_value_item(ident.span.to(value.span), ident, value) + let lit_kind = LitKind::Str(value.node, ast::StrStyle::Cooked); + mk_name_value_item(ident.span.to(value.span), ident, lit_kind, value.span) } -pub fn mk_name_value_item(span: Span, ident: Ident, value: Lit) -> MetaItem { - MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::NameValue(value) } +pub fn mk_name_value_item(span: Span, ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem { + let lit = Lit::from_lit_kind(lit_kind, lit_span); + MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::NameValue(lit) } } pub fn mk_list_item(span: Span, ident: Ident, items: Vec) -> MetaItem { @@ -419,9 +420,8 @@ pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute { let style = doc_comment_style(&text.as_str()); - let node = LitKind::Str(text, ast::StrStyle::Cooked); - let (token, suffix) = node.lit_token(); - let lit = Lit { node, token, suffix, span }; + let lit_kind = LitKind::Str(text, ast::StrStyle::Cooked); + let lit = Lit::from_lit_kind(lit_kind, span); Attribute { id, style, @@ -565,9 +565,7 @@ impl MetaItemKind { Some(TokenTree::Token(_, token::Eq)) => { tokens.next(); return if let Some(TokenTree::Token(span, token)) = tokens.next() { - LitKind::from_token(token).map(|(node, token, suffix)| { - MetaItemKind::NameValue(Lit { node, token, suffix, span }) - }) + Lit::from_token(&token, span, None).map(MetaItemKind::NameValue) } else { None }; @@ -612,9 +610,9 @@ impl NestedMetaItem { where I: Iterator, { if let Some(TokenTree::Token(span, token)) = tokens.peek().cloned() { - if let Some((node, token, suffix)) = LitKind::from_token(token) { + if let Some(lit) = Lit::from_token(&token, span, None) { tokens.next(); - return Some(NestedMetaItem::Literal(Lit { node, token, suffix, span })); + return Some(NestedMetaItem::Literal(lit)); } } @@ -624,21 +622,19 @@ impl NestedMetaItem { impl Lit { crate fn tokens(&self) -> TokenStream { - TokenTree::Token(self.span, self.node.token()).into() + let token = match self.token { + token::Bool(symbol) => Token::Ident(Ident::with_empty_ctxt(symbol), false), + token => Token::Literal(token, self.suffix), + }; + TokenTree::Token(self.span, token).into() } } impl LitKind { - fn token(&self) -> Token { - match self.lit_token() { - (token::Bool(symbol), _) => Token::Ident(Ident::with_empty_ctxt(symbol), false), - (lit, suffix) => Token::Literal(lit, suffix), - } - } - - pub fn lit_token(&self) -> (token::Lit, Option) { - use std::ascii; - + /// Attempts to recover a token from semantic literal. + /// This function is used when the original token doesn't exist (e.g. the literal is created + /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing). + pub fn to_lit_token(&self) -> (token::Lit, Option) { match *self { LitKind::Str(string, ast::StrStyle::Cooked) => { let escaped = string.as_str().escape_default().to_string(); @@ -679,29 +675,45 @@ impl LitKind { LitKind::Err(val) => (token::Lit::Err(val), None), } } +} - fn from_token(token: Token) -> Option<(LitKind, token::Lit, Option)> { - match token { - Token::Ident(ident, false) if ident.name == keywords::True.name() => - Some((LitKind::Bool(true), token::Bool(ident.name), None)), - Token::Ident(ident, false) if ident.name == keywords::False.name() => - Some((LitKind::Bool(false), token::Bool(ident.name), None)), - Token::Interpolated(nt) => match *nt { - token::NtExpr(ref v) | token::NtLiteral(ref v) => match v.node { - ExprKind::Lit(ref lit) => Some((lit.node.clone(), lit.token, lit.suffix)), - _ => None, - }, - _ => None, - }, - Token::Literal(lit, suf) => { - let (suffix_illegal, result) = parse::lit_token(lit, suf, None); - if result.is_none() || suffix_illegal && suf.is_some() { - return None; +impl Lit { + /// Converts literal token with a suffix into an AST literal. + /// Works speculatively and may return `None` is diagnostic handler is not passed. + /// If diagnostic handler is passed, may return `Some`, + /// possibly after reporting non-fatal errors and recovery, or `None` for irrecoverable errors. + crate fn from_token( + token: &token::Token, + span: Span, + diag: Option<(Span, &Handler)>, + ) -> Option { + let (token, suffix) = match *token { + token::Ident(ident, false) if ident.name == keywords::True.name() || + ident.name == keywords::False.name() => + (token::Bool(ident.name), None), + token::Literal(token, suffix) => + (token, suffix), + token::Interpolated(ref nt) => { + if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt { + if let ast::ExprKind::Lit(lit) = &expr.node { + return Some(lit.clone()); + } } - Some((result.unwrap(), lit, suf)) + return None; } - _ => None, - } + _ => return None, + }; + + let node = LitKind::from_lit_token(token, suffix, diag)?; + Some(Lit { node, token, suffix, span }) + } + + /// Attempts to recover an AST literal from semantic literal. + /// This function is used when the original token doesn't exist (e.g. the literal is created + /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing). + pub fn from_lit_kind(node: LitKind, span: Span) -> Lit { + let (token, suffix) = node.to_lit_token(); + Lit { node, token, suffix, span } } } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 0f9977e85038..d24106f697e1 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -697,9 +697,9 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.expr_struct(span, self.path_ident(span, id), fields) } - fn expr_lit(&self, span: Span, node: ast::LitKind) -> P { - let (token, suffix) = node.lit_token(); - self.expr(span, ast::ExprKind::Lit(ast::Lit { node, token, suffix, span })) + fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P { + let lit = ast::Lit::from_lit_kind(lit_kind, span); + self.expr(span, ast::ExprKind::Lit(lit)) } fn expr_usize(&self, span: Span, i: usize) -> P { self.expr_lit(span, ast::LitKind::Int(i as u128, @@ -1165,11 +1165,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> { attr::mk_list_item(sp, Ident::with_empty_ctxt(name).with_span_pos(sp), mis) } - fn meta_name_value(&self, span: Span, name: ast::Name, node: ast::LitKind) + fn meta_name_value(&self, span: Span, name: ast::Name, lit_kind: ast::LitKind) -> ast::MetaItem { - let (token, suffix) = node.lit_token(); attr::mk_name_value_item(span, Ident::with_empty_ctxt(name).with_span_pos(span), - ast::Lit { node, token, suffix, span }) + lit_kind, span) } fn item_use(&self, sp: Span, diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 4d4e99009a9d..868b344c0658 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -1,11 +1,11 @@ //! The main parser interface. -use crate::ast::{self, CrateConfig, NodeId}; +use crate::ast::{self, CrateConfig, LitKind, NodeId}; use crate::early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId}; use crate::source_map::{SourceMap, FilePathMapping}; use crate::feature_gate::UnstableFeatures; use crate::parse::parser::Parser; -use crate::symbol::Symbol; +use crate::symbol::{keywords, Symbol}; use crate::syntax::parse::parser::emit_unclosed_delims; use crate::tokenstream::{TokenStream, TokenTree}; use crate::diagnostics::plugin::ErrorMap; @@ -371,97 +371,151 @@ macro_rules! err { } } -crate fn lit_token(lit: token::Lit, suf: Option, diag: Option<(Span, &Handler)>) - -> (bool /* suffix illegal? */, Option) { - use ast::LitKind; - - match lit { - token::Bool(_) => panic!("literal token contains `Lit::Bool`"), - token::Byte(i) => { - let lit_kind = match unescape_byte(&i.as_str()) { - Ok(c) => LitKind::Byte(c), - Err(_) => LitKind::Err(i), +crate fn expect_no_suffix(sp: Span, diag: &Handler, kind: &str, suffix: Option) { + match suffix { + None => {/* everything ok */} + Some(suf) => { + let text = suf.as_str(); + if text.is_empty() { + diag.span_bug(sp, "found empty literal suffix in Some") + } + let mut err = if kind == "a tuple index" && + ["i32", "u32", "isize", "usize"].contains(&text.to_string().as_str()) + { + // #59553: warn instead of reject out of hand to allow the fix to percolate + // through the ecosystem when people fix their macros + let mut err = diag.struct_span_warn( + sp, + &format!("suffixes on {} are invalid", kind), + ); + err.note(&format!( + "`{}` is *temporarily* accepted on tuple index fields as it was \ + incorrectly accepted on stable for a few releases", + text, + )); + err.help( + "on proc macros, you'll want to use `syn::Index::from` or \ + `proc_macro::Literal::*_unsuffixed` for code that will desugar \ + to tuple field access", + ); + err.note( + "for more context, see https://github.com/rust-lang/rust/issues/60210", + ); + err + } else { + diag.struct_span_err(sp, &format!("suffixes on {} are invalid", kind)) }; - (true, Some(lit_kind)) - }, - token::Char(i) => { - let lit_kind = match unescape_char(&i.as_str()) { - Ok(c) => LitKind::Char(c), - Err(_) => LitKind::Err(i), - }; - (true, Some(lit_kind)) - }, - token::Err(i) => (true, Some(LitKind::Err(i))), + err.span_label(sp, format!("invalid suffix `{}`", text)); + err.emit(); + } + } +} - // There are some valid suffixes for integer and float literals, - // so all the handling is done internally. - token::Integer(s) => (false, integer_lit(&s.as_str(), suf, diag)), - token::Float(s) => (false, float_lit(&s.as_str(), suf, diag)), +impl LitKind { + /// Converts literal token with a suffix into a semantic literal. + /// Works speculatively and may return `None` is diagnostic handler is not passed. + /// If diagnostic handler is passed, always returns `Some`, + /// possibly after reporting non-fatal errors and recovery. + crate fn from_lit_token( + lit: token::Lit, + suf: Option, + diag: Option<(Span, &Handler)> + ) -> Option { + if suf.is_some() && !lit.may_have_suffix() { + err!(diag, |span, diag| { + expect_no_suffix(span, diag, &format!("a {}", lit.literal_name()), suf) + }); + } - token::Str_(mut sym) => { - // If there are no characters requiring special treatment we can - // reuse the symbol from the Token. Otherwise, we must generate a - // new symbol because the string in the LitKind is different to the - // string in the Token. - let mut has_error = false; - let s = &sym.as_str(); - if s.as_bytes().iter().any(|&c| c == b'\\' || c == b'\r') { - let mut buf = String::with_capacity(s.len()); - unescape_str(s, &mut |_, unescaped_char| { - match unescaped_char { + Some(match lit { + token::Bool(i) => { + assert!(i == keywords::True.name() || i == keywords::False.name()); + LitKind::Bool(i == keywords::True.name()) + } + token::Byte(i) => { + match unescape_byte(&i.as_str()) { + Ok(c) => LitKind::Byte(c), + Err(_) => LitKind::Err(i), + } + }, + token::Char(i) => { + match unescape_char(&i.as_str()) { + Ok(c) => LitKind::Char(c), + Err(_) => LitKind::Err(i), + } + }, + token::Err(i) => LitKind::Err(i), + + // There are some valid suffixes for integer and float literals, + // so all the handling is done internally. + token::Integer(s) => return integer_lit(&s.as_str(), suf, diag), + token::Float(s) => return float_lit(&s.as_str(), suf, diag), + + token::Str_(mut sym) => { + // If there are no characters requiring special treatment we can + // reuse the symbol from the Token. Otherwise, we must generate a + // new symbol because the string in the LitKind is different to the + // string in the Token. + let mut has_error = false; + let s = &sym.as_str(); + if s.as_bytes().iter().any(|&c| c == b'\\' || c == b'\r') { + let mut buf = String::with_capacity(s.len()); + unescape_str(s, &mut |_, unescaped_char| { + match unescaped_char { + Ok(c) => buf.push(c), + Err(_) => has_error = true, + } + }); + if has_error { + return Some(LitKind::Err(sym)); + } + sym = Symbol::intern(&buf) + } + + LitKind::Str(sym, ast::StrStyle::Cooked) + } + token::StrRaw(mut sym, n) => { + // Ditto. + let s = &sym.as_str(); + if s.contains('\r') { + sym = Symbol::intern(&raw_str_lit(s)); + } + LitKind::Str(sym, ast::StrStyle::Raw(n)) + } + token::ByteStr(i) => { + let s = &i.as_str(); + let mut buf = Vec::with_capacity(s.len()); + let mut has_error = false; + unescape_byte_str(s, &mut |_, unescaped_byte| { + match unescaped_byte { Ok(c) => buf.push(c), Err(_) => has_error = true, } }); if has_error { - return (true, Some(LitKind::Err(sym))); + return Some(LitKind::Err(i)); } - sym = Symbol::intern(&buf) + buf.shrink_to_fit(); + LitKind::ByteStr(Lrc::new(buf)) } - - (true, Some(LitKind::Str(sym, ast::StrStyle::Cooked))) - } - token::StrRaw(mut sym, n) => { - // Ditto. - let s = &sym.as_str(); - if s.contains('\r') { - sym = Symbol::intern(&raw_str_lit(s)); + token::ByteStrRaw(i, _) => { + LitKind::ByteStr(Lrc::new(i.to_string().into_bytes())) } - (true, Some(LitKind::Str(sym, ast::StrStyle::Raw(n)))) - } - token::ByteStr(i) => { - let s = &i.as_str(); - let mut buf = Vec::with_capacity(s.len()); - let mut has_error = false; - unescape_byte_str(s, &mut |_, unescaped_byte| { - match unescaped_byte { - Ok(c) => buf.push(c), - Err(_) => has_error = true, - } - }); - if has_error { - return (true, Some(LitKind::Err(i))); - } - buf.shrink_to_fit(); - (true, Some(LitKind::ByteStr(Lrc::new(buf)))) - } - token::ByteStrRaw(i, _) => { - (true, Some(LitKind::ByteStr(Lrc::new(i.to_string().into_bytes())))) - } + }) } } fn filtered_float_lit(data: Symbol, suffix: Option, diag: Option<(Span, &Handler)>) - -> Option { + -> Option { debug!("filtered_float_lit: {}, {:?}", data, suffix); let suffix = match suffix { Some(suffix) => suffix, - None => return Some(ast::LitKind::FloatUnsuffixed(data)), + None => return Some(LitKind::FloatUnsuffixed(data)), }; Some(match &*suffix.as_str() { - "f32" => ast::LitKind::Float(data, ast::FloatTy::F32), - "f64" => ast::LitKind::Float(data, ast::FloatTy::F64), + "f32" => LitKind::Float(data, ast::FloatTy::F32), + "f64" => LitKind::Float(data, ast::FloatTy::F64), suf => { err!(diag, |span, diag| { if suf.len() >= 2 && looks_like_width_suffix(&['f'], suf) { @@ -477,12 +531,12 @@ fn filtered_float_lit(data: Symbol, suffix: Option, diag: Option<(Span, } }); - ast::LitKind::FloatUnsuffixed(data) + LitKind::FloatUnsuffixed(data) } }) } fn float_lit(s: &str, suffix: Option, diag: Option<(Span, &Handler)>) - -> Option { + -> Option { debug!("float_lit: {:?}, {:?}", s, suffix); // FIXME #2252: bounds checking float literals is deferred until trans @@ -499,7 +553,7 @@ fn float_lit(s: &str, suffix: Option, diag: Option<(Span, &Handler)>) } fn integer_lit(s: &str, suffix: Option, diag: Option<(Span, &Handler)>) - -> Option { + -> Option { // s can only be ascii, byte indexing is fine // Strip underscores without allocating a new String unless necessary. @@ -595,7 +649,7 @@ fn integer_lit(s: &str, suffix: Option, diag: Option<(Span, &Handler)>) string was {:?}, the original suffix was {:?}", ty, base, s, orig, suffix); Some(match u128::from_str_radix(s, base) { - Ok(r) => ast::LitKind::Int(r, ty), + Ok(r) => LitKind::Int(r, ty), Err(_) => { // small bases are lexed as if they were base 10, e.g, the string // might be `0b10201`. This will cause the conversion above to fail, @@ -608,7 +662,7 @@ fn integer_lit(s: &str, suffix: Option, diag: Option<(Span, &Handler)>) if !already_errored { err!(diag, |span, diag| diag.span_err(span, "int literal is too large")); } - ast::LitKind::Int(0, ty) + LitKind::Int(0, ty) } }) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 8c0c2f4b6e28..b81f7be9c2c1 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -15,7 +15,7 @@ use crate::ast::{ForeignItem, ForeignItemKind, FunctionRetTy}; use crate::ast::{GenericParam, GenericParamKind}; use crate::ast::GenericArg; use crate::ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind}; -use crate::ast::{Label, Lifetime, Lit, LitKind}; +use crate::ast::{Label, Lifetime, Lit}; use crate::ast::{Local, LocalSource}; use crate::ast::MacStmtStyle; use crate::ast::{Mac, Mac_, MacDelimiter}; @@ -46,7 +46,7 @@ use crate::ptr::P; use crate::parse::PResult; use crate::ThinVec; use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint}; -use crate::symbol::{Symbol, keywords}; +use crate::symbol::{keywords, Symbol}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError}; use rustc_target::spec::abi::{self, Abi}; @@ -1109,43 +1109,7 @@ impl<'a> Parser<'a> { } fn expect_no_suffix(&self, sp: Span, kind: &str, suffix: Option) { - match suffix { - None => {/* everything ok */} - Some(suf) => { - let text = suf.as_str(); - if text.is_empty() { - self.span_bug(sp, "found empty literal suffix in Some") - } - let mut err = if kind == "a tuple index" && - ["i32", "u32", "isize", "usize"].contains(&text.to_string().as_str()) - { - // #59553: warn instead of reject out of hand to allow the fix to percolate - // through the ecosystem when people fix their macros - let mut err = self.struct_span_warn( - sp, - &format!("suffixes on {} are invalid", kind), - ); - err.note(&format!( - "`{}` is *temporarily* accepted on tuple index fields as it was \ - incorrectly accepted on stable for a few releases", - text, - )); - err.help( - "on proc macros, you'll want to use `syn::Index::from` or \ - `proc_macro::Literal::*_unsuffixed` for code that will desugar \ - to tuple field access", - ); - err.note( - "for more context, see https://github.com/rust-lang/rust/issues/60210", - ); - err - } else { - self.struct_span_err(sp, &format!("suffixes on {} are invalid", kind)) - }; - err.span_label(sp, format!("invalid suffix `{}`", text)); - err.emit(); - } - } + parse::expect_no_suffix(sp, &self.sess.span_diagnostic, kind, suffix) } /// Attempts to consume a `<`. If `<<` is seen, replaces it with a single @@ -1452,9 +1416,6 @@ impl<'a> Parser<'a> { crate fn struct_span_err>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> { self.sess.span_diagnostic.struct_span_err(sp, m) } - fn struct_span_warn>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> { - self.sess.span_diagnostic.struct_span_warn(sp, m) - } crate fn span_bug>(&self, sp: S, m: &str) -> ! { self.sess.span_diagnostic.span_bug(sp, m) } @@ -2069,85 +2030,45 @@ impl<'a> Parser<'a> { } } - /// Matches `token_lit = LIT_INTEGER | ...`. - fn parse_lit_token(&mut self) -> PResult<'a, (LitKind, token::Lit, Option)> { - let out = match self.token { - token::Interpolated(ref nt) => match **nt { - token::NtExpr(ref v) | token::NtLiteral(ref v) => match v.node { - ExprKind::Lit(ref lit) => { (lit.node.clone(), lit.token, lit.suffix) } - _ => { return self.unexpected_last(&self.token); } - }, - _ => { return self.unexpected_last(&self.token); } - }, - token::Literal(lit, suf) => { - let diag = Some((self.span, &self.sess.span_diagnostic)); - let (suffix_illegal, result) = parse::lit_token(lit, suf, diag); - - if suffix_illegal { - let sp = self.span; - self.expect_no_suffix(sp, &format!("a {}", lit.literal_name()), suf) - } - - (result.unwrap(), lit, suf) - } - token::Dot if self.look_ahead(1, |t| match t { - token::Literal(token::Lit::Integer(_) , _) => true, - _ => false, - }) => { // recover from `let x = .4;` - let lo = self.span; - self.bump(); - if let token::Literal( - token::Lit::Integer(val), - suffix, - ) = self.token { - let float_suffix = suffix.and_then(|s| { - let s = s.as_str(); - if s == "f32" { - Some("f32") - } else if s == "f64" { - Some("f64") - } else { - None - } - }).unwrap_or(""); - self.bump(); - let sp = lo.to(self.prev_span); - let mut err = self.diagnostic() - .struct_span_err(sp, "float literals must have an integer part"); - err.span_suggestion( - sp, - "must have an integer part", - format!("0.{}{}", val, float_suffix), - Applicability::MachineApplicable, - ); - err.emit(); - return Ok((match float_suffix { - "f32" => ast::LitKind::Float(val, ast::FloatTy::F32), - "f64" => ast::LitKind::Float(val, ast::FloatTy::F64), - _ => ast::LitKind::FloatUnsuffixed(val), - }, token::Float(val), suffix)); - } else { - unreachable!(); - }; - } - _ => { return self.unexpected_last(&self.token); } - }; - - self.bump(); - Ok(out) - } - /// Matches `lit = true | false | token_lit`. crate fn parse_lit(&mut self) -> PResult<'a, Lit> { - let lo = self.span; - let (node, token, suffix) = if self.eat_keyword(keywords::True) { - (LitKind::Bool(true), token::Bool(keywords::True.name()), None) - } else if self.eat_keyword(keywords::False) { - (LitKind::Bool(false), token::Bool(keywords::False.name()), None) - } else { - self.parse_lit_token()? - }; - Ok(Lit { node, token, suffix, span: lo.to(self.prev_span) }) + let diag = Some((self.span, &self.sess.span_diagnostic)); + if let Some(lit) = Lit::from_token(&self.token, self.span, diag) { + self.bump(); + return Ok(lit); + } else if self.token == token::Dot { + // Recover `.4` as `0.4`. + let recovered = self.look_ahead(1, |t| { + if let token::Literal(token::Integer(val), suf) = *t { + let next_span = self.look_ahead_span(1); + if self.span.hi() == next_span.lo() { + let sym = String::from("0.") + &val.as_str(); + let token = token::Literal(token::Float(Symbol::intern(&sym)), suf); + return Some((token, self.span.to(next_span))); + } + } + None + }); + if let Some((token, span)) = recovered { + self.diagnostic() + .struct_span_err(span, "float literals must have an integer part") + .span_suggestion( + span, + "must have an integer part", + pprust::token_to_string(&token), + Applicability::MachineApplicable, + ) + .emit(); + let diag = Some((span, &self.sess.span_diagnostic)); + if let Some(lit) = Lit::from_token(&token, span, diag) { + self.bump(); + self.bump(); + return Ok(lit); + } + } + } + + self.unexpected_last(&self.token) } /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`). diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 48a949257ffb..0c2ea70aa20c 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -90,6 +90,13 @@ impl Lit { } } + crate fn may_have_suffix(&self) -> bool { + match *self { + Integer(..) | Float(..) => true, + _ => false, + } + } + // See comments in `Nonterminal::to_tokenstream` for why we care about // *probably* equal here rather than actual equality fn probably_equal_for_proc_macro(&self, other: &Lit) -> bool { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index fa16a2b200ff..0e8ac6c35b9b 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -162,7 +162,7 @@ fn binop_to_string(op: BinOpToken) -> &'static str { } } -fn literal_to_string(lit: token::Lit, suffix: Option) -> String { +pub fn literal_to_string(lit: token::Lit, suffix: Option) -> String { let mut out = match lit { token::Byte(b) => format!("b'{}'", b), token::Char(c) => format!("'{}'", c), diff --git a/src/test/ui/malformed/malformed-interpolated.rs b/src/test/ui/malformed/malformed-interpolated.rs index e452435968ba..7c4ca3c017e7 100644 --- a/src/test/ui/malformed/malformed-interpolated.rs +++ b/src/test/ui/malformed/malformed-interpolated.rs @@ -2,8 +2,7 @@ macro_rules! check { ($expr: expr) => ( - #[my_attr = $expr] //~ ERROR suffixed literals are not allowed in attributes - //~| ERROR unexpected token: `-0` + #[my_attr = $expr] //~ ERROR unexpected token: `-0` //~| ERROR unexpected token: `0 + 0` use main as _; ); @@ -11,7 +10,7 @@ macro_rules! check { check!("0"); // OK check!(0); // OK -check!(0u8); // ERROR, see above +check!(0u8); //~ ERROR suffixed literals are not allowed in attributes check!(-0); // ERROR, see above check!(0 + 0); // ERROR, see above diff --git a/src/test/ui/malformed/malformed-interpolated.stderr b/src/test/ui/malformed/malformed-interpolated.stderr index efeede0148da..bc2146e409d4 100644 --- a/src/test/ui/malformed/malformed-interpolated.stderr +++ b/src/test/ui/malformed/malformed-interpolated.stderr @@ -1,11 +1,8 @@ error: suffixed literals are not allowed in attributes - --> $DIR/malformed-interpolated.rs:5:21 + --> $DIR/malformed-interpolated.rs:13:8 | -LL | #[my_attr = $expr] - | ^^^^^ -... -LL | check!(0u8); // ERROR, see above - | ------------ in this macro invocation +LL | check!(0u8); + | ^^^ | = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). From 3f064cae3d9d0d33951a44c30d83696563244572 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 11 May 2019 02:31:34 +0300 Subject: [PATCH 096/239] Move literal parsing code into a separate file Remove some dead code --- src/libsyntax/attr/mod.rs | 99 ---- src/libsyntax/parse/classify.rs | 13 - src/libsyntax/parse/lexer/mod.rs | 19 +- src/libsyntax/parse/literal.rs | 487 ++++++++++++++++++ src/libsyntax/parse/mod.rs | 352 +------------ src/libsyntax/parse/parser.rs | 56 +- src/test/ui/attr-eq-token-tree.stderr | 4 +- ...sive_range_pattern_syntax_collision.stderr | 4 +- ...ive_range_pattern_syntax_collision2.stderr | 4 +- src/test/ui/macros/macro-attribute.stderr | 4 +- .../malformed/malformed-interpolated.stderr | 8 +- src/test/ui/parser/attr-bad-meta-2.stderr | 4 +- src/test/ui/parser/pat-tuple-5.stderr | 4 +- 13 files changed, 521 insertions(+), 537 deletions(-) create mode 100644 src/libsyntax/parse/literal.rs diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index c122e1994e74..07e4bbf78ffd 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -27,11 +27,9 @@ use crate::ThinVec; use crate::tokenstream::{TokenStream, TokenTree, DelimSpan}; use crate::GLOBALS; -use errors::Handler; use log::debug; use syntax_pos::{FileName, Span}; -use std::ascii; use std::iter; use std::ops::DerefMut; @@ -620,103 +618,6 @@ impl NestedMetaItem { } } -impl Lit { - crate fn tokens(&self) -> TokenStream { - let token = match self.token { - token::Bool(symbol) => Token::Ident(Ident::with_empty_ctxt(symbol), false), - token => Token::Literal(token, self.suffix), - }; - TokenTree::Token(self.span, token).into() - } -} - -impl LitKind { - /// Attempts to recover a token from semantic literal. - /// This function is used when the original token doesn't exist (e.g. the literal is created - /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing). - pub fn to_lit_token(&self) -> (token::Lit, Option) { - match *self { - LitKind::Str(string, ast::StrStyle::Cooked) => { - let escaped = string.as_str().escape_default().to_string(); - (token::Lit::Str_(Symbol::intern(&escaped)), None) - } - LitKind::Str(string, ast::StrStyle::Raw(n)) => { - (token::Lit::StrRaw(string, n), None) - } - LitKind::ByteStr(ref bytes) => { - let string = bytes.iter().cloned().flat_map(ascii::escape_default) - .map(Into::::into).collect::(); - (token::Lit::ByteStr(Symbol::intern(&string)), None) - } - LitKind::Byte(byte) => { - let string: String = ascii::escape_default(byte).map(Into::::into).collect(); - (token::Lit::Byte(Symbol::intern(&string)), None) - } - LitKind::Char(ch) => { - let string: String = ch.escape_default().map(Into::::into).collect(); - (token::Lit::Char(Symbol::intern(&string)), None) - } - LitKind::Int(n, ty) => { - let suffix = match ty { - ast::LitIntType::Unsigned(ty) => Some(Symbol::intern(ty.ty_to_string())), - ast::LitIntType::Signed(ty) => Some(Symbol::intern(ty.ty_to_string())), - ast::LitIntType::Unsuffixed => None, - }; - (token::Lit::Integer(Symbol::intern(&n.to_string())), suffix) - } - LitKind::Float(symbol, ty) => { - (token::Lit::Float(symbol), Some(Symbol::intern(ty.ty_to_string()))) - } - LitKind::FloatUnsuffixed(symbol) => (token::Lit::Float(symbol), None), - LitKind::Bool(value) => { - let kw = if value { keywords::True } else { keywords::False }; - (token::Lit::Bool(kw.name()), None) - } - LitKind::Err(val) => (token::Lit::Err(val), None), - } - } -} - -impl Lit { - /// Converts literal token with a suffix into an AST literal. - /// Works speculatively and may return `None` is diagnostic handler is not passed. - /// If diagnostic handler is passed, may return `Some`, - /// possibly after reporting non-fatal errors and recovery, or `None` for irrecoverable errors. - crate fn from_token( - token: &token::Token, - span: Span, - diag: Option<(Span, &Handler)>, - ) -> Option { - let (token, suffix) = match *token { - token::Ident(ident, false) if ident.name == keywords::True.name() || - ident.name == keywords::False.name() => - (token::Bool(ident.name), None), - token::Literal(token, suffix) => - (token, suffix), - token::Interpolated(ref nt) => { - if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt { - if let ast::ExprKind::Lit(lit) = &expr.node { - return Some(lit.clone()); - } - } - return None; - } - _ => return None, - }; - - let node = LitKind::from_lit_token(token, suffix, diag)?; - Some(Lit { node, token, suffix, span }) - } - - /// Attempts to recover an AST literal from semantic literal. - /// This function is used when the original token doesn't exist (e.g. the literal is created - /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing). - pub fn from_lit_kind(node: LitKind, span: Span) -> Lit { - let (token, suffix) = node.to_lit_token(); - Lit { node, token, suffix, span } - } -} - pub trait HasAttrs: Sized { fn attrs(&self) -> &[ast::Attribute]; fn visit_attrs)>(&mut self, f: F); diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index b4103440e357..dfd6f451c28d 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -25,16 +25,3 @@ pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool { _ => true, } } - -/// this statement requires a semicolon after it. -/// note that in one case (`stmt_semi`), we've already -/// seen the semicolon, and thus don't need another. -pub fn stmt_ends_with_semi(stmt: &ast::StmtKind) -> bool { - match *stmt { - ast::StmtKind::Local(_) => true, - ast::StmtKind::Expr(ref e) => expr_requires_semi_to_be_stmt(e), - ast::StmtKind::Item(_) | - ast::StmtKind::Semi(..) | - ast::StmtKind::Mac(..) => false, - } -} diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 2882acb0e780..e76605cde32a 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -262,18 +262,6 @@ impl<'a> StringReader<'a> { } } - pub fn new(sess: &'a ParseSess, - source_file: Lrc, - override_span: Option) -> Self { - let mut sr = StringReader::new_raw(sess, source_file, override_span); - if sr.advance_token().is_err() { - sr.emit_fatal_errors(); - FatalError.raise(); - } - - sr - } - pub fn new_or_buffered_errs(sess: &'a ParseSess, source_file: Lrc, override_span: Option) -> Result> { @@ -1627,7 +1615,12 @@ mod tests { teststr: String) -> StringReader<'a> { let sf = sm.new_source_file(PathBuf::from(teststr.clone()).into(), teststr); - StringReader::new(sess, sf, None) + let mut sr = StringReader::new_raw(sess, sf, None); + if sr.advance_token().is_err() { + sr.emit_fatal_errors(); + FatalError.raise(); + } + sr } #[test] diff --git a/src/libsyntax/parse/literal.rs b/src/libsyntax/parse/literal.rs new file mode 100644 index 000000000000..2c7ba13fbef8 --- /dev/null +++ b/src/libsyntax/parse/literal.rs @@ -0,0 +1,487 @@ +//! Code related to parsing literals. + +use crate::ast::{self, Ident, Lit, LitKind}; +use crate::parse::parser::Parser; +use crate::parse::PResult; +use crate::parse::token::{self, Token}; +use crate::parse::unescape::{unescape_str, unescape_char, unescape_byte_str, unescape_byte}; +use crate::print::pprust; +use crate::symbol::{keywords, Symbol}; +use crate::tokenstream::{TokenStream, TokenTree}; + +use errors::{Applicability, Handler}; +use log::debug; +use rustc_data_structures::sync::Lrc; +use syntax_pos::Span; + +use std::ascii; + +macro_rules! err { + ($opt_diag:expr, |$span:ident, $diag:ident| $($body:tt)*) => { + match $opt_diag { + Some(($span, $diag)) => { $($body)* } + None => return None, + } + } +} + +impl LitKind { + /// Converts literal token with a suffix into a semantic literal. + /// Works speculatively and may return `None` is diagnostic handler is not passed. + /// If diagnostic handler is passed, always returns `Some`, + /// possibly after reporting non-fatal errors and recovery. + fn from_lit_token( + lit: token::Lit, + suf: Option, + diag: Option<(Span, &Handler)> + ) -> Option { + if suf.is_some() && !lit.may_have_suffix() { + err!(diag, |span, diag| { + expect_no_suffix(span, diag, &format!("a {}", lit.literal_name()), suf) + }); + } + + Some(match lit { + token::Bool(i) => { + assert!(i == keywords::True.name() || i == keywords::False.name()); + LitKind::Bool(i == keywords::True.name()) + } + token::Byte(i) => { + match unescape_byte(&i.as_str()) { + Ok(c) => LitKind::Byte(c), + Err(_) => LitKind::Err(i), + } + }, + token::Char(i) => { + match unescape_char(&i.as_str()) { + Ok(c) => LitKind::Char(c), + Err(_) => LitKind::Err(i), + } + }, + token::Err(i) => LitKind::Err(i), + + // There are some valid suffixes for integer and float literals, + // so all the handling is done internally. + token::Integer(s) => return integer_lit(&s.as_str(), suf, diag), + token::Float(s) => return float_lit(&s.as_str(), suf, diag), + + token::Str_(mut sym) => { + // If there are no characters requiring special treatment we can + // reuse the symbol from the Token. Otherwise, we must generate a + // new symbol because the string in the LitKind is different to the + // string in the Token. + let mut has_error = false; + let s = &sym.as_str(); + if s.as_bytes().iter().any(|&c| c == b'\\' || c == b'\r') { + let mut buf = String::with_capacity(s.len()); + unescape_str(s, &mut |_, unescaped_char| { + match unescaped_char { + Ok(c) => buf.push(c), + Err(_) => has_error = true, + } + }); + if has_error { + return Some(LitKind::Err(sym)); + } + sym = Symbol::intern(&buf) + } + + LitKind::Str(sym, ast::StrStyle::Cooked) + } + token::StrRaw(mut sym, n) => { + // Ditto. + let s = &sym.as_str(); + if s.contains('\r') { + sym = Symbol::intern(&raw_str_lit(s)); + } + LitKind::Str(sym, ast::StrStyle::Raw(n)) + } + token::ByteStr(i) => { + let s = &i.as_str(); + let mut buf = Vec::with_capacity(s.len()); + let mut has_error = false; + unescape_byte_str(s, &mut |_, unescaped_byte| { + match unescaped_byte { + Ok(c) => buf.push(c), + Err(_) => has_error = true, + } + }); + if has_error { + return Some(LitKind::Err(i)); + } + buf.shrink_to_fit(); + LitKind::ByteStr(Lrc::new(buf)) + } + token::ByteStrRaw(i, _) => { + LitKind::ByteStr(Lrc::new(i.to_string().into_bytes())) + } + }) + } + + /// Attempts to recover a token from semantic literal. + /// This function is used when the original token doesn't exist (e.g. the literal is created + /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing). + pub fn to_lit_token(&self) -> (token::Lit, Option) { + match *self { + LitKind::Str(string, ast::StrStyle::Cooked) => { + let escaped = string.as_str().escape_default().to_string(); + (token::Lit::Str_(Symbol::intern(&escaped)), None) + } + LitKind::Str(string, ast::StrStyle::Raw(n)) => { + (token::Lit::StrRaw(string, n), None) + } + LitKind::ByteStr(ref bytes) => { + let string = bytes.iter().cloned().flat_map(ascii::escape_default) + .map(Into::::into).collect::(); + (token::Lit::ByteStr(Symbol::intern(&string)), None) + } + LitKind::Byte(byte) => { + let string: String = ascii::escape_default(byte).map(Into::::into).collect(); + (token::Lit::Byte(Symbol::intern(&string)), None) + } + LitKind::Char(ch) => { + let string: String = ch.escape_default().map(Into::::into).collect(); + (token::Lit::Char(Symbol::intern(&string)), None) + } + LitKind::Int(n, ty) => { + let suffix = match ty { + ast::LitIntType::Unsigned(ty) => Some(Symbol::intern(ty.ty_to_string())), + ast::LitIntType::Signed(ty) => Some(Symbol::intern(ty.ty_to_string())), + ast::LitIntType::Unsuffixed => None, + }; + (token::Lit::Integer(Symbol::intern(&n.to_string())), suffix) + } + LitKind::Float(symbol, ty) => { + (token::Lit::Float(symbol), Some(Symbol::intern(ty.ty_to_string()))) + } + LitKind::FloatUnsuffixed(symbol) => (token::Lit::Float(symbol), None), + LitKind::Bool(value) => { + let kw = if value { keywords::True } else { keywords::False }; + (token::Lit::Bool(kw.name()), None) + } + LitKind::Err(val) => (token::Lit::Err(val), None), + } + } +} + +impl Lit { + /// Converts literal token with a suffix into an AST literal. + /// Works speculatively and may return `None` is diagnostic handler is not passed. + /// If diagnostic handler is passed, may return `Some`, + /// possibly after reporting non-fatal errors and recovery, or `None` for irrecoverable errors. + crate fn from_token( + token: &token::Token, + span: Span, + diag: Option<(Span, &Handler)>, + ) -> Option { + let (token, suffix) = match *token { + token::Ident(ident, false) if ident.name == keywords::True.name() || + ident.name == keywords::False.name() => + (token::Bool(ident.name), None), + token::Literal(token, suffix) => + (token, suffix), + token::Interpolated(ref nt) => { + if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt { + if let ast::ExprKind::Lit(lit) = &expr.node { + return Some(lit.clone()); + } + } + return None; + } + _ => return None, + }; + + let node = LitKind::from_lit_token(token, suffix, diag)?; + Some(Lit { node, token, suffix, span }) + } + + /// Attempts to recover an AST literal from semantic literal. + /// This function is used when the original token doesn't exist (e.g. the literal is created + /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing). + pub fn from_lit_kind(node: LitKind, span: Span) -> Lit { + let (token, suffix) = node.to_lit_token(); + Lit { node, token, suffix, span } + } + + /// Losslessly convert an AST literal into a token stream. + crate fn tokens(&self) -> TokenStream { + let token = match self.token { + token::Bool(symbol) => Token::Ident(Ident::with_empty_ctxt(symbol), false), + token => Token::Literal(token, self.suffix), + }; + TokenTree::Token(self.span, token).into() + } +} + +impl<'a> Parser<'a> { + /// Matches `lit = true | false | token_lit`. + crate fn parse_lit(&mut self) -> PResult<'a, Lit> { + let diag = Some((self.span, &self.sess.span_diagnostic)); + if let Some(lit) = Lit::from_token(&self.token, self.span, diag) { + self.bump(); + return Ok(lit); + } else if self.token == token::Dot { + // Recover `.4` as `0.4`. + let recovered = self.look_ahead(1, |t| { + if let token::Literal(token::Integer(val), suf) = *t { + let next_span = self.look_ahead_span(1); + if self.span.hi() == next_span.lo() { + let sym = String::from("0.") + &val.as_str(); + let token = token::Literal(token::Float(Symbol::intern(&sym)), suf); + return Some((token, self.span.to(next_span))); + } + } + None + }); + if let Some((token, span)) = recovered { + self.diagnostic() + .struct_span_err(span, "float literals must have an integer part") + .span_suggestion( + span, + "must have an integer part", + pprust::token_to_string(&token), + Applicability::MachineApplicable, + ) + .emit(); + let diag = Some((span, &self.sess.span_diagnostic)); + if let Some(lit) = Lit::from_token(&token, span, diag) { + self.bump(); + self.bump(); + return Ok(lit); + } + } + } + + Err(self.span_fatal(self.span, &format!("unexpected token: {}", self.this_token_descr()))) + } +} + +crate fn expect_no_suffix(sp: Span, diag: &Handler, kind: &str, suffix: Option) { + match suffix { + None => {/* everything ok */} + Some(suf) => { + let text = suf.as_str(); + if text.is_empty() { + diag.span_bug(sp, "found empty literal suffix in Some") + } + let mut err = if kind == "a tuple index" && + ["i32", "u32", "isize", "usize"].contains(&text.to_string().as_str()) + { + // #59553: warn instead of reject out of hand to allow the fix to percolate + // through the ecosystem when people fix their macros + let mut err = diag.struct_span_warn( + sp, + &format!("suffixes on {} are invalid", kind), + ); + err.note(&format!( + "`{}` is *temporarily* accepted on tuple index fields as it was \ + incorrectly accepted on stable for a few releases", + text, + )); + err.help( + "on proc macros, you'll want to use `syn::Index::from` or \ + `proc_macro::Literal::*_unsuffixed` for code that will desugar \ + to tuple field access", + ); + err.note( + "for more context, see https://github.com/rust-lang/rust/issues/60210", + ); + err + } else { + diag.struct_span_err(sp, &format!("suffixes on {} are invalid", kind)) + }; + err.span_label(sp, format!("invalid suffix `{}`", text)); + err.emit(); + } + } +} + +/// Parses a string representing a raw string literal into its final form. The +/// only operation this does is convert embedded CRLF into a single LF. +fn raw_str_lit(lit: &str) -> String { + debug!("raw_str_lit: given {}", lit.escape_default()); + let mut res = String::with_capacity(lit.len()); + + let mut chars = lit.chars().peekable(); + while let Some(c) = chars.next() { + if c == '\r' { + if *chars.peek().unwrap() != '\n' { + panic!("lexer accepted bare CR"); + } + chars.next(); + res.push('\n'); + } else { + res.push(c); + } + } + + res.shrink_to_fit(); + res +} + +// check if `s` looks like i32 or u1234 etc. +fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool { + s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit()) +} + +fn filtered_float_lit(data: Symbol, suffix: Option, diag: Option<(Span, &Handler)>) + -> Option { + debug!("filtered_float_lit: {}, {:?}", data, suffix); + let suffix = match suffix { + Some(suffix) => suffix, + None => return Some(LitKind::FloatUnsuffixed(data)), + }; + + Some(match &*suffix.as_str() { + "f32" => LitKind::Float(data, ast::FloatTy::F32), + "f64" => LitKind::Float(data, ast::FloatTy::F64), + suf => { + err!(diag, |span, diag| { + if suf.len() >= 2 && looks_like_width_suffix(&['f'], suf) { + // if it looks like a width, lets try to be helpful. + let msg = format!("invalid width `{}` for float literal", &suf[1..]); + diag.struct_span_err(span, &msg).help("valid widths are 32 and 64").emit() + } else { + let msg = format!("invalid suffix `{}` for float literal", suf); + diag.struct_span_err(span, &msg) + .span_label(span, format!("invalid suffix `{}`", suf)) + .help("valid suffixes are `f32` and `f64`") + .emit(); + } + }); + + LitKind::FloatUnsuffixed(data) + } + }) +} +fn float_lit(s: &str, suffix: Option, diag: Option<(Span, &Handler)>) + -> Option { + debug!("float_lit: {:?}, {:?}", s, suffix); + // FIXME #2252: bounds checking float literals is deferred until trans + + // Strip underscores without allocating a new String unless necessary. + let s2; + let s = if s.chars().any(|c| c == '_') { + s2 = s.chars().filter(|&c| c != '_').collect::(); + &s2 + } else { + s + }; + + filtered_float_lit(Symbol::intern(s), suffix, diag) +} + +fn integer_lit(s: &str, suffix: Option, diag: Option<(Span, &Handler)>) + -> Option { + // s can only be ascii, byte indexing is fine + + // Strip underscores without allocating a new String unless necessary. + let s2; + let mut s = if s.chars().any(|c| c == '_') { + s2 = s.chars().filter(|&c| c != '_').collect::(); + &s2 + } else { + s + }; + + debug!("integer_lit: {}, {:?}", s, suffix); + + let mut base = 10; + let orig = s; + let mut ty = ast::LitIntType::Unsuffixed; + + if s.starts_with('0') && s.len() > 1 { + match s.as_bytes()[1] { + b'x' => base = 16, + b'o' => base = 8, + b'b' => base = 2, + _ => { } + } + } + + // 1f64 and 2f32 etc. are valid float literals. + if let Some(suf) = suffix { + if looks_like_width_suffix(&['f'], &suf.as_str()) { + let err = match base { + 16 => Some("hexadecimal float literal is not supported"), + 8 => Some("octal float literal is not supported"), + 2 => Some("binary float literal is not supported"), + _ => None, + }; + if let Some(err) = err { + err!(diag, |span, diag| { + diag.struct_span_err(span, err) + .span_label(span, "not supported") + .emit(); + }); + } + return filtered_float_lit(Symbol::intern(s), Some(suf), diag) + } + } + + if base != 10 { + s = &s[2..]; + } + + if let Some(suf) = suffix { + if suf.as_str().is_empty() { + err!(diag, |span, diag| diag.span_bug(span, "found empty literal suffix in Some")); + } + ty = match &*suf.as_str() { + "isize" => ast::LitIntType::Signed(ast::IntTy::Isize), + "i8" => ast::LitIntType::Signed(ast::IntTy::I8), + "i16" => ast::LitIntType::Signed(ast::IntTy::I16), + "i32" => ast::LitIntType::Signed(ast::IntTy::I32), + "i64" => ast::LitIntType::Signed(ast::IntTy::I64), + "i128" => ast::LitIntType::Signed(ast::IntTy::I128), + "usize" => ast::LitIntType::Unsigned(ast::UintTy::Usize), + "u8" => ast::LitIntType::Unsigned(ast::UintTy::U8), + "u16" => ast::LitIntType::Unsigned(ast::UintTy::U16), + "u32" => ast::LitIntType::Unsigned(ast::UintTy::U32), + "u64" => ast::LitIntType::Unsigned(ast::UintTy::U64), + "u128" => ast::LitIntType::Unsigned(ast::UintTy::U128), + suf => { + // i and u look like widths, so lets + // give an error message along those lines + err!(diag, |span, diag| { + if looks_like_width_suffix(&['i', 'u'], suf) { + let msg = format!("invalid width `{}` for integer literal", &suf[1..]); + diag.struct_span_err(span, &msg) + .help("valid widths are 8, 16, 32, 64 and 128") + .emit(); + } else { + let msg = format!("invalid suffix `{}` for numeric literal", suf); + diag.struct_span_err(span, &msg) + .span_label(span, format!("invalid suffix `{}`", suf)) + .help("the suffix must be one of the integral types \ + (`u32`, `isize`, etc)") + .emit(); + } + }); + + ty + } + } + } + + debug!("integer_lit: the type is {:?}, base {:?}, the new string is {:?}, the original \ + string was {:?}, the original suffix was {:?}", ty, base, s, orig, suffix); + + Some(match u128::from_str_radix(s, base) { + Ok(r) => LitKind::Int(r, ty), + Err(_) => { + // small bases are lexed as if they were base 10, e.g, the string + // might be `0b10201`. This will cause the conversion above to fail, + // but these cases have errors in the lexer: we don't want to emit + // two errors, and we especially don't want to emit this error since + // it isn't necessarily true. + let already_errored = base < 10 && + s.chars().any(|c| c.to_digit(10).map_or(false, |d| d >= base)); + + if !already_errored { + err!(diag, |span, diag| diag.span_err(span, "int literal is too large")); + } + LitKind::Int(0, ty) + } + }) +} diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 868b344c0658..526143b28755 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -1,11 +1,10 @@ //! The main parser interface. -use crate::ast::{self, CrateConfig, LitKind, NodeId}; +use crate::ast::{self, CrateConfig, NodeId}; use crate::early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId}; use crate::source_map::{SourceMap, FilePathMapping}; use crate::feature_gate::UnstableFeatures; use crate::parse::parser::Parser; -use crate::symbol::{keywords, Symbol}; use crate::syntax::parse::parser::emit_unclosed_delims; use crate::tokenstream::{TokenStream, TokenTree}; use crate::diagnostics::plugin::ErrorMap; @@ -14,7 +13,6 @@ use crate::print::pprust::token_to_string; use errors::{Applicability, FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder}; use rustc_data_structures::sync::{Lrc, Lock}; use syntax_pos::{Span, SourceFile, FileName, MultiSpan}; -use log::debug; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use std::borrow::Cow; @@ -25,18 +23,15 @@ pub type PResult<'a, T> = Result>; #[macro_use] pub mod parser; - +pub mod attr; pub mod lexer; pub mod token; -pub mod attr; -pub mod diagnostics; -pub mod classify; - -pub(crate) mod unescape; -use unescape::{unescape_str, unescape_char, unescape_byte_str, unescape_byte}; - -pub(crate) mod unescape_error_reporting; +crate mod classify; +crate mod diagnostics; +crate mod literal; +crate mod unescape; +crate mod unescape_error_reporting; /// Info about a parsing session. pub struct ParseSess { @@ -334,339 +329,6 @@ pub fn stream_to_parser(sess: &ParseSess, stream: TokenStream) -> Parser<'_> { Parser::new(sess, stream, None, true, false) } -/// Parses a string representing a raw string literal into its final form. The -/// only operation this does is convert embedded CRLF into a single LF. -fn raw_str_lit(lit: &str) -> String { - debug!("raw_str_lit: given {}", lit.escape_default()); - let mut res = String::with_capacity(lit.len()); - - let mut chars = lit.chars().peekable(); - while let Some(c) = chars.next() { - if c == '\r' { - if *chars.peek().unwrap() != '\n' { - panic!("lexer accepted bare CR"); - } - chars.next(); - res.push('\n'); - } else { - res.push(c); - } - } - - res.shrink_to_fit(); - res -} - -// check if `s` looks like i32 or u1234 etc. -fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool { - s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit()) -} - -macro_rules! err { - ($opt_diag:expr, |$span:ident, $diag:ident| $($body:tt)*) => { - match $opt_diag { - Some(($span, $diag)) => { $($body)* } - None => return None, - } - } -} - -crate fn expect_no_suffix(sp: Span, diag: &Handler, kind: &str, suffix: Option) { - match suffix { - None => {/* everything ok */} - Some(suf) => { - let text = suf.as_str(); - if text.is_empty() { - diag.span_bug(sp, "found empty literal suffix in Some") - } - let mut err = if kind == "a tuple index" && - ["i32", "u32", "isize", "usize"].contains(&text.to_string().as_str()) - { - // #59553: warn instead of reject out of hand to allow the fix to percolate - // through the ecosystem when people fix their macros - let mut err = diag.struct_span_warn( - sp, - &format!("suffixes on {} are invalid", kind), - ); - err.note(&format!( - "`{}` is *temporarily* accepted on tuple index fields as it was \ - incorrectly accepted on stable for a few releases", - text, - )); - err.help( - "on proc macros, you'll want to use `syn::Index::from` or \ - `proc_macro::Literal::*_unsuffixed` for code that will desugar \ - to tuple field access", - ); - err.note( - "for more context, see https://github.com/rust-lang/rust/issues/60210", - ); - err - } else { - diag.struct_span_err(sp, &format!("suffixes on {} are invalid", kind)) - }; - err.span_label(sp, format!("invalid suffix `{}`", text)); - err.emit(); - } - } -} - -impl LitKind { - /// Converts literal token with a suffix into a semantic literal. - /// Works speculatively and may return `None` is diagnostic handler is not passed. - /// If diagnostic handler is passed, always returns `Some`, - /// possibly after reporting non-fatal errors and recovery. - crate fn from_lit_token( - lit: token::Lit, - suf: Option, - diag: Option<(Span, &Handler)> - ) -> Option { - if suf.is_some() && !lit.may_have_suffix() { - err!(diag, |span, diag| { - expect_no_suffix(span, diag, &format!("a {}", lit.literal_name()), suf) - }); - } - - Some(match lit { - token::Bool(i) => { - assert!(i == keywords::True.name() || i == keywords::False.name()); - LitKind::Bool(i == keywords::True.name()) - } - token::Byte(i) => { - match unescape_byte(&i.as_str()) { - Ok(c) => LitKind::Byte(c), - Err(_) => LitKind::Err(i), - } - }, - token::Char(i) => { - match unescape_char(&i.as_str()) { - Ok(c) => LitKind::Char(c), - Err(_) => LitKind::Err(i), - } - }, - token::Err(i) => LitKind::Err(i), - - // There are some valid suffixes for integer and float literals, - // so all the handling is done internally. - token::Integer(s) => return integer_lit(&s.as_str(), suf, diag), - token::Float(s) => return float_lit(&s.as_str(), suf, diag), - - token::Str_(mut sym) => { - // If there are no characters requiring special treatment we can - // reuse the symbol from the Token. Otherwise, we must generate a - // new symbol because the string in the LitKind is different to the - // string in the Token. - let mut has_error = false; - let s = &sym.as_str(); - if s.as_bytes().iter().any(|&c| c == b'\\' || c == b'\r') { - let mut buf = String::with_capacity(s.len()); - unescape_str(s, &mut |_, unescaped_char| { - match unescaped_char { - Ok(c) => buf.push(c), - Err(_) => has_error = true, - } - }); - if has_error { - return Some(LitKind::Err(sym)); - } - sym = Symbol::intern(&buf) - } - - LitKind::Str(sym, ast::StrStyle::Cooked) - } - token::StrRaw(mut sym, n) => { - // Ditto. - let s = &sym.as_str(); - if s.contains('\r') { - sym = Symbol::intern(&raw_str_lit(s)); - } - LitKind::Str(sym, ast::StrStyle::Raw(n)) - } - token::ByteStr(i) => { - let s = &i.as_str(); - let mut buf = Vec::with_capacity(s.len()); - let mut has_error = false; - unescape_byte_str(s, &mut |_, unescaped_byte| { - match unescaped_byte { - Ok(c) => buf.push(c), - Err(_) => has_error = true, - } - }); - if has_error { - return Some(LitKind::Err(i)); - } - buf.shrink_to_fit(); - LitKind::ByteStr(Lrc::new(buf)) - } - token::ByteStrRaw(i, _) => { - LitKind::ByteStr(Lrc::new(i.to_string().into_bytes())) - } - }) - } -} - -fn filtered_float_lit(data: Symbol, suffix: Option, diag: Option<(Span, &Handler)>) - -> Option { - debug!("filtered_float_lit: {}, {:?}", data, suffix); - let suffix = match suffix { - Some(suffix) => suffix, - None => return Some(LitKind::FloatUnsuffixed(data)), - }; - - Some(match &*suffix.as_str() { - "f32" => LitKind::Float(data, ast::FloatTy::F32), - "f64" => LitKind::Float(data, ast::FloatTy::F64), - suf => { - err!(diag, |span, diag| { - if suf.len() >= 2 && looks_like_width_suffix(&['f'], suf) { - // if it looks like a width, lets try to be helpful. - let msg = format!("invalid width `{}` for float literal", &suf[1..]); - diag.struct_span_err(span, &msg).help("valid widths are 32 and 64").emit() - } else { - let msg = format!("invalid suffix `{}` for float literal", suf); - diag.struct_span_err(span, &msg) - .span_label(span, format!("invalid suffix `{}`", suf)) - .help("valid suffixes are `f32` and `f64`") - .emit(); - } - }); - - LitKind::FloatUnsuffixed(data) - } - }) -} -fn float_lit(s: &str, suffix: Option, diag: Option<(Span, &Handler)>) - -> Option { - debug!("float_lit: {:?}, {:?}", s, suffix); - // FIXME #2252: bounds checking float literals is deferred until trans - - // Strip underscores without allocating a new String unless necessary. - let s2; - let s = if s.chars().any(|c| c == '_') { - s2 = s.chars().filter(|&c| c != '_').collect::(); - &s2 - } else { - s - }; - - filtered_float_lit(Symbol::intern(s), suffix, diag) -} - -fn integer_lit(s: &str, suffix: Option, diag: Option<(Span, &Handler)>) - -> Option { - // s can only be ascii, byte indexing is fine - - // Strip underscores without allocating a new String unless necessary. - let s2; - let mut s = if s.chars().any(|c| c == '_') { - s2 = s.chars().filter(|&c| c != '_').collect::(); - &s2 - } else { - s - }; - - debug!("integer_lit: {}, {:?}", s, suffix); - - let mut base = 10; - let orig = s; - let mut ty = ast::LitIntType::Unsuffixed; - - if s.starts_with('0') && s.len() > 1 { - match s.as_bytes()[1] { - b'x' => base = 16, - b'o' => base = 8, - b'b' => base = 2, - _ => { } - } - } - - // 1f64 and 2f32 etc. are valid float literals. - if let Some(suf) = suffix { - if looks_like_width_suffix(&['f'], &suf.as_str()) { - let err = match base { - 16 => Some("hexadecimal float literal is not supported"), - 8 => Some("octal float literal is not supported"), - 2 => Some("binary float literal is not supported"), - _ => None, - }; - if let Some(err) = err { - err!(diag, |span, diag| { - diag.struct_span_err(span, err) - .span_label(span, "not supported") - .emit(); - }); - } - return filtered_float_lit(Symbol::intern(s), Some(suf), diag) - } - } - - if base != 10 { - s = &s[2..]; - } - - if let Some(suf) = suffix { - if suf.as_str().is_empty() { - err!(diag, |span, diag| diag.span_bug(span, "found empty literal suffix in Some")); - } - ty = match &*suf.as_str() { - "isize" => ast::LitIntType::Signed(ast::IntTy::Isize), - "i8" => ast::LitIntType::Signed(ast::IntTy::I8), - "i16" => ast::LitIntType::Signed(ast::IntTy::I16), - "i32" => ast::LitIntType::Signed(ast::IntTy::I32), - "i64" => ast::LitIntType::Signed(ast::IntTy::I64), - "i128" => ast::LitIntType::Signed(ast::IntTy::I128), - "usize" => ast::LitIntType::Unsigned(ast::UintTy::Usize), - "u8" => ast::LitIntType::Unsigned(ast::UintTy::U8), - "u16" => ast::LitIntType::Unsigned(ast::UintTy::U16), - "u32" => ast::LitIntType::Unsigned(ast::UintTy::U32), - "u64" => ast::LitIntType::Unsigned(ast::UintTy::U64), - "u128" => ast::LitIntType::Unsigned(ast::UintTy::U128), - suf => { - // i and u look like widths, so lets - // give an error message along those lines - err!(diag, |span, diag| { - if looks_like_width_suffix(&['i', 'u'], suf) { - let msg = format!("invalid width `{}` for integer literal", &suf[1..]); - diag.struct_span_err(span, &msg) - .help("valid widths are 8, 16, 32, 64 and 128") - .emit(); - } else { - let msg = format!("invalid suffix `{}` for numeric literal", suf); - diag.struct_span_err(span, &msg) - .span_label(span, format!("invalid suffix `{}`", suf)) - .help("the suffix must be one of the integral types \ - (`u32`, `isize`, etc)") - .emit(); - } - }); - - ty - } - } - } - - debug!("integer_lit: the type is {:?}, base {:?}, the new string is {:?}, the original \ - string was {:?}, the original suffix was {:?}", ty, base, s, orig, suffix); - - Some(match u128::from_str_radix(s, base) { - Ok(r) => LitKind::Int(r, ty), - Err(_) => { - // small bases are lexed as if they were base 10, e.g, the string - // might be `0b10201`. This will cause the conversion above to fail, - // but these cases have errors in the lexer: we don't want to emit - // two errors, and we especially don't want to emit this error since - // it isn't necessarily true. - let already_errored = base < 10 && - s.chars().any(|c| c.to_digit(10).map_or(false, |d| d >= base)); - - if !already_errored { - err!(diag, |span, diag| diag.span_err(span, "int literal is too large")); - } - LitKind::Int(0, ty) - } - }) -} - /// A sequence separator. pub struct SeqSep { /// The seperator token. diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b81f7be9c2c1..f95981680b94 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -15,7 +15,7 @@ use crate::ast::{ForeignItem, ForeignItemKind, FunctionRetTy}; use crate::ast::{GenericParam, GenericParamKind}; use crate::ast::GenericArg; use crate::ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind}; -use crate::ast::{Label, Lifetime, Lit}; +use crate::ast::{Label, Lifetime}; use crate::ast::{Local, LocalSource}; use crate::ast::MacStmtStyle; use crate::ast::{Mac, Mac_, MacDelimiter}; @@ -35,7 +35,7 @@ use crate::ast::{RangeEnd, RangeSyntax}; use crate::{ast, attr}; use crate::ext::base::DummyResult; use crate::source_map::{self, SourceMap, Spanned, respan}; -use crate::parse::{self, SeqSep, classify, token}; +use crate::parse::{SeqSep, classify, literal, token}; use crate::parse::lexer::{TokenAndSpan, UnmatchedBrace}; use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; use crate::parse::token::DelimToken; @@ -613,7 +613,7 @@ impl<'a> Parser<'a> { }) } - fn this_token_descr(&self) -> String { + crate fn this_token_descr(&self) -> String { if let Some(prefix) = self.token_descr() { format!("{} `{}`", prefix, self.this_token_to_string()) } else { @@ -621,11 +621,6 @@ impl<'a> Parser<'a> { } } - fn unexpected_last(&self, t: &token::Token) -> PResult<'a, T> { - let token_str = pprust::token_to_string(t); - Err(self.span_fatal(self.prev_span, &format!("unexpected token: `{}`", token_str))) - } - crate fn unexpected(&mut self) -> PResult<'a, T> { match self.expect_one_of(&[], &[]) { Err(e) => Err(e), @@ -1109,7 +1104,7 @@ impl<'a> Parser<'a> { } fn expect_no_suffix(&self, sp: Span, kind: &str, suffix: Option) { - parse::expect_no_suffix(sp, &self.sess.span_diagnostic, kind, suffix) + literal::expect_no_suffix(sp, &self.sess.span_diagnostic, kind, suffix) } /// Attempts to consume a `<`. If `<<` is seen, replaces it with a single @@ -1387,7 +1382,7 @@ impl<'a> Parser<'a> { }) } - fn look_ahead_span(&self, dist: usize) -> Span { + crate fn look_ahead_span(&self, dist: usize) -> Span { if dist == 0 { return self.span } @@ -2030,47 +2025,6 @@ impl<'a> Parser<'a> { } } - /// Matches `lit = true | false | token_lit`. - crate fn parse_lit(&mut self) -> PResult<'a, Lit> { - let diag = Some((self.span, &self.sess.span_diagnostic)); - if let Some(lit) = Lit::from_token(&self.token, self.span, diag) { - self.bump(); - return Ok(lit); - } else if self.token == token::Dot { - // Recover `.4` as `0.4`. - let recovered = self.look_ahead(1, |t| { - if let token::Literal(token::Integer(val), suf) = *t { - let next_span = self.look_ahead_span(1); - if self.span.hi() == next_span.lo() { - let sym = String::from("0.") + &val.as_str(); - let token = token::Literal(token::Float(Symbol::intern(&sym)), suf); - return Some((token, self.span.to(next_span))); - } - } - None - }); - if let Some((token, span)) = recovered { - self.diagnostic() - .struct_span_err(span, "float literals must have an integer part") - .span_suggestion( - span, - "must have an integer part", - pprust::token_to_string(&token), - Applicability::MachineApplicable, - ) - .emit(); - let diag = Some((span, &self.sess.span_diagnostic)); - if let Some(lit) = Lit::from_token(&token, span, diag) { - self.bump(); - self.bump(); - return Ok(lit); - } - } - } - - self.unexpected_last(&self.token) - } - /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`). crate fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P> { maybe_whole_expr!(self); diff --git a/src/test/ui/attr-eq-token-tree.stderr b/src/test/ui/attr-eq-token-tree.stderr index aae25b2721e4..571779dfa1ae 100644 --- a/src/test/ui/attr-eq-token-tree.stderr +++ b/src/test/ui/attr-eq-token-tree.stderr @@ -1,8 +1,8 @@ error: unexpected token: `!` - --> $DIR/attr-eq-token-tree.rs:3:11 + --> $DIR/attr-eq-token-tree.rs:3:13 | LL | #[my_attr = !] - | ^ + | ^ error: aborting due to previous error diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr index 03867a8e43b1..359725a41c10 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr @@ -1,8 +1,8 @@ error: unexpected token: `,` - --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:15 + --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:17 | LL | [_, 99.., _] => {}, - | ^^ + | ^ error: aborting due to previous error diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr index 5ac435bf011e..8f849d7b3f87 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr @@ -1,8 +1,8 @@ error: unexpected token: `]` - --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:15 + --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:17 | LL | [_, 99..] => {}, - | ^^ + | ^ error: aborting due to previous error diff --git a/src/test/ui/macros/macro-attribute.stderr b/src/test/ui/macros/macro-attribute.stderr index aa1cd94b0c63..d28ce25341d3 100644 --- a/src/test/ui/macros/macro-attribute.stderr +++ b/src/test/ui/macros/macro-attribute.stderr @@ -1,8 +1,8 @@ error: unexpected token: `$` - --> $DIR/macro-attribute.rs:1:7 + --> $DIR/macro-attribute.rs:1:9 | LL | #[doc = $not_there] - | ^ + | ^ error: aborting due to previous error diff --git a/src/test/ui/malformed/malformed-interpolated.stderr b/src/test/ui/malformed/malformed-interpolated.stderr index bc2146e409d4..e805416172ba 100644 --- a/src/test/ui/malformed/malformed-interpolated.stderr +++ b/src/test/ui/malformed/malformed-interpolated.stderr @@ -7,19 +7,19 @@ LL | check!(0u8); = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). error: unexpected token: `-0` - --> $DIR/malformed-interpolated.rs:5:19 + --> $DIR/malformed-interpolated.rs:5:21 | LL | #[my_attr = $expr] - | ^ + | ^^^^^ ... LL | check!(-0); // ERROR, see above | ----------- in this macro invocation error: unexpected token: `0 + 0` - --> $DIR/malformed-interpolated.rs:5:19 + --> $DIR/malformed-interpolated.rs:5:21 | LL | #[my_attr = $expr] - | ^ + | ^^^^^ ... LL | check!(0 + 0); // ERROR, see above | -------------- in this macro invocation diff --git a/src/test/ui/parser/attr-bad-meta-2.stderr b/src/test/ui/parser/attr-bad-meta-2.stderr index ffbfc583e8a7..2d772dae6912 100644 --- a/src/test/ui/parser/attr-bad-meta-2.stderr +++ b/src/test/ui/parser/attr-bad-meta-2.stderr @@ -1,8 +1,8 @@ error: unexpected token: `]` - --> $DIR/attr-bad-meta-2.rs:1:8 + --> $DIR/attr-bad-meta-2.rs:1:9 | LL | #[path =] - | ^ + | ^ error: aborting due to previous error diff --git a/src/test/ui/parser/pat-tuple-5.stderr b/src/test/ui/parser/pat-tuple-5.stderr index 61ae40b355d3..f9832214c680 100644 --- a/src/test/ui/parser/pat-tuple-5.stderr +++ b/src/test/ui/parser/pat-tuple-5.stderr @@ -1,8 +1,8 @@ error: unexpected token: `)` - --> $DIR/pat-tuple-5.rs:3:14 + --> $DIR/pat-tuple-5.rs:3:16 | LL | (pat ..) => {} - | ^^ + | ^ error: aborting due to previous error From 362431b4d6029e473166b9df307a171d961b5675 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 11 May 2019 15:42:14 +0200 Subject: [PATCH 097/239] Cleanup the .await HIR lowering with .stmt(..). --- src/librustc/hir/lowering.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 7ccfb826e37b..1612e0a6e9df 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -5647,11 +5647,7 @@ impl<'a> LoweringContext<'a> { hir_vec![ready_arm, pending_arm], hir::MatchSource::AwaitDesugar, )); - hir::Stmt { - hir_id: self.next_id(), - node: hir::StmtKind::Expr(match_expr), - span, - } + self.stmt(span, hir::StmtKind::Expr(match_expr)) }; let yield_stmt = { @@ -5661,11 +5657,7 @@ impl<'a> LoweringContext<'a> { hir::ExprKind::Yield(P(unit)), ThinVec::new(), )); - hir::Stmt { - hir_id: self.next_id(), - node: hir::StmtKind::Expr(yield_expr), - span, - } + self.stmt(span, hir::StmtKind::Expr(yield_expr)) }; let loop_block = P(self.block_all( From 83ed781c017632d48746553bdb2bf3d1633d5ca4 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 11 May 2019 16:03:27 +0300 Subject: [PATCH 098/239] Address comments + Fix tests --- src/librustdoc/clean/cfg.rs | 2 ++ src/libsyntax/ast.rs | 9 +++++++-- src/libsyntax/parse/literal.rs | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 51fe26b37431..b96ac19c1ea6 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -416,6 +416,8 @@ mod test { use syntax_pos::DUMMY_SP; use syntax::ast::*; + use syntax::attr; + use syntax::source_map::dummy_spanned; use syntax::symbol::Symbol; use syntax::with_globals; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a188f1a93689..aa176c892588 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1351,12 +1351,17 @@ pub enum StrStyle { Raw(u16), } -/// A literal. +/// An AST literal. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Lit { - pub node: LitKind, + /// The original literal token as written in source code. pub token: token::Lit, + /// The original literal suffix as written in source code. pub suffix: Option, + /// The "semantic" representation of the literal lowered from the original tokens. + /// Strings are unescaped, hexadecimal forms are eliminated, etc. + /// FIXME: Remove this and only create the semantic representation during lowering to HIR. + pub node: LitKind, pub span: Span, } diff --git a/src/libsyntax/parse/literal.rs b/src/libsyntax/parse/literal.rs index 2c7ba13fbef8..53195421ddce 100644 --- a/src/libsyntax/parse/literal.rs +++ b/src/libsyntax/parse/literal.rs @@ -27,7 +27,7 @@ macro_rules! err { impl LitKind { /// Converts literal token with a suffix into a semantic literal. - /// Works speculatively and may return `None` is diagnostic handler is not passed. + /// Works speculatively and may return `None` if diagnostic handler is not passed. /// If diagnostic handler is passed, always returns `Some`, /// possibly after reporting non-fatal errors and recovery. fn from_lit_token( @@ -166,7 +166,7 @@ impl LitKind { impl Lit { /// Converts literal token with a suffix into an AST literal. - /// Works speculatively and may return `None` is diagnostic handler is not passed. + /// Works speculatively and may return `None` if diagnostic handler is not passed. /// If diagnostic handler is passed, may return `Some`, /// possibly after reporting non-fatal errors and recovery, or `None` for irrecoverable errors. crate fn from_token( From d17713599cca675d2ca5def29fdce4b353c97234 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sat, 11 May 2019 08:56:38 -0700 Subject: [PATCH 099/239] Update clippy --- Cargo.lock | 2 -- src/tools/clippy | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f6334e9bdb81..982070a243ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -378,7 +378,6 @@ dependencies = [ "rustc_tools_util 0.1.1", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -399,7 +398,6 @@ dependencies = [ "regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/tools/clippy b/src/tools/clippy index 341c96afd331..3710ec599622 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 341c96afd331195beeb001436535c1feb479ff9d +Subproject commit 3710ec59962295336ab4aed100267b584dd7df7d From a145b14b3e1f7bf15ea67d2bd9c39c85395f94bb Mon Sep 17 00:00:00 2001 From: Yusuke Matsushita Date: Sun, 12 May 2019 01:47:20 +0900 Subject: [PATCH 100/239] Remove redundant "let mut" in write_graph_label Removed the redundant "let mut" in the write_graph_label function (it caused "let mut let mut" for non-user-defined local variables). --- src/librustc_mir/util/graphviz.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index 04b0e16cd9a8..188da9a82dc9 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -167,7 +167,7 @@ fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>, write!(w, r#"{:?}: {}; // {}
"#, Place::Base(PlaceBase::Local(local)), escape(&decl.ty), name)?; } else { - write!(w, r#"let mut {:?}: {};
"#, + write!(w, r#"{:?}: {};
"#, Place::Base(PlaceBase::Local(local)), escape(&decl.ty))?; } } From 5ccf2fb985b5581fdc3f1a3a647b0d613da996d3 Mon Sep 17 00:00:00 2001 From: Mike Boutin Date: Sun, 5 May 2019 10:25:01 -0400 Subject: [PATCH 101/239] Add #[doc(hidden)] attribute on compiler generated proc-macro module. Stops unavoidable `missing_docs` warning/error on proc-macro crates. Resolves #42008. --- src/libsyntax_ext/proc_macro_decls.rs | 7 ++++++- src/test/ui/proc-macro/no-missing-docs.rs | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/proc-macro/no-missing-docs.rs diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs index f0390ba3d40c..e14781c4fa9f 100644 --- a/src/libsyntax_ext/proc_macro_decls.rs +++ b/src/libsyntax_ext/proc_macro_decls.rs @@ -324,6 +324,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { // Creates a new module which looks like: // +// #[doc(hidden)] // mod $gensym { // extern crate proc_macro; // @@ -357,6 +358,10 @@ fn mk_decls( }); let span = DUMMY_SP.apply_mark(mark); + let hidden = cx.meta_list_item_word(span, Symbol::intern("hidden")); + let doc = cx.meta_list(span, Symbol::intern("doc"), vec![hidden]); + let doc_hidden = cx.attribute(span, doc); + let proc_macro = Ident::from_str("proc_macro"); let krate = cx.item(span, proc_macro, @@ -421,7 +426,7 @@ fn mk_decls( span, span, ast::Ident::with_empty_ctxt(Symbol::gensym("decls")), - vec![], + vec![doc_hidden], vec![krate, decls_static], ).map(|mut i| { i.vis = respan(span, ast::VisibilityKind::Public); diff --git a/src/test/ui/proc-macro/no-missing-docs.rs b/src/test/ui/proc-macro/no-missing-docs.rs new file mode 100644 index 000000000000..e5a5f8beb458 --- /dev/null +++ b/src/test/ui/proc-macro/no-missing-docs.rs @@ -0,0 +1,16 @@ +//! Verify that the `decls` module implicitly added by the compiler does not cause `missing_docs` +//! warnings. + +// compile-pass +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![deny(missing_docs)] + +extern crate proc_macro; +use proc_macro::*; + +/// Foo1. +#[proc_macro] +pub fn foo1(input: TokenStream) -> TokenStream { input } From 3b78a474f3048dd6221e1ddd3e5b1af61df3945d Mon Sep 17 00:00:00 2001 From: Pulkit Goyal <7895pulkit@gmail.com> Date: Thu, 9 May 2019 21:32:33 +0300 Subject: [PATCH 102/239] Fix HIR printing of existential type #60662 This fixes https://github.com/rust-lang/rust/issues/60662 --- src/librustc/hir/print.rs | 1 - src/test/ui/issues/issue-60662.rs | 11 +++++++++++ src/test/ui/issues/issue-60662.stdout | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issues/issue-60662.rs create mode 100644 src/test/ui/issues/issue-60662.stdout diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index c42d8f3cb3c3..88fbe9a06ddd 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -646,7 +646,6 @@ impl<'a> State<'a> { self.print_where_clause(&exist.generics.where_clause)?; self.s.space()?; - self.word_space(":")?; let mut real_bounds = Vec::with_capacity(exist.bounds.len()); for b in exist.bounds.iter() { if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b { diff --git a/src/test/ui/issues/issue-60662.rs b/src/test/ui/issues/issue-60662.rs new file mode 100644 index 000000000000..fe4eaff742d6 --- /dev/null +++ b/src/test/ui/issues/issue-60662.rs @@ -0,0 +1,11 @@ +// compile-pass +// compile-flags: -Z unpretty=hir + +#![feature(existential_type)] + +trait Animal { +} + +fn main() { + pub existential type ServeFut: Animal; +} diff --git a/src/test/ui/issues/issue-60662.stdout b/src/test/ui/issues/issue-60662.stdout new file mode 100644 index 000000000000..5acfdf9ed534 --- /dev/null +++ b/src/test/ui/issues/issue-60662.stdout @@ -0,0 +1,14 @@ +// compile-pass +// compile-flags: -Z unpretty=hir + +#![feature(existential_type)] +#[prelude_import] +use ::std::prelude::v1::*; +#[macro_use] +extern crate std; + +trait Animal { } + +fn main() { + pub existential type ServeFut : Animal; + } From 14b353820f94d8613a678be73ce96cf646038bf4 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 11 May 2019 22:44:33 +0300 Subject: [PATCH 103/239] syntax: Remove some legacy nonterminal tokens --- src/libsyntax/mut_visit.rs | 4 ---- src/libsyntax/parse/parser.rs | 8 -------- src/libsyntax/parse/token.rs | 14 ++++---------- src/libsyntax/print/pprust.rs | 4 ---- 4 files changed, 4 insertions(+), 26 deletions(-) diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 6eb8b1b5004c..f587e63e12b9 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -663,7 +663,6 @@ pub fn noop_visit_interpolated(nt: &mut token::Nonterminal, vis: token::NtMeta(meta) => vis.visit_meta_item(meta), token::NtPath(path) => vis.visit_path(path), token::NtTT(tt) => vis.visit_tt(tt), - token::NtArm(arm) => vis.visit_arm(arm), token::NtImplItem(item) => visit_clobber(item, |item| { // See reasoning above. @@ -676,9 +675,6 @@ pub fn noop_visit_interpolated(nt: &mut token::Nonterminal, vis: vis.flat_map_trait_item(item) .expect_one("expected visitor to produce exactly one item") }), - token::NtGenerics(generics) => vis.visit_generics(generics), - token::NtWhereClause(where_clause) => vis.visit_where_clause(where_clause), - token::NtArg(arg) => vis.visit_arg(arg), token::NtVis(visib) => vis.visit_vis(visib), token::NtForeignItem(item) => visit_clobber(item, |item| { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d97d1e2f0f4e..48aaa1cbb034 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1925,8 +1925,6 @@ impl<'a> Parser<'a> { /// This version of parse arg doesn't necessarily require identifier names. fn parse_arg_general(&mut self, require_name: bool, is_trait_item: bool, allow_c_variadic: bool) -> PResult<'a, Arg> { - maybe_whole!(self, NtArg, |x| x); - if let Ok(Some(_)) = self.parse_self_arg() { let mut err = self.struct_span_err(self.prev_span, "unexpected `self` argument in function"); @@ -4179,8 +4177,6 @@ impl<'a> Parser<'a> { } crate fn parse_arm(&mut self) -> PResult<'a, Arm> { - maybe_whole!(self, NtArm, |x| x); - let attrs = self.parse_outer_attributes()?; let pats = self.parse_pats()?; let guard = if self.eat_keyword(keywords::If) { @@ -5915,8 +5911,6 @@ impl<'a> Parser<'a> { /// | ( < lifetimes , typaramseq ( , )? > ) /// where typaramseq = ( typaram ) | ( typaram , typaramseq ) fn parse_generics(&mut self) -> PResult<'a, ast::Generics> { - maybe_whole!(self, NtGenerics, |x| x); - let span_lo = self.span; if self.eat_lt() { let params = self.parse_generic_params()?; @@ -6169,8 +6163,6 @@ impl<'a> Parser<'a> { /// where T : Trait + 'b, 'a : 'b /// ``` fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> { - maybe_whole!(self, NtWhereClause, |x| x); - let mut where_clause = WhereClause { id: ast::DUMMY_NODE_ID, predicates: Vec::new(), diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index fd7a39c576da..79852e38596d 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -585,14 +585,12 @@ pub enum Nonterminal { NtPath(ast::Path), NtVis(ast::Visibility), NtTT(TokenTree), - // These are not exposed to macros, but are used by quasiquote. - NtArm(ast::Arm), - NtImplItem(ast::ImplItem), + // Used only for passing items to proc macro attributes (they are not + // strictly necessary for that, `Annotatable` can be converted into + // tokens directly, but doing that naively regresses pretty-printing). NtTraitItem(ast::TraitItem), + NtImplItem(ast::ImplItem), NtForeignItem(ast::ForeignItem), - NtGenerics(ast::Generics), - NtWhereClause(ast::WhereClause), - NtArg(ast::Arg), } impl PartialEq for Nonterminal { @@ -625,13 +623,9 @@ impl fmt::Debug for Nonterminal { NtMeta(..) => f.pad("NtMeta(..)"), NtPath(..) => f.pad("NtPath(..)"), NtTT(..) => f.pad("NtTT(..)"), - NtArm(..) => f.pad("NtArm(..)"), NtImplItem(..) => f.pad("NtImplItem(..)"), NtTraitItem(..) => f.pad("NtTraitItem(..)"), NtForeignItem(..) => f.pad("NtForeignItem(..)"), - NtGenerics(..) => f.pad("NtGenerics(..)"), - NtWhereClause(..) => f.pad("NtWhereClause(..)"), - NtArg(..) => f.pad("NtArg(..)"), NtVis(..) => f.pad("NtVis(..)"), NtLifetime(..) => f.pad("NtLifetime(..)"), } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 682621d40ab6..0a402e924005 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -278,12 +278,8 @@ pub fn nonterminal_to_string(nt: &Nonterminal) -> String { token::NtLifetime(e) => ident_to_string(e), token::NtLiteral(ref e) => expr_to_string(e), token::NtTT(ref tree) => tt_to_string(tree.clone()), - token::NtArm(ref e) => arm_to_string(e), token::NtImplItem(ref e) => impl_item_to_string(e), token::NtTraitItem(ref e) => trait_item_to_string(e), - token::NtGenerics(ref e) => generic_params_to_string(&e.params), - token::NtWhereClause(ref e) => where_clause_to_string(e), - token::NtArg(ref e) => arg_to_string(e), token::NtVis(ref e) => vis_to_string(e), token::NtForeignItem(ref e) => foreign_item_to_string(e), } From 0535e42678d45084e2cff03dbd63f5168731564c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 5 May 2019 14:06:04 +0200 Subject: [PATCH 104/239] ast_validation: comments -> doc comments --- src/librustc_passes/ast_validation.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 6cb3161382af..16935796d4ba 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -54,21 +54,21 @@ struct AstValidator<'a> { has_proc_macro_decls: bool, has_global_allocator: bool, - // Used to ban nested `impl Trait`, e.g., `impl Into`. - // Nested `impl Trait` _is_ allowed in associated type position, - // e.g `impl Iterator` + /// Used to ban nested `impl Trait`, e.g., `impl Into`. + /// Nested `impl Trait` _is_ allowed in associated type position, + /// e.g `impl Iterator` outer_impl_trait: Option, - // Used to ban `impl Trait` in path projections like `::Item` - // or `Foo::Bar` + /// Used to ban `impl Trait` in path projections like `::Item` + /// or `Foo::Bar` is_impl_trait_banned: bool, - // rust-lang/rust#57979: the ban of nested `impl Trait` was buggy - // until PRs #57730 and #57981 landed: it would jump directly to - // walk_ty rather than visit_ty (or skip recurring entirely for - // impl trait in projections), and thus miss some cases. We track - // whether we should downgrade to a warning for short-term via - // these booleans. + /// rust-lang/rust#57979: the ban of nested `impl Trait` was buggy + /// until PRs #57730 and #57981 landed: it would jump directly to + /// walk_ty rather than visit_ty (or skip recurring entirely for + /// impl trait in projections), and thus miss some cases. We track + /// whether we should downgrade to a warning for short-term via + /// these booleans. warning_period_57979_didnt_record_next_impl_trait: bool, warning_period_57979_impl_trait_in_proj: bool, } From 9b4a630baaba9bc36bce91d0721886f38ad1b182 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 12 May 2019 02:00:06 +0200 Subject: [PATCH 105/239] syntax::parse::parser: convert unnecessary '&mut self's to '&self'. --- src/libsyntax/parse/parser.rs | 38 +++++++++++++++++------------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d97d1e2f0f4e..36ee1949ad58 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1877,7 +1877,7 @@ impl<'a> Parser<'a> { Ok(MutTy { ty: t, mutbl: mutbl }) } - fn is_named_argument(&mut self) -> bool { + fn is_named_argument(&self) -> bool { let offset = match self.token { token::Interpolated(ref nt) => match **nt { token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon), @@ -2471,27 +2471,27 @@ impl<'a> Parser<'a> { }) } - fn mk_expr(&mut self, span: Span, node: ExprKind, attrs: ThinVec) -> P { + fn mk_expr(&self, span: Span, node: ExprKind, attrs: ThinVec) -> P { P(Expr { node, span, attrs, id: ast::DUMMY_NODE_ID }) } - fn mk_unary(&mut self, unop: ast::UnOp, expr: P) -> ast::ExprKind { + fn mk_unary(&self, unop: ast::UnOp, expr: P) -> ast::ExprKind { ExprKind::Unary(unop, expr) } - fn mk_binary(&mut self, binop: ast::BinOp, lhs: P, rhs: P) -> ast::ExprKind { + fn mk_binary(&self, binop: ast::BinOp, lhs: P, rhs: P) -> ast::ExprKind { ExprKind::Binary(binop, lhs, rhs) } - fn mk_call(&mut self, f: P, args: Vec>) -> ast::ExprKind { + fn mk_call(&self, f: P, args: Vec>) -> ast::ExprKind { ExprKind::Call(f, args) } - fn mk_index(&mut self, expr: P, idx: P) -> ast::ExprKind { + fn mk_index(&self, expr: P, idx: P) -> ast::ExprKind { ExprKind::Index(expr, idx) } - fn mk_range(&mut self, + fn mk_range(&self, start: Option>, end: Option>, limits: RangeLimits) @@ -2503,7 +2503,7 @@ impl<'a> Parser<'a> { } } - fn mk_assign_op(&mut self, binop: ast::BinOp, + fn mk_assign_op(&self, binop: ast::BinOp, lhs: P, rhs: P) -> ast::ExprKind { ExprKind::AssignOp(binop, lhs, rhs) } @@ -3840,7 +3840,7 @@ impl<'a> Parser<'a> { /// Produce an error if comparison operators are chained (RFC #558). /// We only need to check lhs, not rhs, because all comparison ops /// have same precedence and are left-associative - fn check_no_chained_comparison(&mut self, lhs: &Expr, outer_op: &AssocOp) { + fn check_no_chained_comparison(&self, lhs: &Expr, outer_op: &AssocOp) { debug_assert!(outer_op.is_comparison(), "check_no_chained_comparison: {:?} is not comparison", outer_op); @@ -5137,7 +5137,7 @@ impl<'a> Parser<'a> { }) } - fn is_async_block(&mut self) -> bool { + fn is_async_block(&self) -> bool { self.token.is_keyword(keywords::Async) && ( ( // `async move {` @@ -5149,19 +5149,19 @@ impl<'a> Parser<'a> { ) } - fn is_async_fn(&mut self) -> bool { + fn is_async_fn(&self) -> bool { self.token.is_keyword(keywords::Async) && self.look_ahead(1, |t| t.is_keyword(keywords::Fn)) } - fn is_do_catch_block(&mut self) -> bool { + fn is_do_catch_block(&self) -> bool { self.token.is_keyword(keywords::Do) && self.look_ahead(1, |t| t.is_keyword(keywords::Catch)) && self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace)) && !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL) } - fn is_try_block(&mut self) -> bool { + fn is_try_block(&self) -> bool { self.token.is_keyword(keywords::Try) && self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) && self.span.rust_2018() && @@ -5183,7 +5183,7 @@ impl<'a> Parser<'a> { self.look_ahead(1, |t| t.is_keyword(keywords::Type)) } - fn is_auto_trait_item(&mut self) -> bool { + fn is_auto_trait_item(&self) -> bool { // auto trait (self.token.is_keyword(keywords::Auto) && self.look_ahead(1, |t| t.is_keyword(keywords::Trait))) @@ -5445,7 +5445,7 @@ impl<'a> Parser<'a> { } /// Checks if this expression is a successfully parsed statement. - fn expr_is_complete(&mut self, e: &Expr) -> bool { + fn expr_is_complete(&self, e: &Expr) -> bool { self.restrictions.contains(Restrictions::STMT_EXPR) && !classify::expr_requires_semi_to_be_stmt(e) } @@ -6517,7 +6517,7 @@ impl<'a> Parser<'a> { Ok((id, generics)) } - fn mk_item(&mut self, span: Span, ident: Ident, node: ItemKind, vis: Visibility, + fn mk_item(&self, span: Span, ident: Ident, node: ItemKind, vis: Visibility, attrs: Vec) -> P { P(Item { ident, @@ -6549,7 +6549,7 @@ impl<'a> Parser<'a> { /// Returns `true` if we are looking at `const ID` /// (returns `false` for things like `const fn`, etc.). - fn is_const_item(&mut self) -> bool { + fn is_const_item(&self) -> bool { self.token.is_keyword(keywords::Const) && !self.look_ahead(1, |t| t.is_keyword(keywords::Fn)) && !self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe)) @@ -6657,7 +6657,7 @@ impl<'a> Parser<'a> { }) } - fn complain_if_pub_macro(&mut self, vis: &VisibilityKind, sp: Span) { + fn complain_if_pub_macro(&self, vis: &VisibilityKind, sp: Span) { match *vis { VisibilityKind::Inherited => {} _ => { @@ -6686,7 +6686,7 @@ impl<'a> Parser<'a> { } } - fn missing_assoc_item_kind_err(&mut self, item_type: &str, prev_span: Span) + fn missing_assoc_item_kind_err(&self, item_type: &str, prev_span: Span) -> DiagnosticBuilder<'a> { let expected_kinds = if item_type == "extern" { From b680b66dddf0d4ea4286c1ed921ac48511937923 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 12 May 2019 02:01:32 +0200 Subject: [PATCH 106/239] parse_bottom_expr: extract common 'return' out. --- src/libsyntax/parse/parser.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 36ee1949ad58..3eb5281e3b16 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2643,13 +2643,12 @@ impl<'a> Parser<'a> { hi = path.span; return Ok(self.mk_expr(lo.to(hi), ExprKind::Path(Some(qself), path), attrs)); } - if self.span.rust_2018() && self.check_keyword(keywords::Async) - { - if self.is_async_block() { // check for `async {` and `async move {` - return self.parse_async_block(attrs); + if self.span.rust_2018() && self.check_keyword(keywords::Async) { + return if self.is_async_block() { // check for `async {` and `async move {` + self.parse_async_block(attrs) } else { - return self.parse_lambda_expr(attrs); - } + self.parse_lambda_expr(attrs) + }; } if self.check_keyword(keywords::Move) || self.check_keyword(keywords::Static) { return self.parse_lambda_expr(attrs); From 4aa4a8f776d9ab3f0110f74f85cc8313b9e4d604 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 12 May 2019 02:17:34 +0200 Subject: [PATCH 107/239] Minor cleanup in parse_assoc_expr_with. --- src/libsyntax/parse/parser.rs | 38 +++++++++++++---------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3eb5281e3b16..0e2e4eceabf4 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3573,7 +3573,8 @@ impl<'a> Parser<'a> { } else { self.restrictions }; - if op.precedence() < min_prec { + let prec = op.precedence(); + if prec < min_prec { break; } // Check for deprecated `...` syntax @@ -3614,8 +3615,7 @@ impl<'a> Parser<'a> { // We have 2 alternatives here: `x..y`/`x..=y` and `x..`/`x..=` The other // two variants are handled with `parse_prefix_range_expr` call above. let rhs = if self.is_at_start_of_range_notation_rhs() { - Some(self.parse_assoc_expr_with(op.precedence() + 1, - LhsExpr::NotYetParsed)?) + Some(self.parse_assoc_expr_with(prec + 1, LhsExpr::NotYetParsed)?) } else { None }; @@ -3635,28 +3635,18 @@ impl<'a> Parser<'a> { break } - let rhs = match op.fixity() { - Fixity::Right => self.with_res( - restrictions - Restrictions::STMT_EXPR, - |this| { - this.parse_assoc_expr_with(op.precedence(), - LhsExpr::NotYetParsed) - }), - Fixity::Left => self.with_res( - restrictions - Restrictions::STMT_EXPR, - |this| { - this.parse_assoc_expr_with(op.precedence() + 1, - LhsExpr::NotYetParsed) - }), + let fixity = op.fixity(); + let prec_adjustment = match fixity { + Fixity::Right => 0, + Fixity::Left => 1, // We currently have no non-associative operators that are not handled above by // the special cases. The code is here only for future convenience. - Fixity::None => self.with_res( - restrictions - Restrictions::STMT_EXPR, - |this| { - this.parse_assoc_expr_with(op.precedence() + 1, - LhsExpr::NotYetParsed) - }), - }?; + Fixity::None => 1, + }; + let rhs = self.with_res( + restrictions - Restrictions::STMT_EXPR, + |this| this.parse_assoc_expr_with(prec + prec_adjustment, LhsExpr::NotYetParsed) + )?; // Make sure that the span of the parent node is larger than the span of lhs and rhs, // including the attributes. @@ -3702,7 +3692,7 @@ impl<'a> Parser<'a> { } }; - if op.fixity() == Fixity::None { break } + if let Fixity::None = fixity { break } } Ok(lhs) } From 0fc2cfb66c7de60099386a3cc091e2bbb2b2187a Mon Sep 17 00:00:00 2001 From: Yusuke Matsushita Date: Sun, 12 May 2019 09:52:38 +0900 Subject: [PATCH 108/239] Fix minor typos for ItemLocalId * added comma before 'that is' * "can be implement" -> "can be implemented" --- src/librustc/hir/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 9f7fa6c5557e..3778324f01a1 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -126,12 +126,12 @@ mod item_local_id_inner { use rustc_macros::HashStable; newtype_index! { /// An `ItemLocalId` uniquely identifies something within a given "item-like", - /// that is within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no + /// that is, within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no /// guarantee that the numerical value of a given `ItemLocalId` corresponds to /// the node's position within the owning item in any way, but there is a /// guarantee that the `LocalItemId`s within an owner occupy a dense range of /// integers starting at zero, so a mapping that maps all or most nodes within - /// an "item-like" to something else can be implement by a `Vec` instead of a + /// an "item-like" to something else can be implemented by a `Vec` instead of a /// tree or hash map. pub struct ItemLocalId { derive [HashStable] From 664c8ed301c8089e77775ac3a52d3f3d938e74d3 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 12 May 2019 17:12:49 +0100 Subject: [PATCH 109/239] Always use the stronger outlives version for opaque types --- src/librustc/infer/opaque_types/mod.rs | 34 +++++++++++++++---- .../can-return-unconstrained-closure.rs | 4 +++ .../issue-57464-unexpected-regions.rs | 7 ++++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index f85fd524a5d9..6bf23ab864ab 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -284,18 +284,40 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { debug!("constrain_opaque_type: def_id={:?}", def_id); debug!("constrain_opaque_type: opaque_defn={:#?}", opaque_defn); + let tcx = self.tcx; + let concrete_ty = self.resolve_type_vars_if_possible(&opaque_defn.concrete_ty); debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty); - let abstract_type_generics = self.tcx.generics_of(def_id); + let abstract_type_generics = tcx.generics_of(def_id); - let span = self.tcx.def_span(def_id); + let span = tcx.def_span(def_id); - // If there are required region bounds, we can just skip - // ahead. There will already be a registered region - // obligation related `concrete_ty` to those regions. + // If there are required region bounds, we can use them. if opaque_defn.has_required_region_bounds { + let predicates_of = tcx.predicates_of(def_id); + debug!( + "constrain_opaque_type: predicates: {:#?}", + predicates_of, + ); + let bounds = predicates_of.instantiate(tcx, opaque_defn.substs); + debug!("constrain_opaque_type: bounds={:#?}", bounds); + let opaque_type = tcx.mk_opaque(def_id, opaque_defn.substs); + + let required_region_bounds = tcx.required_region_bounds( + opaque_type, + bounds.predicates.clone(), + ); + debug_assert!(!required_region_bounds.is_empty()); + + for region in required_region_bounds { + concrete_ty.visit_with(&mut OpaqueTypeOutlivesVisitor { + infcx: self, + least_region: region, + span, + }); + } return; } @@ -371,7 +393,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } - let least_region = least_region.unwrap_or(self.tcx.lifetimes.re_static); + let least_region = least_region.unwrap_or(tcx.lifetimes.re_static); debug!("constrain_opaque_types: least_region={:?}", least_region); concrete_ty.visit_with(&mut OpaqueTypeOutlivesVisitor { diff --git a/src/test/ui/impl-trait/can-return-unconstrained-closure.rs b/src/test/ui/impl-trait/can-return-unconstrained-closure.rs index a982b176ecda..90a7519074b5 100644 --- a/src/test/ui/impl-trait/can-return-unconstrained-closure.rs +++ b/src/test/ui/impl-trait/can-return-unconstrained-closure.rs @@ -16,4 +16,8 @@ fn make_identity() -> impl Sized { |x: &'static i32| x } +fn make_identity_static() -> impl Sized + 'static { + |x: &'static i32| x +} + fn main() {} diff --git a/src/test/ui/impl-trait/issue-57464-unexpected-regions.rs b/src/test/ui/impl-trait/issue-57464-unexpected-regions.rs index 29e271c68ec9..11f1a392239d 100644 --- a/src/test/ui/impl-trait/issue-57464-unexpected-regions.rs +++ b/src/test/ui/impl-trait/issue-57464-unexpected-regions.rs @@ -17,6 +17,13 @@ fn wrapped_closure() -> impl Sized { A(f) } +fn wrapped_closure_with_bound() -> impl Sized + 'static { + let f = |x| x; + f(&0); + A(f) +} + fn main() { let x: Box = Box::new(wrapped_closure()); + let y: Box = Box::new(wrapped_closure_with_bound()); } From 1f5145e2735083475d586f4a6a1a389a090f30e4 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 12 May 2019 17:52:33 +0100 Subject: [PATCH 110/239] Treat generators the same as closure for escaping lifetimes --- src/librustc/infer/opaque_types/mod.rs | 17 +++++++++++++++++ src/test/run-pass/impl-trait/lifetimes.rs | 6 ++++++ 2 files changed, 23 insertions(+) diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 6bf23ab864ab..a8dca9062bd2 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -705,6 +705,23 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx> self.tcx.mk_closure(def_id, ty::ClosureSubsts { substs }) } + ty::Generator(def_id, substs, movability) => { + let generics = self.tcx.generics_of(def_id); + let substs = self.tcx.mk_substs(substs.substs.iter().enumerate().map( + |(index, &kind)| { + if index < generics.parent_count { + // Accommodate missing regions in the parent kinds... + self.fold_kind_mapping_missing_regions_to_empty(kind) + } else { + // ...but not elsewhere. + self.fold_kind_normally(kind) + } + }, + )); + + self.tcx.mk_generator(def_id, ty::GeneratorSubsts { substs }, movability) + } + _ => ty.super_fold_with(self), } } diff --git a/src/test/run-pass/impl-trait/lifetimes.rs b/src/test/run-pass/impl-trait/lifetimes.rs index 5a21e1dd8175..9a9843375e4c 100644 --- a/src/test/run-pass/impl-trait/lifetimes.rs +++ b/src/test/run-pass/impl-trait/lifetimes.rs @@ -1,6 +1,7 @@ // run-pass #![allow(warnings)] +#![feature(generators)] use std::fmt::Debug; @@ -112,6 +113,11 @@ impl<'unnecessary_lifetime> MyVec { fn iter_doesnt_capture_unnecessary_lifetime<'s>(&'s self) -> impl Iterator { self.0.iter().flat_map(|inner_vec| inner_vec.iter()) } + + fn generator_doesnt_capture_unnecessary_lifetime<'s: 's>() -> impl Sized { + || yield + } } + fn main() {} From ff71b80a85185c5d0ce594c13efddcaca9be54c5 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 27 Jan 2019 11:03:21 +0000 Subject: [PATCH 111/239] Change compare mode to use -Zborrowck=mir --- .../incremental/hashes/closure_expressions.rs | 4 +- ...es-project-from-hrtb-in-fn-body.nll.stderr | 24 ++ .../associated-types-subtyping-1.nll.stderr | 24 ++ ...fn-ret-contravariant.krisskross.nll.stderr | 24 ++ ...-fn-ret-contravariant.transmute.nll.stderr | 10 + ...ect-fn-ret-invariant.krisskross.nll.stderr | 24 ++ ...project-fn-ret-invariant.oneuse.nll.stderr | 24 ++ ...ject-fn-ret-invariant.transmute.nll.stderr | 11 + .../borrowck-anon-fields-variant.nll.stderr | 40 ++ .../borrowck-describe-lvalue.nll.stderr | 366 ++++++++++++++++++ .../borrowck-for-loop-head-linkage.nll.stderr | 27 ++ .../borrowck-mutate-in-guard.nll.stderr | 41 ++ .../borrowck-object-lifetime.nll.stderr | 23 ++ ...orrow-from-shorter-lived-andmut.nll.stderr | 12 + src/test/ui/borrowck/issue-7573.nll.stderr | 14 + .../regions-escape-bound-fn-2.nll.stderr | 12 + .../regions-escape-bound-fn.nll.stderr | 12 + .../regions-escape-unboxed-closure.nll.stderr | 12 + ...interference-future-compat-lint.nll.stderr | 36 ++ .../ui/c-variadic/variadic-ffi-4.nll.stderr | 81 ++++ .../expect-fn-supply-fn.nll.stderr | 53 +++ ...ds-static-cant-capture-borrowed.nll.stderr | 37 ++ .../expect-region-supply-region.nll.stderr | 42 ++ .../ui/consts/const_let_refutable.nll.stderr | 31 ++ .../min_const_fn/min_const_fn.nll.stderr | 328 ++++++++++++++++ .../min_const_fn/min_const_fn_dyn.nll.stderr | 31 ++ .../ui/continue-after-missing-main.nll.stderr | 7 + .../ui/empty/empty-never-array.nll.stderr | 23 ++ src/test/ui/error-codes/E0502.nll.stderr | 13 + ...1-does-not-trigger-for-closures.nll.stderr | 11 + ..._type_does_not_live_long_enough.nll.stderr | 18 + .../generator/auto-trait-regions.nll.stderr | 41 ++ .../ui/hashmap-iter-value-lifetime.nll.stderr | 15 + src/test/ui/hashmap-lifetimes.nll.stderr | 13 + ...ubtype.free_inv_x_vs_free_inv_y.nll.stderr | 30 ++ .../hr-subtype.free_x_vs_free_y.nll.stderr | 16 + .../ui/hrtb/hrtb-cache-issue-54302.nll.stderr | 8 + .../hrtb/hrtb-perfect-forwarding.nll.stderr | 77 ++++ .../dyn-trait.nll.stderr | 10 + ...t_outlive_least_region_or_bound.nll.stderr | 51 +++ .../static-return-lifetime-infered.nll.stderr | 26 ++ .../type_parameters_captured.nll.stderr | 11 + .../in-band-lifetimes/mismatched.nll.stderr | 20 + .../mismatched_trait_impl.nll.stderr | 24 ++ src/test/ui/issues/issue-10291.nll.stderr | 11 + src/test/ui/issues/issue-13058.nll.stderr | 12 + src/test/ui/issues/issue-15034.nll.stderr | 11 + src/test/ui/issues/issue-15381.nll.stderr | 16 + src/test/ui/issues/issue-16683.nll.stderr | 10 + src/test/ui/issues/issue-17728.nll.stderr | 21 + src/test/ui/issues/issue-17758.nll.stderr | 10 + src/test/ui/issues/issue-26217.nll.stderr | 10 + src/test/ui/issues/issue-28848.nll.stderr | 12 + .../issues/issue-40510-1.migrate.nll.stderr | 13 + ...-1.stderr => issue-40510-1.migrate.stderr} | 10 +- src/test/ui/issues/issue-40510-1.nll.stderr | 13 + src/test/ui/issues/issue-40510-1.rs | 12 +- .../issues/issue-40510-3.migrate.nll.stderr | 15 + ...-3.stderr => issue-40510-3.migrate.stderr} | 10 +- src/test/ui/issues/issue-40510-3.nll.stderr | 15 + src/test/ui/issues/issue-40510-3.rs | 12 +- src/test/ui/issues/issue-49824.nll.stderr | 18 + src/test/ui/issues/issue-52213.nll.stderr | 13 + src/test/ui/issues/issue-52533-1.nll.stderr | 11 + src/test/ui/issues/issue-52533.nll.stderr | 11 + .../ui/issues/issue-54302-cases.nll.stderr | 26 ++ src/test/ui/issues/issue-54302.nll.stderr | 8 + src/test/ui/issues/issue-55731.nll.stderr | 11 + src/test/ui/issues/issue-55796.nll.stderr | 20 + src/test/ui/issues/issue-57843.nll.stderr | 8 + .../kindck/kindck-impl-type-params.nll.stderr | 63 +++ .../ui/kindck/kindck-send-object1.nll.stderr | 32 ++ ...etime-bound-will-change-warning.nll.stderr | 20 + ...xisting-name-if-else-using-impl.nll.stderr | 13 + ...isting-name-return-type-is-anon.nll.stderr | 13 + ...-one-existing-name-self-is-anon.nll.stderr | 13 + .../ex2a-push-one-existing-name-2.nll.stderr | 11 + ...h-one-existing-name-early-bound.nll.stderr | 12 + .../ex2a-push-one-existing-name.nll.stderr | 11 + .../ex2b-push-no-existing-names.nll.stderr | 12 + .../ex2c-push-inference-variable.nll.stderr | 13 + .../ex2d-push-inference-variable-2.nll.stderr | 13 + .../ex2e-push-inference-variable-3.nll.stderr | 13 + .../ex3-both-anon-regions-2.nll.stderr | 12 + .../ex3-both-anon-regions-3.nll.stderr | 22 ++ ...anon-regions-both-are-structs-2.nll.stderr | 12 + ...anon-regions-both-are-structs-3.nll.stderr | 13 + ...-are-structs-earlybound-regions.nll.stderr | 13 + ...h-are-structs-latebound-regions.nll.stderr | 12 + ...h-anon-regions-both-are-structs.nll.stderr | 12 + ...-anon-regions-latebound-regions.nll.stderr | 12 + ...th-anon-regions-one-is-struct-2.nll.stderr | 21 + ...th-anon-regions-one-is-struct-3.nll.stderr | 12 + ...th-anon-regions-one-is-struct-4.nll.stderr | 12 + ...both-anon-regions-one-is-struct.nll.stderr | 12 + ...non-regions-return-type-is-anon.nll.stderr | 12 + ...-both-anon-regions-self-is-anon.nll.stderr | 12 + ...oth-anon-regions-using-fn-items.nll.stderr | 21 + ...h-anon-regions-using-impl-items.nll.stderr | 12 + ...non-regions-using-trait-objects.nll.stderr | 21 + .../ex3-both-anon-regions.nll.stderr | 12 + src/test/ui/lub-if.nll.stderr | 20 + src/test/ui/lub-match.nll.stderr | 20 + .../match/match-ref-mut-invariance.nll.stderr | 12 + .../match-ref-mut-let-invariance.nll.stderr | 13 + src/test/ui/nll/get_default.nll.stderr | 48 +++ .../region-ends-after-if-condition.nll.stderr | 15 + ...where-clause-env-wrong-lifetime.nll.stderr | 11 + ...object-lifetime-default-elision.nll.stderr | 13 + ...lifetime-default-from-box-error.nll.stderr | 28 ++ ...ime-default-from-rptr-box-error.nll.stderr | 10 + ...-default-from-rptr-struct-error.nll.stderr | 10 + .../object-lifetime-default-mybox.nll.stderr | 21 + .../pattern-bindings-after-at.nll.stderr | 22 ++ ...rsive-types-are-not-uninhabited.nll.stderr | 16 + ...nvariant-static-error-reporting.nll.stderr | 11 + ...time-bounds-on-fns-where-clause.nll.stderr | 12 + ...time-bounds-on-fns-where-clause.nll.stderr | 12 + .../region-object-lifetime-2.nll.stderr | 12 + .../region-object-lifetime-4.nll.stderr | 12 + ...ion-object-lifetime-in-coercion.nll.stderr | 38 ++ .../regions/regions-addr-of-self.nll.stderr | 10 + .../regions-addr-of-upvar-self.nll.stderr | 35 ++ ...rait-outlives-container.migrate.nll.stderr | 13 + ...unded-by-trait-requiring-static.nll.stderr | 50 +++ ...hod-type-parameters-cross-crate.nll.stderr | 13 + ...hod-type-parameters-trait-bound.nll.stderr | 13 + ...-bounded-method-type-parameters.nll.stderr | 10 + src/test/ui/regions/regions-bounds.nll.stderr | 22 ++ ...ose-associated-type-into-object.nll.stderr | 36 ++ ...ions-close-object-into-object-2.nll.stderr | 20 + ...ions-close-object-into-object-4.nll.stderr | 37 ++ ...ions-close-object-into-object-5.nll.stderr | 29 ++ ...ons-close-over-type-parameter-1.nll.stderr | 20 + ...se-over-type-parameter-multiple.nll.stderr | 13 + ...regions-close-param-into-object.nll.stderr | 36 ++ .../regions-creating-enums3.nll.stderr | 12 + .../regions-creating-enums4.nll.stderr | 12 + ...egions-early-bound-error-method.nll.stderr | 12 + .../regions-early-bound-error.nll.stderr | 12 + .../regions/regions-escape-method.nll.stderr | 11 + ...regions-escape-via-trait-or-not.nll.stderr | 11 + ...ons-free-region-ordering-callee.nll.stderr | 24 ++ ...-region-ordering-caller.migrate.nll.stderr | 33 ++ ...-free-region-ordering-incorrect.nll.stderr | 15 + ...implied-bounds-projection-gap-1.nll.stderr | 11 + ...ons-infer-bound-from-trait-self.nll.stderr | 11 + .../regions-infer-bound-from-trait.nll.stderr | 19 + .../regions/regions-infer-call-3.nll.stderr | 11 + ...nfer-contravariance-due-to-decl.nll.stderr | 13 + ...ns-infer-covariance-due-to-decl.nll.stderr | 13 + ...ns-infer-invariance-due-to-decl.nll.stderr | 10 + ...-invariance-due-to-mutability-3.nll.stderr | 10 + ...-invariance-due-to-mutability-4.nll.stderr | 10 + .../regions-infer-not-param.nll.stderr | 26 ++ .../regions-infer-paramd-indirect.nll.stderr | 13 + .../regions-lifetime-bounds-on-fns.nll.stderr | 12 + .../ui/regions/regions-nested-fns.nll.stderr | 51 +++ ...ojection-container-hrtb.migrate.nll.stderr | 24 ++ ...projection-container-wc.migrate.nll.stderr | 13 + ...s-outlives-projection-container.nll.stderr | 46 +++ ...ow-from-shorter-mut-ref-mut-ref.nll.stderr | 12 + ...s-reborrow-from-shorter-mut-ref.nll.stderr | 12 + .../regions/regions-ret-borrowed-1.nll.stderr | 11 + .../regions/regions-ret-borrowed.nll.stderr | 11 + ...return-ref-to-upvar-issue-17403.nll.stderr | 13 + .../regions-static-bound.ll.nll.stderr | 28 ++ .../regions-static-bound.migrate.nll.stderr | 28 ++ .../regions-trait-object-subtyping.nll.stderr | 24 ++ ...se-covariant-in-second-position.nll.stderr | 13 + ...nce-contravariant-use-covariant.nll.stderr | 13 + ...nce-covariant-use-contravariant.nll.stderr | 13 + ...nce-invariant-use-contravariant.nll.stderr | 13 + ...ariance-invariant-use-covariant.nll.stderr | 11 + .../borrowck-issue-49631.nll.stderr | 14 + .../suggest-impl-trait-lifetime.nll.stderr | 11 + src/test/ui/thread-local-in-ctfe.nll.stderr | 49 +++ ...ument-types-two-region-pointers.nll.stderr | 12 + .../dyn-trait-underscore.nll.stderr | 11 + ...rscore-lifetime-elison-mismatch.nll.stderr | 11 + .../variance-btree-invariant-types.nll.stderr | 106 +++++ .../variance-cell-is-invariant.nll.stderr | 13 + ...riance-contravariant-arg-object.nll.stderr | 24 ++ ...e-contravariant-arg-trait-match.nll.stderr | 24 ++ ...-contravariant-self-trait-match.nll.stderr | 24 ++ .../variance-covariant-arg-object.nll.stderr | 24 ++ ...iance-covariant-arg-trait-match.nll.stderr | 24 ++ ...ance-covariant-self-trait-match.nll.stderr | 24 ++ .../variance-invariant-arg-object.nll.stderr | 24 ++ ...iance-invariant-arg-trait-match.nll.stderr | 24 ++ ...ance-invariant-self-trait-match.nll.stderr | 24 ++ .../variance-trait-matching.nll.stderr | 12 + ...ance-use-contravariant-struct-1.nll.stderr | 13 + ...variance-use-covariant-struct-1.nll.stderr | 13 + ...variance-use-invariant-struct-1.nll.stderr | 24 ++ src/test/ui/wf/wf-static-method.nll.stderr | 65 ++++ src/tools/compiletest/src/runtest.rs | 3 +- 197 files changed, 4503 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.nll.stderr create mode 100644 src/test/ui/associated-types/associated-types-subtyping-1.nll.stderr create mode 100644 src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.nll.stderr create mode 100644 src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.nll.stderr create mode 100644 src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.nll.stderr create mode 100644 src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.nll.stderr create mode 100644 src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.nll.stderr create mode 100644 src/test/ui/borrowck/borrowck-anon-fields-variant.nll.stderr create mode 100644 src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr create mode 100644 src/test/ui/borrowck/borrowck-for-loop-head-linkage.nll.stderr create mode 100644 src/test/ui/borrowck/borrowck-mutate-in-guard.nll.stderr create mode 100644 src/test/ui/borrowck/borrowck-object-lifetime.nll.stderr create mode 100644 src/test/ui/borrowck/borrowck-reborrow-from-shorter-lived-andmut.nll.stderr create mode 100644 src/test/ui/borrowck/issue-7573.nll.stderr create mode 100644 src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr create mode 100644 src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr create mode 100644 src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr create mode 100644 src/test/ui/borrowck/two-phase-reservation-sharing-interference-future-compat-lint.nll.stderr create mode 100644 src/test/ui/c-variadic/variadic-ffi-4.nll.stderr create mode 100644 src/test/ui/closure-expected-type/expect-fn-supply-fn.nll.stderr create mode 100644 src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr create mode 100644 src/test/ui/closures/closure-expected-type/expect-region-supply-region.nll.stderr create mode 100644 src/test/ui/consts/const_let_refutable.nll.stderr create mode 100644 src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr create mode 100644 src/test/ui/consts/min_const_fn/min_const_fn_dyn.nll.stderr create mode 100644 src/test/ui/continue-after-missing-main.nll.stderr create mode 100644 src/test/ui/empty/empty-never-array.nll.stderr create mode 100644 src/test/ui/error-codes/E0502.nll.stderr create mode 100644 src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr create mode 100644 src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr create mode 100644 src/test/ui/generator/auto-trait-regions.nll.stderr create mode 100644 src/test/ui/hashmap-iter-value-lifetime.nll.stderr create mode 100644 src/test/ui/hashmap-lifetimes.nll.stderr create mode 100644 src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.nll.stderr create mode 100644 src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.nll.stderr create mode 100644 src/test/ui/hrtb/hrtb-cache-issue-54302.nll.stderr create mode 100644 src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr create mode 100644 src/test/ui/impl-header-lifetime-elision/dyn-trait.nll.stderr create mode 100644 src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr create mode 100644 src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr create mode 100644 src/test/ui/impl-trait/type_parameters_captured.nll.stderr create mode 100644 src/test/ui/in-band-lifetimes/mismatched.nll.stderr create mode 100644 src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr create mode 100644 src/test/ui/issues/issue-10291.nll.stderr create mode 100644 src/test/ui/issues/issue-13058.nll.stderr create mode 100644 src/test/ui/issues/issue-15034.nll.stderr create mode 100644 src/test/ui/issues/issue-15381.nll.stderr create mode 100644 src/test/ui/issues/issue-16683.nll.stderr create mode 100644 src/test/ui/issues/issue-17728.nll.stderr create mode 100644 src/test/ui/issues/issue-17758.nll.stderr create mode 100644 src/test/ui/issues/issue-26217.nll.stderr create mode 100644 src/test/ui/issues/issue-28848.nll.stderr create mode 100644 src/test/ui/issues/issue-40510-1.migrate.nll.stderr rename src/test/ui/issues/{issue-40510-1.stderr => issue-40510-1.migrate.stderr} (79%) create mode 100644 src/test/ui/issues/issue-40510-1.nll.stderr create mode 100644 src/test/ui/issues/issue-40510-3.migrate.nll.stderr rename src/test/ui/issues/{issue-40510-3.stderr => issue-40510-3.migrate.stderr} (80%) create mode 100644 src/test/ui/issues/issue-40510-3.nll.stderr create mode 100644 src/test/ui/issues/issue-49824.nll.stderr create mode 100644 src/test/ui/issues/issue-52213.nll.stderr create mode 100644 src/test/ui/issues/issue-52533-1.nll.stderr create mode 100644 src/test/ui/issues/issue-52533.nll.stderr create mode 100644 src/test/ui/issues/issue-54302-cases.nll.stderr create mode 100644 src/test/ui/issues/issue-54302.nll.stderr create mode 100644 src/test/ui/issues/issue-55731.nll.stderr create mode 100644 src/test/ui/issues/issue-55796.nll.stderr create mode 100644 src/test/ui/issues/issue-57843.nll.stderr create mode 100644 src/test/ui/kindck/kindck-impl-type-params.nll.stderr create mode 100644 src/test/ui/kindck/kindck-send-object1.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-bound-will-change-warning.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.nll.stderr create mode 100644 src/test/ui/lub-if.nll.stderr create mode 100644 src/test/ui/lub-match.nll.stderr create mode 100644 src/test/ui/match/match-ref-mut-invariance.nll.stderr create mode 100644 src/test/ui/match/match-ref-mut-let-invariance.nll.stderr create mode 100644 src/test/ui/nll/get_default.nll.stderr create mode 100644 src/test/ui/nll/region-ends-after-if-condition.nll.stderr create mode 100644 src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.nll.stderr create mode 100644 src/test/ui/object-lifetime/object-lifetime-default-elision.nll.stderr create mode 100644 src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr create mode 100644 src/test/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.nll.stderr create mode 100644 src/test/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.nll.stderr create mode 100644 src/test/ui/object-lifetime/object-lifetime-default-mybox.nll.stderr create mode 100644 src/test/ui/pattern/pattern-bindings-after-at.nll.stderr create mode 100644 src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr create mode 100644 src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr create mode 100644 src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.nll.stderr create mode 100644 src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.nll.stderr create mode 100644 src/test/ui/regions/region-object-lifetime-2.nll.stderr create mode 100644 src/test/ui/regions/region-object-lifetime-4.nll.stderr create mode 100644 src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr create mode 100644 src/test/ui/regions/regions-addr-of-self.nll.stderr create mode 100644 src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr create mode 100644 src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.nll.stderr create mode 100644 src/test/ui/regions/regions-bounded-by-trait-requiring-static.nll.stderr create mode 100644 src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.nll.stderr create mode 100644 src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr create mode 100644 src/test/ui/regions/regions-bounded-method-type-parameters.nll.stderr create mode 100644 src/test/ui/regions/regions-bounds.nll.stderr create mode 100644 src/test/ui/regions/regions-close-associated-type-into-object.nll.stderr create mode 100644 src/test/ui/regions/regions-close-object-into-object-2.nll.stderr create mode 100644 src/test/ui/regions/regions-close-object-into-object-4.nll.stderr create mode 100644 src/test/ui/regions/regions-close-object-into-object-5.nll.stderr create mode 100644 src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr create mode 100644 src/test/ui/regions/regions-close-over-type-parameter-multiple.nll.stderr create mode 100644 src/test/ui/regions/regions-close-param-into-object.nll.stderr create mode 100644 src/test/ui/regions/regions-creating-enums3.nll.stderr create mode 100644 src/test/ui/regions/regions-creating-enums4.nll.stderr create mode 100644 src/test/ui/regions/regions-early-bound-error-method.nll.stderr create mode 100644 src/test/ui/regions/regions-early-bound-error.nll.stderr create mode 100644 src/test/ui/regions/regions-escape-method.nll.stderr create mode 100644 src/test/ui/regions/regions-escape-via-trait-or-not.nll.stderr create mode 100644 src/test/ui/regions/regions-free-region-ordering-callee.nll.stderr create mode 100644 src/test/ui/regions/regions-free-region-ordering-caller.migrate.nll.stderr create mode 100644 src/test/ui/regions/regions-free-region-ordering-incorrect.nll.stderr create mode 100644 src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr create mode 100644 src/test/ui/regions/regions-infer-bound-from-trait-self.nll.stderr create mode 100644 src/test/ui/regions/regions-infer-bound-from-trait.nll.stderr create mode 100644 src/test/ui/regions/regions-infer-call-3.nll.stderr create mode 100644 src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr create mode 100644 src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr create mode 100644 src/test/ui/regions/regions-infer-invariance-due-to-decl.nll.stderr create mode 100644 src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.nll.stderr create mode 100644 src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.nll.stderr create mode 100644 src/test/ui/regions/regions-infer-not-param.nll.stderr create mode 100644 src/test/ui/regions/regions-infer-paramd-indirect.nll.stderr create mode 100644 src/test/ui/regions/regions-lifetime-bounds-on-fns.nll.stderr create mode 100644 src/test/ui/regions/regions-nested-fns.nll.stderr create mode 100644 src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.nll.stderr create mode 100644 src/test/ui/regions/regions-outlives-projection-container-wc.migrate.nll.stderr create mode 100644 src/test/ui/regions/regions-outlives-projection-container.nll.stderr create mode 100644 src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.nll.stderr create mode 100644 src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.nll.stderr create mode 100644 src/test/ui/regions/regions-ret-borrowed-1.nll.stderr create mode 100644 src/test/ui/regions/regions-ret-borrowed.nll.stderr create mode 100644 src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.nll.stderr create mode 100644 src/test/ui/regions/regions-static-bound.ll.nll.stderr create mode 100644 src/test/ui/regions/regions-static-bound.migrate.nll.stderr create mode 100644 src/test/ui/regions/regions-trait-object-subtyping.nll.stderr create mode 100644 src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr create mode 100644 src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr create mode 100644 src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr create mode 100644 src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr create mode 100644 src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr create mode 100644 src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.nll.stderr create mode 100644 src/test/ui/suggestions/suggest-impl-trait-lifetime.nll.stderr create mode 100644 src/test/ui/thread-local-in-ctfe.nll.stderr create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.nll.stderr create mode 100644 src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr create mode 100644 src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr create mode 100644 src/test/ui/variance/variance-btree-invariant-types.nll.stderr create mode 100644 src/test/ui/variance/variance-cell-is-invariant.nll.stderr create mode 100644 src/test/ui/variance/variance-contravariant-arg-object.nll.stderr create mode 100644 src/test/ui/variance/variance-contravariant-arg-trait-match.nll.stderr create mode 100644 src/test/ui/variance/variance-contravariant-self-trait-match.nll.stderr create mode 100644 src/test/ui/variance/variance-covariant-arg-object.nll.stderr create mode 100644 src/test/ui/variance/variance-covariant-arg-trait-match.nll.stderr create mode 100644 src/test/ui/variance/variance-covariant-self-trait-match.nll.stderr create mode 100644 src/test/ui/variance/variance-invariant-arg-object.nll.stderr create mode 100644 src/test/ui/variance/variance-invariant-arg-trait-match.nll.stderr create mode 100644 src/test/ui/variance/variance-invariant-self-trait-match.nll.stderr create mode 100644 src/test/ui/variance/variance-trait-matching.nll.stderr create mode 100644 src/test/ui/variance/variance-use-contravariant-struct-1.nll.stderr create mode 100644 src/test/ui/variance/variance-use-covariant-struct-1.nll.stderr create mode 100644 src/test/ui/variance/variance-use-invariant-struct-1.nll.stderr create mode 100644 src/test/ui/wf/wf-static-method.nll.stderr diff --git a/src/test/incremental/hashes/closure_expressions.rs b/src/test/incremental/hashes/closure_expressions.rs index 5bfd540eca63..5165f9821fd8 100644 --- a/src/test/incremental/hashes/closure_expressions.rs +++ b/src/test/incremental/hashes/closure_expressions.rs @@ -49,14 +49,14 @@ pub fn add_parameter() { // Change parameter pattern ---------------------------------------------------- #[cfg(cfail1)] pub fn change_parameter_pattern() { - let _ = |x: &u32| x; + let _ = |x: (u32,)| x; } #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", except="HirBody, mir_built, typeck_tables_of")] #[rustc_clean(cfg="cfail3")] pub fn change_parameter_pattern() { - let _ = |&x: &u32| x; + let _ = |(x,): (u32,)| x; } diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.nll.stderr b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.nll.stderr new file mode 100644 index 000000000000..ca99304f9b4a --- /dev/null +++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/associated-types-project-from-hrtb-in-fn-body.rs:22:29 + | +LL | fn bar<'a, 'b, I : for<'x> Foo<&'x isize>>( + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let z: I::A = if cond { x } else { y }; + | ^ assignment requires that `'a` must outlive `'b` + +error: lifetime may not live long enough + --> $DIR/associated-types-project-from-hrtb-in-fn-body.rs:22:40 + | +LL | fn bar<'a, 'b, I : for<'x> Foo<&'x isize>>( + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let z: I::A = if cond { x } else { y }; + | ^ assignment requires that `'b` must outlive `'a` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/associated-types/associated-types-subtyping-1.nll.stderr b/src/test/ui/associated-types/associated-types-subtyping-1.nll.stderr new file mode 100644 index 000000000000..d8506b9c8c81 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-subtyping-1.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/associated-types-subtyping-1.rs:24:12 + | +LL | fn method2<'a,'b,T>(x: &'a T, y: &'b T) + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let a: >::Type = make_any(); + | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: lifetime may not live long enough + --> $DIR/associated-types-subtyping-1.rs:35:13 + | +LL | fn method3<'a,'b,T>(x: &'a T, y: &'b T) + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _c: >::Type = b; + | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.nll.stderr b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.nll.stderr new file mode 100644 index 000000000000..779e6dac92e2 --- /dev/null +++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/project-fn-ret-contravariant.rs:45:4 + | +LL | fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | (a, b) + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + +error: lifetime may not live long enough + --> $DIR/project-fn-ret-contravariant.rs:45:4 + | +LL | fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | (a, b) + | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.nll.stderr b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.nll.stderr new file mode 100644 index 000000000000..f532c96ed2cc --- /dev/null +++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.nll.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/project-fn-ret-contravariant.rs:38:4 + | +LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | bar(foo, x) + | ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.nll.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.nll.stderr new file mode 100644 index 000000000000..c45082fb0538 --- /dev/null +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/project-fn-ret-invariant.rs:55:4 + | +LL | fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | (a, b) + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + +error: lifetime may not live long enough + --> $DIR/project-fn-ret-invariant.rs:55:4 + | +LL | fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | (a, b) + | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.nll.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.nll.stderr new file mode 100644 index 000000000000..2c11e7ffe930 --- /dev/null +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/project-fn-ret-invariant.rs:38:12 + | +LL | fn baz<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let f = foo; // <-- No consistent type can be inferred for `f` here. +LL | let a = bar(f, x); + | ^^^^^^^^^ argument requires that `'a` must outlive `'b` + +error: lifetime may not live long enough + --> $DIR/project-fn-ret-invariant.rs:39:12 + | +LL | fn baz<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let b = bar(f, y); + | ^^^^^^^^^ argument requires that `'b` must outlive `'a` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.nll.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.nll.stderr new file mode 100644 index 000000000000..8be0ad6e88f3 --- /dev/null +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/project-fn-ret-invariant.rs:48:4 + | +LL | fn baz<'a,'b>(x: Type<'a>) -> Type<'static> { + | -- lifetime `'a` defined here +... +LL | bar(foo, x) + | ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/borrowck/borrowck-anon-fields-variant.nll.stderr b/src/test/ui/borrowck/borrowck-anon-fields-variant.nll.stderr new file mode 100644 index 000000000000..f66994b3f100 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-anon-fields-variant.nll.stderr @@ -0,0 +1,40 @@ +error[E0503]: cannot use `y` because it was mutably borrowed + --> $DIR/borrowck-anon-fields-variant.rs:17:7 + | +LL | Foo::Y(ref mut a, _) => a, + | --------- borrow of `y.0` occurs here +... +LL | Foo::Y(_, ref mut b) => b, + | ^^^^^^^^^^^^^^^^^^^^ use of borrowed `y.0` +... +LL | *a += 1; + | ------- borrow later used here + +error[E0503]: cannot use `y` because it was mutably borrowed + --> $DIR/borrowck-anon-fields-variant.rs:37:7 + | +LL | Foo::Y(ref mut a, _) => a, + | --------- borrow of `y.0` occurs here +... +LL | Foo::Y(ref mut b, _) => b, + | ^^^^^^^^^^^^^^^^^^^^ use of borrowed `y.0` +... +LL | *a += 1; + | ------- borrow later used here + +error[E0499]: cannot borrow `y.0` as mutable more than once at a time + --> $DIR/borrowck-anon-fields-variant.rs:37:14 + | +LL | Foo::Y(ref mut a, _) => a, + | --------- first mutable borrow occurs here +... +LL | Foo::Y(ref mut b, _) => b, + | ^^^^^^^^^ second mutable borrow occurs here +... +LL | *a += 1; + | ------- first borrow later used here + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0499, E0503. +For more information about an error, try `rustc --explain E0499`. diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr new file mode 100644 index 000000000000..f1e1ae18839c --- /dev/null +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr @@ -0,0 +1,366 @@ +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/borrowck-describe-lvalue.rs:262:13 + | +LL | let y = &mut x; + | ------ first mutable borrow occurs here +LL | &mut x; + | ^^^^^^ second mutable borrow occurs here +LL | *y = 1; + | ------ first borrow later used here + +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/borrowck-describe-lvalue.rs:272:20 + | +LL | let y = &mut x; + | ------ first mutable borrow occurs here +LL | &mut x; + | ^^^^^^ second mutable borrow occurs here +LL | *y = 1; + | ------ first borrow later used here + +error: captured variable cannot escape `FnMut` closure body + --> $DIR/borrowck-describe-lvalue.rs:270:16 + | +LL | || { + | - inferred to be a `FnMut` closure +LL | / || { +LL | | let y = &mut x; +LL | | &mut x; +LL | | *y = 1; +LL | | drop(y); +LL | | } + | |_________________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body + | + = note: `FnMut` closures only have access to their captured variables while they are executing... + = note: ...therefore, they cannot allow references to captured variables to escape + +error[E0503]: cannot use `f.x` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:41:9 + | +LL | let x = f.x(); + | - borrow of `f` occurs here +LL | f.x; + | ^^^ use of borrowed `f` +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `g.0` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:48:9 + | +LL | let x = g.x(); + | - borrow of `g` occurs here +LL | g.0; + | ^^^ use of borrowed `g` +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `h.0` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:55:9 + | +LL | let x = &mut h.0; + | -------- borrow of `h.0` occurs here +LL | h.0; + | ^^^ use of borrowed `h.0` +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `e.0` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:63:20 + | +LL | let x = e.x(); + | - borrow of `e` occurs here +LL | match e { +LL | Baz::X(value) => value + | ^^^^^ use of borrowed `e` +LL | }; +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `u.a` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:71:9 + | +LL | let x = &mut u.a; + | -------- borrow of `u.a` occurs here +LL | u.a; + | ^^^ use of borrowed `u.a` +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `f.x` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:78:9 + | +LL | let x = f.x(); + | - borrow of `*f` occurs here +LL | f.x; + | ^^^ use of borrowed `*f` +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `g.0` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:85:9 + | +LL | let x = g.x(); + | - borrow of `*g` occurs here +LL | g.0; + | ^^^ use of borrowed `*g` +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `h.0` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:92:9 + | +LL | let x = &mut h.0; + | -------- borrow of `h.0` occurs here +LL | h.0; + | ^^^ use of borrowed `h.0` +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `e.0` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:100:20 + | +LL | let x = e.x(); + | - borrow of `*e` occurs here +LL | match *e { +LL | Baz::X(value) => value + | ^^^^^ use of borrowed `*e` +... +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `u.a` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:109:9 + | +LL | let x = &mut u.a; + | -------- borrow of `u.a` occurs here +LL | u.a; + | ^^^ use of borrowed `u.a` +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `v[..]` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:117:15 + | +LL | let x = &mut v; + | ------ borrow of `v` occurs here +LL | match v { +LL | &[x, _, .., _, _] => println!("{}", x), + | ^ use of borrowed `v` +... +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `v[..]` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:122:18 + | +LL | let x = &mut v; + | ------ borrow of `v` occurs here +... +LL | &[_, x, .., _, _] => println!("{}", x), + | ^ use of borrowed `v` +... +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `v[..]` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:127:25 + | +LL | let x = &mut v; + | ------ borrow of `v` occurs here +... +LL | &[_, _, .., x, _] => println!("{}", x), + | ^ use of borrowed `v` +... +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `v[..]` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:132:28 + | +LL | let x = &mut v; + | ------ borrow of `v` occurs here +... +LL | &[_, _, .., _, x] => println!("{}", x), + | ^ use of borrowed `v` +... +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `v[..]` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:143:15 + | +LL | let x = &mut v; + | ------ borrow of `v` occurs here +LL | match v { +LL | &[x..] => println!("{:?}", x), + | ^ use of borrowed `v` +... +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `v[..]` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:148:18 + | +LL | let x = &mut v; + | ------ borrow of `v` occurs here +... +LL | &[_, x..] => println!("{:?}", x), + | ^ use of borrowed `v` +... +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `v[..]` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:153:15 + | +LL | let x = &mut v; + | ------ borrow of `v` occurs here +... +LL | &[x.., _] => println!("{:?}", x), + | ^ use of borrowed `v` +... +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `v[..]` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:158:18 + | +LL | let x = &mut v; + | ------ borrow of `v` occurs here +... +LL | &[_, x.., _] => println!("{:?}", x), + | ^ use of borrowed `v` +... +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `e` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:171:13 + | +LL | let x = &mut e; + | ------ borrow of `e` occurs here +LL | match e { +LL | E::A(ref ax) => + | ^^^^^^^^^^^^ use of borrowed `e` +... +LL | drop(x); + | - borrow later used here + +error[E0502]: cannot borrow `e.0` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-describe-lvalue.rs:171:18 + | +LL | let x = &mut e; + | ------ mutable borrow occurs here +LL | match e { +LL | E::A(ref ax) => + | ^^^^^^ immutable borrow occurs here +... +LL | drop(x); + | - mutable borrow later used here + +error[E0502]: cannot borrow `e.x` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-describe-lvalue.rs:175:23 + | +LL | let x = &mut e; + | ------ mutable borrow occurs here +... +LL | E::B { x: ref bx } => + | ^^^^^^ immutable borrow occurs here +... +LL | drop(x); + | - mutable borrow later used here + +error[E0502]: cannot borrow `s.y.0` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-describe-lvalue.rs:188:22 + | +LL | let x = &mut s; + | ------ mutable borrow occurs here +LL | match s { +LL | S { y: (ref y0, _), .. } => + | ^^^^^^ immutable borrow occurs here +... +LL | drop(x); + | - mutable borrow later used here + +error[E0502]: cannot borrow `s.x.y` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-describe-lvalue.rs:194:28 + | +LL | let x = &mut s; + | ------ mutable borrow occurs here +... +LL | S { x: F { y: ref x0, .. }, .. } => + | ^^^^^^ immutable borrow occurs here +... +LL | drop(x); + | - mutable borrow later used here + +error[E0503]: cannot use `*v` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:240:9 + | +LL | let x = &mut v; + | ------ borrow of `v` occurs here +LL | v[0].y; + | ^^^^ use of borrowed `v` +... +LL | drop(x); + | - borrow later used here + +error[E0503]: cannot use `v[_].y` because it was mutably borrowed + --> $DIR/borrowck-describe-lvalue.rs:240:9 + | +LL | let x = &mut v; + | ------ borrow of `v` occurs here +LL | v[0].y; + | ^^^^^^ use of borrowed `v` +... +LL | drop(x); + | - borrow later used here + +error[E0502]: cannot borrow `v[..].x` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-describe-lvalue.rs:251:24 + | +LL | let x = &mut v; + | ------ mutable borrow occurs here +LL | match v { +LL | &[_, F {x: ref xf, ..}] => println!("{}", xf), + | ^^^^^^ immutable borrow occurs here +... +LL | drop(x); + | - mutable borrow later used here + +error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-describe-lvalue.rs:210:29 + | +LL | let x = &mut block; + | ---------- mutable borrow occurs here +LL | let p: &'a u8 = &*block.current; + | ^^^^^^^^^^^^^^^ immutable borrow occurs here +... +LL | drop(x); + | - mutable borrow later used here + +error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-describe-lvalue.rs:227:33 + | +LL | let x = &mut block; + | ---------- mutable borrow occurs here +LL | let p : *const u8 = &*(*block).current; + | ^^^^^^^^^^^^^^^^^^ immutable borrow occurs here +... +LL | drop(x); + | - mutable borrow later used here + +error[E0382]: use of moved value: `x` + --> $DIR/borrowck-describe-lvalue.rs:282:22 + | +LL | drop(x); + | - value moved here +LL | drop(x); + | ^ value used here after move + | + = note: move occurs because `x` has type `std::vec::Vec`, which does not implement the `Copy` trait + +error: aborting due to 32 previous errors + +Some errors have detailed explanations: E0382, E0499, E0502, E0503. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/borrowck-for-loop-head-linkage.nll.stderr b/src/test/ui/borrowck/borrowck-for-loop-head-linkage.nll.stderr new file mode 100644 index 000000000000..3468f29fb1a2 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-for-loop-head-linkage.nll.stderr @@ -0,0 +1,27 @@ +error[E0502]: cannot borrow `vector` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-for-loop-head-linkage.rs:7:9 + | +LL | for &x in &vector { + | ------- + | | + | immutable borrow occurs here + | immutable borrow later used here +LL | let cap = vector.capacity(); +LL | vector.extend(repeat(0)); + | ^^^^^^ mutable borrow occurs here + +error[E0502]: cannot borrow `vector` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-for-loop-head-linkage.rs:8:9 + | +LL | for &x in &vector { + | ------- + | | + | immutable borrow occurs here + | immutable borrow later used here +... +LL | vector[1] = 5; + | ^^^^^^ mutable borrow occurs here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/borrowck/borrowck-mutate-in-guard.nll.stderr b/src/test/ui/borrowck/borrowck-mutate-in-guard.nll.stderr new file mode 100644 index 000000000000..7e4a6322d5f5 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-mutate-in-guard.nll.stderr @@ -0,0 +1,41 @@ +error[E0302]: cannot assign in a pattern guard + --> $DIR/borrowck-mutate-in-guard.rs:10:25 + | +LL | Enum::A(_) if { x = Enum::B(false); false } => 1, + | ^^^^^^^^^^^^^^^^^^ assignment in pattern guard + +error[E0301]: cannot mutably borrow in a pattern guard + --> $DIR/borrowck-mutate-in-guard.rs:15:38 + | +LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1, + | ^ borrowed mutably in pattern guard + | + = help: add #![feature(bind_by_move_pattern_guards)] to the crate attributes to enable + +error[E0302]: cannot assign in a pattern guard + --> $DIR/borrowck-mutate-in-guard.rs:15:41 + | +LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1, + | ^^^^^^^^^^^^^^^^^^^ assignment in pattern guard + +error[E0510]: cannot assign `x` in match guard + --> $DIR/borrowck-mutate-in-guard.rs:10:25 + | +LL | match x { + | - value is immutable in match guard +LL | Enum::A(_) if { x = Enum::B(false); false } => 1, + | ^^^^^^^^^^^^^^^^^^ cannot assign + +error[E0510]: cannot mutably borrow `x` in match guard + --> $DIR/borrowck-mutate-in-guard.rs:15:33 + | +LL | match x { + | - value is immutable in match guard +... +LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1, + | ^^^^^^ cannot mutably borrow + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0301, E0302, E0510. +For more information about an error, try `rustc --explain E0301`. diff --git a/src/test/ui/borrowck/borrowck-object-lifetime.nll.stderr b/src/test/ui/borrowck/borrowck-object-lifetime.nll.stderr new file mode 100644 index 000000000000..49c3f861ea99 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-object-lifetime.nll.stderr @@ -0,0 +1,23 @@ +error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-object-lifetime.rs:20:13 + | +LL | let y = x.borrowed(); + | - immutable borrow occurs here +LL | let z = x.mut_borrowed(); + | ^ mutable borrow occurs here +LL | y.use_ref(); + | - immutable borrow later used here + +error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-object-lifetime.rs:26:13 + | +LL | let y = x.borrowed(); + | - immutable borrow occurs here +LL | let z = &mut x; + | ^^^^^^ mutable borrow occurs here +LL | y.use_ref(); + | - immutable borrow later used here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/borrowck/borrowck-reborrow-from-shorter-lived-andmut.nll.stderr b/src/test/ui/borrowck/borrowck-reborrow-from-shorter-lived-andmut.nll.stderr new file mode 100644 index 000000000000..e6d0f88e3ea8 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-reborrow-from-shorter-lived-andmut.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/borrowck-reborrow-from-shorter-lived-andmut.rs:9:5 + | +LL | fn copy_borrowed_ptr<'a,'b>(p: &'a mut S<'b>) -> S<'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | S { pointer: &mut *p.pointer } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/borrowck/issue-7573.nll.stderr b/src/test/ui/borrowck/issue-7573.nll.stderr new file mode 100644 index 000000000000..0da715bbdb76 --- /dev/null +++ b/src/test/ui/borrowck/issue-7573.nll.stderr @@ -0,0 +1,14 @@ +error[E0521]: borrowed data escapes outside of closure + --> $DIR/issue-7573.rs:21:9 + | +LL | let mut lines_to_use: Vec<&CrateId> = Vec::new(); + | ---------------- `lines_to_use` is declared here, outside of the closure body +LL | +LL | let push_id = |installed_id: &CrateId| { + | ------------ `installed_id` is a reference that is only valid in the closure body +... +LL | lines_to_use.push(installed_id); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `installed_id` escapes the closure body here + +error: aborting due to previous error + diff --git a/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr b/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr new file mode 100644 index 000000000000..4797a9d456cc --- /dev/null +++ b/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr @@ -0,0 +1,12 @@ +error[E0521]: borrowed data escapes outside of closure + --> $DIR/regions-escape-bound-fn-2.rs:8:18 + | +LL | let mut x = None; + | ----- `x` is declared here, outside of the closure body +LL | with_int(|y| x = Some(y)); + | - ^^^^^^^^^^^ `y` escapes the closure body here + | | + | `y` is a reference that is only valid in the closure body + +error: aborting due to previous error + diff --git a/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr b/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr new file mode 100644 index 000000000000..2b3a9816e454 --- /dev/null +++ b/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr @@ -0,0 +1,12 @@ +error[E0521]: borrowed data escapes outside of closure + --> $DIR/regions-escape-bound-fn.rs:8:18 + | +LL | let mut x: Option<&isize> = None; + | ----- `x` is declared here, outside of the closure body +LL | with_int(|y| x = Some(y)); + | - ^^^^^^^^^^^ `y` escapes the closure body here + | | + | `y` is a reference that is only valid in the closure body + +error: aborting due to previous error + diff --git a/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr b/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr new file mode 100644 index 000000000000..8ceefd25344a --- /dev/null +++ b/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr @@ -0,0 +1,12 @@ +error[E0521]: borrowed data escapes outside of closure + --> $DIR/regions-escape-unboxed-closure.rs:6:23 + | +LL | let mut x: Option<&isize> = None; + | ----- `x` is declared here, outside of the closure body +LL | with_int(&mut |y| x = Some(y)); + | - ^^^^^^^^^^^ `y` escapes the closure body here + | | + | `y` is a reference that is only valid in the closure body + +error: aborting due to previous error + diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-future-compat-lint.nll.stderr b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-future-compat-lint.nll.stderr new file mode 100644 index 000000000000..d2ea5ab2077e --- /dev/null +++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-future-compat-lint.nll.stderr @@ -0,0 +1,36 @@ +error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable + --> $DIR/two-phase-reservation-sharing-interference-future-compat-lint.rs:13:9 + | +LL | let shared = &v; + | -- immutable borrow occurs here +LL | +LL | v.push(shared.len()); + | ^ ------ immutable borrow later used here + | | + | mutable borrow occurs here + +error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable + --> $DIR/two-phase-reservation-sharing-interference-future-compat-lint.rs:24:9 + | +LL | let shared = &v; + | -- immutable borrow occurs here +LL | +LL | v.push(shared.len()); + | ^ ------ immutable borrow later used here + | | + | mutable borrow occurs here + +error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable + --> $DIR/two-phase-reservation-sharing-interference-future-compat-lint.rs:37:9 + | +LL | let shared = &v; + | -- immutable borrow occurs here +LL | +LL | v.push(shared.len()); + | ^ ------ immutable borrow later used here + | | + | mutable borrow occurs here + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr new file mode 100644 index 000000000000..a1afbb06390f --- /dev/null +++ b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr @@ -0,0 +1,81 @@ +error[E0621]: explicit lifetime required in the type of `ap` + --> $DIR/variadic-ffi-4.rs:8:5 + | +LL | pub unsafe extern "C" fn no_escape0<'a>(_: usize, ap: ...) -> VaList<'a> { + | --- help: add explicit lifetime `'a` to the type of `ap`: `core::ffi::VaList<'a>` +LL | ap + | ^^ lifetime `'a` required + +error[E0621]: explicit lifetime required in the type of `ap` + --> $DIR/variadic-ffi-4.rs:12:5 + | +LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> { + | --- help: add explicit lifetime `'static` to the type of `ap`: `core::ffi::VaList<'static>` +LL | ap + | ^^ lifetime `'static` required + +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:16:33 + | +LL | let _ = ap.with_copy(|ap| { ap }); + | --- ^^ returning this value requires that `'1` must outlive `'2` + | | | + | | return type of closure is core::ffi::VaList<'2> + | has type `core::ffi::VaList<'1>` + +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:20:5 + | +LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaList, mut ap1: ...) { + | ------- ------- has type `core::ffi::VaList<'1>` + | | + | has type `&mut core::ffi::VaList<'2>` +LL | *ap0 = ap1; + | ^^^^^^^^^^ assignment requires that `'1` must outlive `'2` + +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:24:5 + | +LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { + | --- ------- has type `core::ffi::VaList<'2>` + | | + | has type `&mut core::ffi::VaList<'1>` +LL | ap0 = &mut ap1; + | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` + +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:24:5 + | +LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { + | --- ------- has type `core::ffi::VaList<'1>` + | | + | has type `&mut core::ffi::VaList<'2>` +LL | ap0 = &mut ap1; + | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` + +error[E0384]: cannot assign to immutable argument `ap0` + --> $DIR/variadic-ffi-4.rs:24:5 + | +LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { + | --- help: make this binding mutable: `mut ap0` +LL | ap0 = &mut ap1; + | ^^^^^^^^^^^^^^ cannot assign to immutable argument + +error[E0597]: `ap1` does not live long enough + --> $DIR/variadic-ffi-4.rs:24:11 + | +LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { + | - let's call the lifetime of this reference `'1` +LL | ap0 = &mut ap1; + | ------^^^^^^^^ + | | | + | | borrowed value does not live long enough + | assignment requires that `ap1` is borrowed for `'1` +... +LL | } + | - `ap1` dropped here while still borrowed + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0384, E0597, E0621. +For more information about an error, try `rustc --explain E0384`. diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.nll.stderr b/src/test/ui/closure-expected-type/expect-fn-supply-fn.nll.stderr new file mode 100644 index 000000000000..7e4ac4e8ce65 --- /dev/null +++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.nll.stderr @@ -0,0 +1,53 @@ +error[E0631]: type mismatch in closure arguments + --> $DIR/expect-fn-supply-fn.rs:30:5 + | +LL | with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {}); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _` + | | + | expected signature of `fn(fn(&'a u32), &i32) -> _` + | +note: required by `with_closure_expecting_fn_with_free_region` + --> $DIR/expect-fn-supply-fn.rs:1:1 + | +LL | / fn with_closure_expecting_fn_with_free_region(_: F) +LL | | where F: for<'a> FnOnce(fn(&'a u32), &i32) +LL | | { +LL | | } + | |_^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/expect-fn-supply-fn.rs:37:5 + | +LL | with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {}); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _` + | | + | expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _` + | +note: required by `with_closure_expecting_fn_with_bound_region` + --> $DIR/expect-fn-supply-fn.rs:6:1 + | +LL | / fn with_closure_expecting_fn_with_bound_region(_: F) +LL | | where F: FnOnce(fn(&u32), &i32) +LL | | { +LL | | } + | |_^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/expect-fn-supply-fn.rs:46:5 + | +LL | with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _` + | | + | expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _` + | +note: required by `with_closure_expecting_fn_with_bound_region` + --> $DIR/expect-fn-supply-fn.rs:6:1 + | +LL | / fn with_closure_expecting_fn_with_bound_region(_: F) +LL | | where F: FnOnce(fn(&u32), &i32) +LL | | { +LL | | } + | |_^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr new file mode 100644 index 000000000000..1d12e2f585e8 --- /dev/null +++ b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr @@ -0,0 +1,37 @@ +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:5 + | +LL | fn foo(x: &()) { + | --- help: add explicit lifetime `'static` to the type of `x`: `&'static ()` +LL | / bar(|| { +LL | | +LL | | let _ = x; +LL | | }) + | |______^ lifetime `'static` required + +error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function + --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:9 + | +LL | bar(|| { + | ^^ may outlive borrowed value `x` +LL | +LL | let _ = x; + | - `x` is borrowed here + | +note: function requires argument type to outlive `'static` + --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:5 + | +LL | / bar(|| { +LL | | +LL | | let _ = x; +LL | | }) + | |______^ +help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword + | +LL | bar(move || { + | ^^^^^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0373, E0621. +For more information about an error, try `rustc --explain E0373`. diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.nll.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.nll.stderr new file mode 100644 index 000000000000..bbf75302d564 --- /dev/null +++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.nll.stderr @@ -0,0 +1,42 @@ +error[E0521]: borrowed data escapes outside of closure + --> $DIR/expect-region-supply-region.rs:18:9 + | +LL | let mut f: Option<&u32> = None; + | ----- `f` is declared here, outside of the closure body +LL | closure_expecting_bound(|x| { + | - `x` is a reference that is only valid in the closure body +LL | f = Some(x); + | ^^^^^^^^^^^ `x` escapes the closure body here + +error[E0521]: borrowed data escapes outside of closure + --> $DIR/expect-region-supply-region.rs:28:9 + | +LL | let mut f: Option<&u32> = None; + | ----- `f` is declared here, outside of the closure body +LL | closure_expecting_bound(|x: &u32| { + | - `x` is a reference that is only valid in the closure body +LL | f = Some(x); + | ^^^^^^^^^^^ `x` escapes the closure body here + +error: lifetime may not live long enough + --> $DIR/expect-region-supply-region.rs:37:30 + | +LL | fn expect_bound_supply_named<'x>() { + | -- lifetime `'x` defined here +... +LL | closure_expecting_bound(|x: &'x u32| { + | ^ - let's call the lifetime of this reference `'1` + | | + | requires that `'1` must outlive `'x` + +error: lifetime may not live long enough + --> $DIR/expect-region-supply-region.rs:37:30 + | +LL | fn expect_bound_supply_named<'x>() { + | -- lifetime `'x` defined here +... +LL | closure_expecting_bound(|x: &'x u32| { + | ^ requires that `'x` must outlive `'static` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/consts/const_let_refutable.nll.stderr b/src/test/ui/consts/const_let_refutable.nll.stderr new file mode 100644 index 000000000000..30ab1f4d5ec0 --- /dev/null +++ b/src/test/ui/consts/const_let_refutable.nll.stderr @@ -0,0 +1,31 @@ +error[E0005]: refutable pattern in function argument: `&[]` not covered + --> $DIR/const_let_refutable.rs:3:16 + | +LL | const fn slice([a, b]: &[i32]) -> i32 { + | ^^^^^^ pattern `&[]` not covered + +error[E0723]: can only call other `const fn` within a `const fn`, but `const std::ops::Add::add` is not stable as `const fn` + --> $DIR/const_let_refutable.rs:4:5 + | +LL | a + b + | ^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0381]: use of possibly uninitialized variable: `a` + --> $DIR/const_let_refutable.rs:4:5 + | +LL | a + b + | ^ use of possibly uninitialized `a` + +error[E0381]: use of possibly uninitialized variable: `b` + --> $DIR/const_let_refutable.rs:4:9 + | +LL | a + b + | ^ use of possibly uninitialized `b` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0005, E0381, E0723. +For more information about an error, try `rustc --explain E0005`. diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr new file mode 100644 index 000000000000..8d962384a121 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr @@ -0,0 +1,328 @@ +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/min_const_fn.rs:37:25 + | +LL | const fn into_inner(self) -> T { self.0 } + | ^^^^ constant functions cannot evaluate destructors + +error[E0723]: mutable references in const fn are unstable + --> $DIR/min_const_fn.rs:39:36 + | +LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/min_const_fn.rs:44:28 + | +LL | const fn into_inner_lt(self) -> T { self.0 } + | ^^^^ constant functions cannot evaluate destructors + +error[E0723]: mutable references in const fn are unstable + --> $DIR/min_const_fn.rs:46:42 + | +LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } + | ^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/min_const_fn.rs:51:27 + | +LL | const fn into_inner_s(self) -> T { self.0 } + | ^^^^ constant functions cannot evaluate destructors + +error[E0723]: mutable references in const fn are unstable + --> $DIR/min_const_fn.rs:53:38 + | +LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: mutable references in const fn are unstable + --> $DIR/min_const_fn.rs:58:39 + | +LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:76:16 + | +LL | const fn foo11(t: T) -> T { t } + | ^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:78:18 + | +LL | const fn foo11_2(t: T) -> T { t } + | ^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: only int, `bool` and `char` operations are stable in const fn + --> $DIR/min_const_fn.rs:80:33 + | +LL | const fn foo19(f: f32) -> f32 { f * 2.0 } + | ^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: only int, `bool` and `char` operations are stable in const fn + --> $DIR/min_const_fn.rs:82:35 + | +LL | const fn foo19_2(f: f32) -> f32 { 2.0 - f } + | ^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: only int and `bool` operations are stable in const fn + --> $DIR/min_const_fn.rs:84:35 + | +LL | const fn foo19_3(f: f32) -> f32 { -f } + | ^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: only int, `bool` and `char` operations are stable in const fn + --> $DIR/min_const_fn.rs:86:43 + | +LL | const fn foo19_4(f: f32, g: f32) -> f32 { f / g } + | ^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: cannot access `static` items in const fn + --> $DIR/min_const_fn.rs:90:27 + | +LL | const fn foo25() -> u32 { BAR } + | ^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: cannot access `static` items in const fn + --> $DIR/min_const_fn.rs:91:36 + | +LL | const fn foo26() -> &'static u32 { &BAR } + | ^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: casting pointers to ints is unstable in const fn + --> $DIR/min_const_fn.rs:92:42 + | +LL | const fn foo30(x: *const u32) -> usize { x as usize } + | ^^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: casting pointers to ints is unstable in const fn + --> $DIR/min_const_fn.rs:94:63 + | +LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } } + | ^^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: casting pointers to ints is unstable in const fn + --> $DIR/min_const_fn.rs:96:42 + | +LL | const fn foo30_2(x: *mut u32) -> usize { x as usize } + | ^^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: casting pointers to ints is unstable in const fn + --> $DIR/min_const_fn.rs:98:63 + | +LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } } + | ^^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn + --> $DIR/min_const_fn.rs:100:38 + | +LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn + --> $DIR/min_const_fn.rs:102:29 + | +LL | const fn foo30_5(b: bool) { while b { } } + | ^^^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn + --> $DIR/min_const_fn.rs:104:44 + | +LL | const fn foo36(a: bool, b: bool) -> bool { a && b } + | ^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn + --> $DIR/min_const_fn.rs:106:44 + | +LL | const fn foo37(a: bool, b: bool) -> bool { a || b } + | ^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: mutable references in const fn are unstable + --> $DIR/min_const_fn.rs:108:14 + | +LL | const fn inc(x: &mut i32) { *x += 1 } + | ^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:113:6 + | +LL | impl Foo { + | ^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:118:6 + | +LL | impl Foo { + | ^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:123:6 + | +LL | impl Foo { + | ^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: `impl Trait` in const fn is unstable + --> $DIR/min_const_fn.rs:129:24 + | +LL | const fn no_rpit2() -> AlanTuring { AlanTuring(0) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:131:34 + | +LL | const fn no_apit2(_x: AlanTuring) {} + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:133:22 + | +LL | const fn no_apit(_x: impl std::fmt::Debug) {} + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: `impl Trait` in const fn is unstable + --> $DIR/min_const_fn.rs:134:23 + | +LL | const fn no_rpit() -> impl std::fmt::Debug {} + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:135:23 + | +LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} + | ^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:136:32 + | +LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0515]: cannot return reference to temporary value + --> $DIR/min_const_fn.rs:136:63 + | +LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } + | ^-- + | || + | |temporary value created here + | returns a reference to data owned by the current function + +error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:144:41 + | +LL | const fn really_no_traits_i_mean_it() { (&() as &std::fmt::Debug, ()).1 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: function pointers in const fn are unstable + --> $DIR/min_const_fn.rs:147:21 + | +LL | const fn no_fn_ptrs(_x: fn()) {} + | ^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: function pointers in const fn are unstable + --> $DIR/min_const_fn.rs:149:27 + | +LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } + | ^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error: aborting due to 37 previous errors + +Some errors have detailed explanations: E0515, E0723. +For more information about an error, try `rustc --explain E0515`. diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.nll.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.nll.stderr new file mode 100644 index 000000000000..9ffb549057bc --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.nll.stderr @@ -0,0 +1,31 @@ +error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn_dyn.rs:9:5 + | +LL | x.0.field; + | ^^^^^^^^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn_dyn.rs:12:66 + | +LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) } + | ^^ + | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0716]: temporary value dropped while borrowed + --> $DIR/min_const_fn_dyn.rs:12:67 + | +LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) } + | -^ - temporary value is freed at the end of this statement + | || + | |creates a temporary which is freed while still in use + | cast requires that borrow lasts for `'static` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0716, E0723. +For more information about an error, try `rustc --explain E0716`. diff --git a/src/test/ui/continue-after-missing-main.nll.stderr b/src/test/ui/continue-after-missing-main.nll.stderr new file mode 100644 index 000000000000..aceabf331647 --- /dev/null +++ b/src/test/ui/continue-after-missing-main.nll.stderr @@ -0,0 +1,7 @@ +error[E0601]: `main` function not found in crate `continue_after_missing_main` + | + = note: consider adding a `main` function to `$DIR/continue-after-missing-main.rs` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/empty/empty-never-array.nll.stderr b/src/test/ui/empty/empty-never-array.nll.stderr new file mode 100644 index 000000000000..01ee1c3a4d7f --- /dev/null +++ b/src/test/ui/empty/empty-never-array.nll.stderr @@ -0,0 +1,23 @@ +error[E0005]: refutable pattern in local binding: `T(_, _)` not covered + --> $DIR/empty-never-array.rs:10:9 + | +LL | / enum Helper { +LL | | T(T, [!; 0]), +LL | | #[allow(dead_code)] +LL | | U(U), +LL | | } + | |_- `Helper` defined here +... +LL | let Helper::U(u) = Helper::T(t, []); + | ^^^^^^^^^^^^ pattern `T(_, _)` not covered + +error[E0381]: use of possibly uninitialized variable: `u` + --> $DIR/empty-never-array.rs:12:5 + | +LL | u + | ^ use of possibly uninitialized `u` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0005, E0381. +For more information about an error, try `rustc --explain E0005`. diff --git a/src/test/ui/error-codes/E0502.nll.stderr b/src/test/ui/error-codes/E0502.nll.stderr new file mode 100644 index 000000000000..e5671ee49e65 --- /dev/null +++ b/src/test/ui/error-codes/E0502.nll.stderr @@ -0,0 +1,13 @@ +error[E0502]: cannot borrow `*a` as mutable because it is also borrowed as immutable + --> $DIR/E0502.rs:4:9 + | +LL | let ref y = a; + | ----- immutable borrow occurs here +LL | bar(a); + | ^ mutable borrow occurs here +LL | y.use_ref(); + | - immutable borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr new file mode 100644 index 000000000000..5140d1a9a7ad --- /dev/null +++ b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/E0621-does-not-trigger-for-closures.rs:15:45 + | +LL | invoke(&x, |a, b| if a > b { a } else { b }); + | -- ^ returning this value requires that `'1` must outlive `'2` + | || + | |return type of closure is &'2 i32 + | has type `&'1 i32` + +error: aborting due to previous error + diff --git a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr b/src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr new file mode 100644 index 000000000000..f316644156dc --- /dev/null +++ b/src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr @@ -0,0 +1,18 @@ +error: at least one trait must be specified + --> $DIR/generic_type_does_not_live_long_enough.rs:9:35 + | +LL | existential type WrongGeneric: 'static; + | ^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/generic_type_does_not_live_long_enough.rs:6:18 + | +LL | let z: i32 = x; + | ^ expected i32, found opaque type + | + = note: expected type `i32` + found type `WrongGeneric::<&{integer}>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/generator/auto-trait-regions.nll.stderr b/src/test/ui/generator/auto-trait-regions.nll.stderr new file mode 100644 index 000000000000..4c157a05a5e0 --- /dev/null +++ b/src/test/ui/generator/auto-trait-regions.nll.stderr @@ -0,0 +1,41 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/auto-trait-regions.rs:44:24 + | +LL | let a = A(&mut true, &mut true, No); + | ^^^^ - temporary value is freed at the end of this statement + | | + | creates a temporary which is freed while still in use +LL | yield; +LL | assert_foo(a); + | - borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/auto-trait-regions.rs:44:35 + | +LL | let a = A(&mut true, &mut true, No); + | ^^^^ - temporary value is freed at the end of this statement + | | + | creates a temporary which is freed while still in use +LL | yield; +LL | assert_foo(a); + | - borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error: higher-ranked subtype error + --> $DIR/auto-trait-regions.rs:30:5 + | +LL | assert_foo(gen); + | ^^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/auto-trait-regions.rs:48:5 + | +LL | assert_foo(gen); + | ^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0716`. diff --git a/src/test/ui/hashmap-iter-value-lifetime.nll.stderr b/src/test/ui/hashmap-iter-value-lifetime.nll.stderr new file mode 100644 index 000000000000..312a91adca67 --- /dev/null +++ b/src/test/ui/hashmap-iter-value-lifetime.nll.stderr @@ -0,0 +1,15 @@ +error[E0502]: cannot borrow `my_stuff` as mutable because it is also borrowed as immutable + --> $DIR/hashmap-iter-value-lifetime.rs:7:5 + | +LL | let (_, thing) = my_stuff.iter().next().unwrap(); + | -------- immutable borrow occurs here +LL | +LL | my_stuff.clear(); + | ^^^^^^^^ mutable borrow occurs here +LL | +LL | println!("{}", *thing); + | ------ immutable borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/hashmap-lifetimes.nll.stderr b/src/test/ui/hashmap-lifetimes.nll.stderr new file mode 100644 index 000000000000..aa8e890c168d --- /dev/null +++ b/src/test/ui/hashmap-lifetimes.nll.stderr @@ -0,0 +1,13 @@ +error[E0502]: cannot borrow `my_stuff` as mutable because it is also borrowed as immutable + --> $DIR/hashmap-lifetimes.rs:6:5 + | +LL | let mut it = my_stuff.iter(); + | -------- immutable borrow occurs here +LL | my_stuff.insert(1, 43); + | ^^^^^^^^ mutable borrow occurs here +LL | it; + | -- immutable borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.nll.stderr b/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.nll.stderr new file mode 100644 index 000000000000..070fe12a2849 --- /dev/null +++ b/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.nll.stderr @@ -0,0 +1,30 @@ +error: lifetime may not live long enough + --> $DIR/hr-subtype.rs:33:13 + | +LL | fn subtype<'x,'y:'x,'z:'y>() { + | -- -- lifetime `'y` defined here + | | + | lifetime `'x` defined here +LL | gimme::<$t2>(None::<$t1>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'x` must outlive `'y` +... +LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), +LL | | fn(Inv<'y>)) } + | |__________________________________________________- in this macro invocation + +error: lifetime may not live long enough + --> $DIR/hr-subtype.rs:39:13 + | +LL | fn supertype<'x,'y:'x,'z:'y>() { + | -- -- lifetime `'y` defined here + | | + | lifetime `'x` defined here +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'x` must outlive `'y` +... +LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), +LL | | fn(Inv<'y>)) } + | |__________________________________________________- in this macro invocation + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.nll.stderr b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.nll.stderr new file mode 100644 index 000000000000..e140eaadd48a --- /dev/null +++ b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.nll.stderr @@ -0,0 +1,16 @@ +error: lifetime may not live long enough + --> $DIR/hr-subtype.rs:39:13 + | +LL | fn supertype<'x,'y:'x,'z:'y>() { + | -- -- lifetime `'y` defined here + | | + | lifetime `'x` defined here +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'x` must outlive `'y` +... +LL | / check! { free_x_vs_free_y: (fn(&'x u32), +LL | | fn(&'y u32)) } + | |__________________________________________- in this macro invocation + +error: aborting due to previous error + diff --git a/src/test/ui/hrtb/hrtb-cache-issue-54302.nll.stderr b/src/test/ui/hrtb/hrtb-cache-issue-54302.nll.stderr new file mode 100644 index 000000000000..4de35d70c30a --- /dev/null +++ b/src/test/ui/hrtb/hrtb-cache-issue-54302.nll.stderr @@ -0,0 +1,8 @@ +error: higher-ranked subtype error + --> $DIR/hrtb-cache-issue-54302.rs:19:5 + | +LL | assert_deserialize_owned::<&'static str>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr new file mode 100644 index 000000000000..0522fc45d68f --- /dev/null +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr @@ -0,0 +1,77 @@ +warning: function cannot return without recursing + --> $DIR/hrtb-perfect-forwarding.rs:22:1 + | +LL | / fn no_hrtb<'b,T>(mut t: T) +LL | | where T : Bar<&'b isize> +LL | | { +LL | | // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that +LL | | // `&mut T : Bar<&'b isize>`. +LL | | no_hrtb(&mut t); + | | --------------- recursive call site +LL | | } + | |_^ cannot return without recursing + | + = note: #[warn(unconditional_recursion)] on by default + = help: a `loop` may express intention better if this is on purpose + +warning: function cannot return without recursing + --> $DIR/hrtb-perfect-forwarding.rs:30:1 + | +LL | / fn bar_hrtb(mut t: T) +LL | | where T : for<'b> Bar<&'b isize> +LL | | { +LL | | // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above +... | +LL | | bar_hrtb(&mut t); + | | ---------------- recursive call site +LL | | } + | |_^ cannot return without recursing + | + = help: a `loop` may express intention better if this is on purpose + +warning: function cannot return without recursing + --> $DIR/hrtb-perfect-forwarding.rs:39:1 + | +LL | / fn foo_hrtb_bar_not<'b,T>(mut t: T) +LL | | where T : for<'a> Foo<&'a isize> + Bar<&'b isize> +LL | | { +LL | | // Not OK -- The forwarding impl for `Foo` requires that `Bar` also +... | +LL | | foo_hrtb_bar_not(&mut t); + | | ------------------------ recursive call site +LL | | } + | |_^ cannot return without recursing + | + = help: a `loop` may express intention better if this is on purpose + +error: higher-ranked subtype error + --> $DIR/hrtb-perfect-forwarding.rs:46:5 + | +LL | foo_hrtb_bar_not(&mut t); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: lifetime may not live long enough + --> $DIR/hrtb-perfect-forwarding.rs:46:5 + | +LL | fn foo_hrtb_bar_not<'b,T>(mut t: T) + | -- lifetime `'b` defined here +... +LL | foo_hrtb_bar_not(&mut t); + | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static` + +warning: function cannot return without recursing + --> $DIR/hrtb-perfect-forwarding.rs:49:1 + | +LL | / fn foo_hrtb_bar_hrtb(mut t: T) +LL | | where T : for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize> +LL | | { +LL | | // OK -- now we have `T : for<'b> Bar&'b isize>`. +LL | | foo_hrtb_bar_hrtb(&mut t); + | | ------------------------- recursive call site +LL | | } + | |_^ cannot return without recursing + | + = help: a `loop` may express intention better if this is on purpose + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/impl-header-lifetime-elision/dyn-trait.nll.stderr b/src/test/ui/impl-header-lifetime-elision/dyn-trait.nll.stderr new file mode 100644 index 000000000000..da30997a2311 --- /dev/null +++ b/src/test/ui/impl-header-lifetime-elision/dyn-trait.nll.stderr @@ -0,0 +1,10 @@ +error[E0521]: borrowed data escapes outside of function + --> $DIR/dyn-trait.rs:20:5 + | +LL | fn with_dyn_debug_static<'a>(x: Box) { + | - `x` is a reference that is only valid in the function body +LL | static_val(x); + | ^^^^^^^^^^^^^ `x` escapes the function body here + +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr new file mode 100644 index 000000000000..4b7c04f1e433 --- /dev/null +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr @@ -0,0 +1,51 @@ +error: lifetime may not live long enough + --> $DIR/must_outlive_least_region_or_bound.rs:3:23 + | +LL | fn elided(x: &i32) -> impl Copy { x } + | - ^^^^^^^^^ opaque type requires that `'1` must outlive `'static` + | | + | let's call the lifetime of this reference `'1` +help: to allow this impl Trait to capture borrowed data with lifetime `'1`, add `'_` as a constraint + | +LL | fn elided(x: &i32) -> impl Copy + '_ { x } + | ^^^^^^^^^^^^^^ + +error: lifetime may not live long enough + --> $DIR/must_outlive_least_region_or_bound.rs:6:32 + | +LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } + | -- ^^^^^^^^^ opaque type requires that `'a` must outlive `'static` + | | + | lifetime `'a` defined here +help: to allow this impl Trait to capture borrowed data with lifetime `'a`, add `'a` as a constraint + | +LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } + | ^^^^^^^^^^^^^^ + +error: lifetime may not live long enough + --> $DIR/must_outlive_least_region_or_bound.rs:12:69 + | +LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } + | -- lifetime `'a` defined here ^ returning this value requires that `'a` must outlive `'static` + | + = help: consider replacing `'a` with `'static` + +error: lifetime may not live long enough + --> $DIR/must_outlive_least_region_or_bound.rs:17:61 + | +LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { + | -- -- lifetime `'b` defined here ^^^^^^^^^^^^^^^^ opaque type requires that `'b` must outlive `'a` + | | + | lifetime `'a` defined here + +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/must_outlive_least_region_or_bound.rs:22:51 + | +LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `T: 'static`... + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0310`. diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr new file mode 100644 index 000000000000..0bf120cf7ecc --- /dev/null +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr @@ -0,0 +1,26 @@ +error: lifetime may not live long enough + --> $DIR/static-return-lifetime-infered.rs:6:35 + | +LL | fn iter_values_anon(&self) -> impl Iterator { + | - ^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static` + | | + | let's call the lifetime of this reference `'1` +help: to allow this impl Trait to capture borrowed data with lifetime `'1`, add `'_` as a constraint + | +LL | fn iter_values_anon(&self) -> impl Iterator + '_ { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: lifetime may not live long enough + --> $DIR/static-return-lifetime-infered.rs:10:37 + | +LL | fn iter_values<'a>(&'a self) -> impl Iterator { + | -- ^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'static` + | | + | lifetime `'a` defined here +help: to allow this impl Trait to capture borrowed data with lifetime `'a`, add `'a` as a constraint + | +LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/impl-trait/type_parameters_captured.nll.stderr b/src/test/ui/impl-trait/type_parameters_captured.nll.stderr new file mode 100644 index 000000000000..039cb62f8665 --- /dev/null +++ b/src/test/ui/impl-trait/type_parameters_captured.nll.stderr @@ -0,0 +1,11 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/type_parameters_captured.rs:7:20 + | +LL | fn foo(x: T) -> impl Any + 'static { + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `T: 'static`... + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/src/test/ui/in-band-lifetimes/mismatched.nll.stderr b/src/test/ui/in-band-lifetimes/mismatched.nll.stderr new file mode 100644 index 000000000000..f5aee2d2d7e5 --- /dev/null +++ b/src/test/ui/in-band-lifetimes/mismatched.nll.stderr @@ -0,0 +1,20 @@ +error[E0621]: explicit lifetime required in the type of `y` + --> $DIR/mismatched.rs:4:42 + | +LL | fn foo(x: &'a u32, y: &u32) -> &'a u32 { y } + | ---- ^ lifetime `'a` required + | | + | help: add explicit lifetime `'a` to the type of `y`: `&'a u32` + +error: lifetime may not live long enough + --> $DIR/mismatched.rs:6:46 + | +LL | fn foo2(x: &'a u32, y: &'b u32) -> &'a u32 { y } + | -- -- ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | | | + | | lifetime `'b` defined here + | lifetime `'a` defined here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr new file mode 100644 index 000000000000..cd65bab2d466 --- /dev/null +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr @@ -0,0 +1,24 @@ +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements + --> $DIR/mismatched_trait_impl.rs:9:5 + | +LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 9:5... + --> $DIR/mismatched_trait_impl.rs:9:5 + | +LL | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { +LL | | x +LL | | } + | |_____^ +note: ...but the lifetime must also be valid for the lifetime 'a as defined on the method body at 9:32... + --> $DIR/mismatched_trait_impl.rs:9:32 + | +LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { + | ^^ + = note: ...so that the method type is compatible with trait: + expected fn(&i32, &'a u32, &u32) -> &'a u32 + found fn(&i32, &u32, &u32) -> &u32 + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-10291.nll.stderr b/src/test/ui/issues/issue-10291.nll.stderr new file mode 100644 index 000000000000..45f29fd79565 --- /dev/null +++ b/src/test/ui/issues/issue-10291.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/issue-10291.rs:3:9 + | +LL | fn test<'x>(x: &'x isize) { + | -- lifetime `'x` defined here +LL | drop:: FnMut(&'z isize) -> &'z isize>>(Box::new(|z| { +LL | x + | ^ returning this value requires that `'x` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-13058.nll.stderr b/src/test/ui/issues/issue-13058.nll.stderr new file mode 100644 index 000000000000..8368978deab1 --- /dev/null +++ b/src/test/ui/issues/issue-13058.nll.stderr @@ -0,0 +1,12 @@ +error[E0621]: explicit lifetime required in the type of `cont` + --> $DIR/issue-13058.rs:14:21 + | +LL | fn check<'r, I: Iterator, T: Itble<'r, usize, I>>(cont: &T) -> bool + | -- help: add explicit lifetime `'r` to the type of `cont`: `&'r T` +LL | { +LL | let cont_iter = cont.iter(); + | ^^^^^^^^^^^ lifetime `'r` required + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/issues/issue-15034.nll.stderr b/src/test/ui/issues/issue-15034.nll.stderr new file mode 100644 index 000000000000..f142e260a231 --- /dev/null +++ b/src/test/ui/issues/issue-15034.nll.stderr @@ -0,0 +1,11 @@ +error[E0621]: explicit lifetime required in the type of `lexer` + --> $DIR/issue-15034.rs:17:9 + | +LL | pub fn new(lexer: &'a mut Lexer) -> Parser<'a> { + | ------------- help: add explicit lifetime `'a` to the type of `lexer`: `&'a mut Lexer<'a>` +LL | Parser { lexer: lexer } + | ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/issues/issue-15381.nll.stderr b/src/test/ui/issues/issue-15381.nll.stderr new file mode 100644 index 000000000000..a8495846b361 --- /dev/null +++ b/src/test/ui/issues/issue-15381.nll.stderr @@ -0,0 +1,16 @@ +error[E0005]: refutable pattern in `for` loop binding: `&[]` not covered + --> $DIR/issue-15381.rs:4:9 + | +LL | for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) { + | ^^^^^^^^ pattern `&[]` not covered + +error[E0381]: borrow of possibly uninitialized variable: `y` + --> $DIR/issue-15381.rs:6:26 + | +LL | println!("y={}", y); + | ^ use of possibly uninitialized `y` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0005, E0381. +For more information about an error, try `rustc --explain E0005`. diff --git a/src/test/ui/issues/issue-16683.nll.stderr b/src/test/ui/issues/issue-16683.nll.stderr new file mode 100644 index 000000000000..ea6b69d1a76c --- /dev/null +++ b/src/test/ui/issues/issue-16683.nll.stderr @@ -0,0 +1,10 @@ +error[E0521]: borrowed data escapes outside of function + --> $DIR/issue-16683.rs:4:9 + | +LL | fn b(&self) { + | ----- `self` is a reference that is only valid in the function body +LL | self.a(); + | ^^^^^^^^ `self` escapes the function body here + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-17728.nll.stderr b/src/test/ui/issues/issue-17728.nll.stderr new file mode 100644 index 000000000000..7436ebd920ee --- /dev/null +++ b/src/test/ui/issues/issue-17728.nll.stderr @@ -0,0 +1,21 @@ +error[E0308]: match arms have incompatible types + --> $DIR/issue-17728.rs:109:14 + | +LL | / match to_parse { +LL | | "w" | "west" => RoomDirection::West, +LL | | "e" | "east" => RoomDirection::East, +LL | | "n" | "north" => RoomDirection::North, +... | +LL | | "down" => RoomDirection::Down, + | | ------------------- this and all prior arms are found to be of type `RoomDirection` +LL | | _ => None + | | ^^^^ expected enum `RoomDirection`, found enum `std::option::Option` +LL | | } + | |_____- `match` arms have incompatible types + | + = note: expected type `RoomDirection` + found type `std::option::Option<_>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-17758.nll.stderr b/src/test/ui/issues/issue-17758.nll.stderr new file mode 100644 index 000000000000..b9dc9da3683d --- /dev/null +++ b/src/test/ui/issues/issue-17758.nll.stderr @@ -0,0 +1,10 @@ +error[E0521]: borrowed data escapes outside of function + --> $DIR/issue-17758.rs:7:9 + | +LL | fn bar(&self) { + | ----- `self` is a reference that is only valid in the function body +LL | self.foo(); + | ^^^^^^^^^^ `self` escapes the function body here + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-26217.nll.stderr b/src/test/ui/issues/issue-26217.nll.stderr new file mode 100644 index 000000000000..c7601caacdca --- /dev/null +++ b/src/test/ui/issues/issue-26217.nll.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/issue-26217.rs:4:5 + | +LL | fn bar<'a>() { + | -- lifetime `'a` defined here +LL | foo::<&'a i32>(); + | ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-28848.nll.stderr b/src/test/ui/issues/issue-28848.nll.stderr new file mode 100644 index 000000000000..5cf9856e4dc7 --- /dev/null +++ b/src/test/ui/issues/issue-28848.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/issue-28848.rs:10:5 + | +LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | Foo::<'a, 'b>::xmute(u) + | ^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-40510-1.migrate.nll.stderr b/src/test/ui/issues/issue-40510-1.migrate.nll.stderr new file mode 100644 index 000000000000..776a724d3106 --- /dev/null +++ b/src/test/ui/issues/issue-40510-1.migrate.nll.stderr @@ -0,0 +1,13 @@ +error: captured variable cannot escape `FnMut` closure body + --> $DIR/issue-40510-1.rs:11:9 + | +LL | || { + | - inferred to be a `FnMut` closure +LL | &mut x + | ^^^^^^ returns a reference to a captured variable which escapes the closure body + | + = note: `FnMut` closures only have access to their captured variables while they are executing... + = note: ...therefore, they cannot allow references to captured variables to escape + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-40510-1.stderr b/src/test/ui/issues/issue-40510-1.migrate.stderr similarity index 79% rename from src/test/ui/issues/issue-40510-1.stderr rename to src/test/ui/issues/issue-40510-1.migrate.stderr index 44234cbc8816..17d1c48d0754 100644 --- a/src/test/ui/issues/issue-40510-1.stderr +++ b/src/test/ui/issues/issue-40510-1.migrate.stderr @@ -1,5 +1,5 @@ warning: captured variable cannot escape `FnMut` closure body - --> $DIR/issue-40510-1.rs:8:9 + --> $DIR/issue-40510-1.rs:11:9 | LL | || { | - inferred to be a `FnMut` closure @@ -11,3 +11,11 @@ LL | &mut x = warning: this error has been downgraded to a warning for backwards compatibility with previous releases = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future +error: compilation successful + --> $DIR/issue-40510-1.rs:20:1 + | +LL | fn main() {} + | ^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-40510-1.nll.stderr b/src/test/ui/issues/issue-40510-1.nll.stderr new file mode 100644 index 000000000000..776a724d3106 --- /dev/null +++ b/src/test/ui/issues/issue-40510-1.nll.stderr @@ -0,0 +1,13 @@ +error: captured variable cannot escape `FnMut` closure body + --> $DIR/issue-40510-1.rs:11:9 + | +LL | || { + | - inferred to be a `FnMut` closure +LL | &mut x + | ^^^^^^ returns a reference to a captured variable which escapes the closure body + | + = note: `FnMut` closures only have access to their captured variables while they are executing... + = note: ...therefore, they cannot allow references to captured variables to escape + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-40510-1.rs b/src/test/ui/issues/issue-40510-1.rs index dd8a6bc5ab2b..6ecbeefd8811 100644 --- a/src/test/ui/issues/issue-40510-1.rs +++ b/src/test/ui/issues/issue-40510-1.rs @@ -1,13 +1,21 @@ -// compile-pass +#![feature(rustc_attrs)] #![allow(unused)] +// revisions: migrate nll +#![cfg_attr(nll, feature(nll))] + fn f() { let mut x: Box<()> = Box::new(()); || { &mut x }; + //[migrate]~^^ WARNING captured variable cannot escape `FnMut` closure body + //[migrate]~| WARNING this error has been downgraded to a warning + //[migrate]~| WARNING this warning will become a hard error in the future + //[nll]~^^^^^ ERROR captured variable cannot escape `FnMut` closure body } - +#[rustc_error] fn main() {} +//[migrate]~^ ERROR diff --git a/src/test/ui/issues/issue-40510-3.migrate.nll.stderr b/src/test/ui/issues/issue-40510-3.migrate.nll.stderr new file mode 100644 index 000000000000..a49475a8570a --- /dev/null +++ b/src/test/ui/issues/issue-40510-3.migrate.nll.stderr @@ -0,0 +1,15 @@ +error: captured variable cannot escape `FnMut` closure body + --> $DIR/issue-40510-3.rs:11:9 + | +LL | || { + | - inferred to be a `FnMut` closure +LL | / || { +LL | | x.push(()) +LL | | } + | |_________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body + | + = note: `FnMut` closures only have access to their captured variables while they are executing... + = note: ...therefore, they cannot allow references to captured variables to escape + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-40510-3.stderr b/src/test/ui/issues/issue-40510-3.migrate.stderr similarity index 80% rename from src/test/ui/issues/issue-40510-3.stderr rename to src/test/ui/issues/issue-40510-3.migrate.stderr index 1297e1418981..692aa1053779 100644 --- a/src/test/ui/issues/issue-40510-3.stderr +++ b/src/test/ui/issues/issue-40510-3.migrate.stderr @@ -1,5 +1,5 @@ warning: captured variable cannot escape `FnMut` closure body - --> $DIR/issue-40510-3.rs:8:9 + --> $DIR/issue-40510-3.rs:11:9 | LL | || { | - inferred to be a `FnMut` closure @@ -13,3 +13,11 @@ LL | | } = warning: this error has been downgraded to a warning for backwards compatibility with previous releases = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future +error: compilation successful + --> $DIR/issue-40510-3.rs:22:1 + | +LL | fn main() {} + | ^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-40510-3.nll.stderr b/src/test/ui/issues/issue-40510-3.nll.stderr new file mode 100644 index 000000000000..a49475a8570a --- /dev/null +++ b/src/test/ui/issues/issue-40510-3.nll.stderr @@ -0,0 +1,15 @@ +error: captured variable cannot escape `FnMut` closure body + --> $DIR/issue-40510-3.rs:11:9 + | +LL | || { + | - inferred to be a `FnMut` closure +LL | / || { +LL | | x.push(()) +LL | | } + | |_________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body + | + = note: `FnMut` closures only have access to their captured variables while they are executing... + = note: ...therefore, they cannot allow references to captured variables to escape + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-40510-3.rs b/src/test/ui/issues/issue-40510-3.rs index bc95c461d1e1..205d98236312 100644 --- a/src/test/ui/issues/issue-40510-3.rs +++ b/src/test/ui/issues/issue-40510-3.rs @@ -1,6 +1,9 @@ -// compile-pass +#![feature(rustc_attrs)] #![allow(unused)] +// revisions: migrate nll +#![cfg_attr(nll, feature(nll))] + fn f() { let mut x: Vec<()> = Vec::new(); @@ -8,8 +11,13 @@ fn f() { || { x.push(()) } + //[migrate]~^^^ WARNING captured variable cannot escape `FnMut` closure body + //[migrate]~| WARNING this error has been downgraded to a warning + //[migrate]~| WARNING this warning will become a hard error in the future + //[nll]~^^^^^^ ERROR captured variable cannot escape `FnMut` closure body }; } - +#[rustc_error] fn main() {} +//[migrate]~^ ERROR diff --git a/src/test/ui/issues/issue-49824.nll.stderr b/src/test/ui/issues/issue-49824.nll.stderr new file mode 100644 index 000000000000..9c6f8d4532a7 --- /dev/null +++ b/src/test/ui/issues/issue-49824.nll.stderr @@ -0,0 +1,18 @@ +error: captured variable cannot escape `FnMut` closure body + --> $DIR/issue-49824.rs:10:9 + | +LL | || { + | - inferred to be a `FnMut` closure +LL | / || { +LL | | +LL | | +LL | | +LL | | let _y = &mut x; +LL | | } + | |_________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body + | + = note: `FnMut` closures only have access to their captured variables while they are executing... + = note: ...therefore, they cannot allow references to captured variables to escape + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-52213.nll.stderr b/src/test/ui/issues/issue-52213.nll.stderr new file mode 100644 index 000000000000..eba875de2152 --- /dev/null +++ b/src/test/ui/issues/issue-52213.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/issue-52213.rs:3:20 + | +LL | fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | match (&t,) { +LL | ((u,),) => u, + | ^ returning this value requires that `'a` must outlive `'b` + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-52533-1.nll.stderr b/src/test/ui/issues/issue-52533-1.nll.stderr new file mode 100644 index 000000000000..20f19b259671 --- /dev/null +++ b/src/test/ui/issues/issue-52533-1.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/issue-52533-1.rs:9:18 + | +LL | gimme(|x, y| y) + | - - ^ closure was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | | | + | | has type `&Foo<'_, '1, u32>` + | has type `&Foo<'_, '2, u32>` + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-52533.nll.stderr b/src/test/ui/issues/issue-52533.nll.stderr new file mode 100644 index 000000000000..c764736d7987 --- /dev/null +++ b/src/test/ui/issues/issue-52533.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/issue-52533.rs:5:16 + | +LL | foo(|a, b| b) + | - - ^ closure was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | | | + | | has type `&'1 u32` + | has type `&'2 u32` + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-54302-cases.nll.stderr b/src/test/ui/issues/issue-54302-cases.nll.stderr new file mode 100644 index 000000000000..7463a3f286f4 --- /dev/null +++ b/src/test/ui/issues/issue-54302-cases.nll.stderr @@ -0,0 +1,26 @@ +error: higher-ranked subtype error + --> $DIR/issue-54302-cases.rs:63:5 + | +LL | >::ref_foo(a) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-54302-cases.rs:69:5 + | +LL | >::ref_foo(a) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-54302-cases.rs:75:5 + | +LL | >::ref_foo(a) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-54302-cases.rs:81:5 + | +LL | >::ref_foo(a) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/issues/issue-54302.nll.stderr b/src/test/ui/issues/issue-54302.nll.stderr new file mode 100644 index 000000000000..e68de0312824 --- /dev/null +++ b/src/test/ui/issues/issue-54302.nll.stderr @@ -0,0 +1,8 @@ +error: higher-ranked subtype error + --> $DIR/issue-54302.rs:13:5 + | +LL | assert_deserialize_owned::<&'static str>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-55731.nll.stderr b/src/test/ui/issues/issue-55731.nll.stderr new file mode 100644 index 000000000000..dd38bb629125 --- /dev/null +++ b/src/test/ui/issues/issue-55731.nll.stderr @@ -0,0 +1,11 @@ +error: higher-ranked subtype error + --> $DIR/issue-55731.rs:48:5 + | +LL | / multi(Map { +LL | | i: Cloned(PhantomData), +LL | | f: X, +LL | | }); + | |______^ + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-55796.nll.stderr b/src/test/ui/issues/issue-55796.nll.stderr new file mode 100644 index 000000000000..5809a56cd4b6 --- /dev/null +++ b/src/test/ui/issues/issue-55796.nll.stderr @@ -0,0 +1,20 @@ +error: lifetime may not live long enough + --> $DIR/issue-55796.rs:16:9 + | +LL | pub trait Graph<'a> { + | -- lifetime `'a` defined here +... +LL | Box::new(self.out_edges(u).map(|e| e.target())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/issue-55796.rs:21:9 + | +LL | pub trait Graph<'a> { + | -- lifetime `'a` defined here +... +LL | Box::new(self.in_edges(u).map(|e| e.target())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/issues/issue-57843.nll.stderr b/src/test/ui/issues/issue-57843.nll.stderr new file mode 100644 index 000000000000..70310780b433 --- /dev/null +++ b/src/test/ui/issues/issue-57843.nll.stderr @@ -0,0 +1,8 @@ +error: higher-ranked subtype error + --> $DIR/issue-57843.rs:23:9 + | +LL | Foo(Box::new(|_| ())); + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/kindck/kindck-impl-type-params.nll.stderr b/src/test/ui/kindck/kindck-impl-type-params.nll.stderr new file mode 100644 index 000000000000..c1f662fda610 --- /dev/null +++ b/src/test/ui/kindck/kindck-impl-type-params.nll.stderr @@ -0,0 +1,63 @@ +error[E0277]: `T` cannot be sent between threads safely + --> $DIR/kindck-impl-type-params.rs:18:13 + | +LL | let a = &t as &Gettable; + | ^^ `T` cannot be sent between threads safely + | + = help: the trait `std::marker::Send` is not implemented for `T` + = help: consider adding a `where T: std::marker::Send` bound + = note: required because of the requirements on the impl of `Gettable` for `S` + = note: required for the cast to the object type `dyn Gettable` + +error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied + --> $DIR/kindck-impl-type-params.rs:18:13 + | +LL | let a = &t as &Gettable; + | ^^ the trait `std::marker::Copy` is not implemented for `T` + | + = help: consider adding a `where T: std::marker::Copy` bound + = note: required because of the requirements on the impl of `Gettable` for `S` + = note: required for the cast to the object type `dyn Gettable` + +error[E0277]: `T` cannot be sent between threads safely + --> $DIR/kindck-impl-type-params.rs:25:27 + | +LL | let a: &Gettable = &t; + | ^^ `T` cannot be sent between threads safely + | + = help: the trait `std::marker::Send` is not implemented for `T` + = help: consider adding a `where T: std::marker::Send` bound + = note: required because of the requirements on the impl of `Gettable` for `S` + = note: required for the cast to the object type `dyn Gettable` + +error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied + --> $DIR/kindck-impl-type-params.rs:25:27 + | +LL | let a: &Gettable = &t; + | ^^ the trait `std::marker::Copy` is not implemented for `T` + | + = help: consider adding a `where T: std::marker::Copy` bound + = note: required because of the requirements on the impl of `Gettable` for `S` + = note: required for the cast to the object type `dyn Gettable` + +error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied + --> $DIR/kindck-impl-type-params.rs:38:13 + | +LL | let a = t as Box>; + | ^ the trait `std::marker::Copy` is not implemented for `std::string::String` + | + = note: required because of the requirements on the impl of `Gettable` for `S` + = note: required for the cast to the object type `dyn Gettable` + +error[E0277]: the trait bound `foo3::Foo: std::marker::Copy` is not satisfied + --> $DIR/kindck-impl-type-params.rs:46:33 + | +LL | let a: Box> = t; + | ^ the trait `std::marker::Copy` is not implemented for `foo3::Foo` + | + = note: required because of the requirements on the impl of `Gettable` for `S` + = note: required for the cast to the object type `dyn Gettable` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/kindck/kindck-send-object1.nll.stderr b/src/test/ui/kindck/kindck-send-object1.nll.stderr new file mode 100644 index 000000000000..1df7412132bd --- /dev/null +++ b/src/test/ui/kindck/kindck-send-object1.nll.stderr @@ -0,0 +1,32 @@ +error[E0277]: `(dyn Dummy + 'a)` cannot be shared between threads safely + --> $DIR/kindck-send-object1.rs:10:5 + | +LL | assert_send::<&'a Dummy>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely + | + = help: the trait `std::marker::Sync` is not implemented for `(dyn Dummy + 'a)` + = note: required because of the requirements on the impl of `std::marker::Send` for `&'a (dyn Dummy + 'a)` +note: required by `assert_send` + --> $DIR/kindck-send-object1.rs:5:1 + | +LL | fn assert_send() { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely + --> $DIR/kindck-send-object1.rs:29:5 + | +LL | assert_send::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely + | + = help: the trait `std::marker::Send` is not implemented for `(dyn Dummy + 'a)` + = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<(dyn Dummy + 'a)>` + = note: required because it appears within the type `std::boxed::Box<(dyn Dummy + 'a)>` +note: required by `assert_send` + --> $DIR/kindck-send-object1.rs:5:1 + | +LL | fn assert_send() { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/lifetimes/lifetime-bound-will-change-warning.nll.stderr b/src/test/ui/lifetimes/lifetime-bound-will-change-warning.nll.stderr new file mode 100644 index 000000000000..8b24563e9200 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-bound-will-change-warning.nll.stderr @@ -0,0 +1,20 @@ +error[E0521]: borrowed data escapes outside of function + --> $DIR/lifetime-bound-will-change-warning.rs:34:5 + | +LL | fn test2<'a>(x: &'a Box) { + | - `x` is a reference that is only valid in the function body +LL | // but ref_obj will not, so warn. +LL | ref_obj(x) + | ^^^^^^^^^^ `x` escapes the function body here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/lifetime-bound-will-change-warning.rs:39:5 + | +LL | fn test2cc<'a>(x: &'a Box) { + | - `x` is a reference that is only valid in the function body +LL | // same as test2, but cross crate +LL | lib::ref_obj(x) + | ^^^^^^^^^^^^^^^ `x` escapes the function body here + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.nll.stderr new file mode 100644 index 000000000000..fc9093bb2e4b --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/ex1-return-one-existing-name-if-else-using-impl.rs:11:20 + | +LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 { + | -- - let's call the lifetime of this reference `'1` + | | + | lifetime `'a` defined here +LL | +LL | if x > y { x } else { y } + | ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.nll.stderr new file mode 100644 index 000000000000..3384c24da8fb --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/ex1-return-one-existing-name-return-type-is-anon.rs:8:5 + | +LL | fn foo<'a>(&self, x: &'a i32) -> &i32 { + | -- - let's call the lifetime of this reference `'1` + | | + | lifetime `'a` defined here +LL | +LL | x + | ^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.nll.stderr new file mode 100644 index 000000000000..5ef29076e07b --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/ex1-return-one-existing-name-self-is-anon.rs:8:30 + | +LL | fn foo<'a>(&self, x: &'a Foo) -> &'a Foo { + | -- - let's call the lifetime of this reference `'1` + | | + | lifetime `'a` defined here +LL | +LL | if true { x } else { self } + | ^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.nll.stderr new file mode 100644 index 000000000000..90d4754ebab8 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.nll.stderr @@ -0,0 +1,11 @@ +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/ex2a-push-one-existing-name-2.rs:6:5 + | +LL | fn foo<'a>(x: Ref, y: &mut Vec>) { + | -------- help: add explicit lifetime `'a` to the type of `x`: `Ref<'a, i32>` +LL | y.push(x); + | ^^^^^^^^^ lifetime `'a` required + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.nll.stderr new file mode 100644 index 000000000000..a03e16b3b791 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.nll.stderr @@ -0,0 +1,12 @@ +error[E0621]: explicit lifetime required in the type of `y` + --> $DIR/ex2a-push-one-existing-name-early-bound.rs:8:5 + | +LL | fn baz<'a, 'b, T>(x: &mut Vec<&'a T>, y: &T) + | -- help: add explicit lifetime `'a` to the type of `y`: `&'a T` +... +LL | x.push(y); + | ^^^^^^^^^ lifetime `'a` required + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.nll.stderr new file mode 100644 index 000000000000..487b34e3d18f --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.nll.stderr @@ -0,0 +1,11 @@ +error[E0621]: explicit lifetime required in the type of `y` + --> $DIR/ex2a-push-one-existing-name.rs:6:5 + | +LL | fn foo<'a>(x: &mut Vec>, y: Ref) { + | -------- help: add explicit lifetime `'a` to the type of `y`: `Ref<'a, i32>` +LL | x.push(y); + | ^^^^^^^^^ lifetime `'a` required + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.nll.stderr new file mode 100644 index 000000000000..735f7a0dfc63 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/ex2b-push-no-existing-names.rs:6:5 + | +LL | fn foo(x: &mut Vec>, y: Ref) { + | - - has type `Ref<'1, i32>` + | | + | has type `&mut std::vec::Vec>` +LL | x.push(y); + | ^^^^^^^^^ argument requires that `'1` must outlive `'2` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.nll.stderr new file mode 100644 index 000000000000..fbefa1f5667c --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/ex2c-push-inference-variable.rs:7:5 + | +LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { + | -- -- lifetime `'c` defined here + | | + | lifetime `'b` defined here +LL | let z = Ref { data: y.data }; +LL | x.push(z); + | ^^^^^^^^^ argument requires that `'c` must outlive `'b` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.nll.stderr new file mode 100644 index 000000000000..d889eb4afdbe --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/ex2d-push-inference-variable-2.rs:8:5 + | +LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { + | -- -- lifetime `'c` defined here + | | + | lifetime `'b` defined here +... +LL | a.push(b); + | ^^^^^^^^^ argument requires that `'c` must outlive `'b` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.nll.stderr new file mode 100644 index 000000000000..39eb4079352c --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/ex2e-push-inference-variable-3.rs:8:5 + | +LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { + | -- -- lifetime `'c` defined here + | | + | lifetime `'b` defined here +... +LL | Vec::push(a, b); + | ^^^^^^^^^^^^^^^ argument requires that `'c` must outlive `'b` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.nll.stderr new file mode 100644 index 000000000000..a94f9a799061 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-2.rs:2:5 + | +LL | fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | *v = x; + | ^^^^^^ assignment requires that `'1` must outlive `'2` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr new file mode 100644 index 000000000000..779e2eb8b920 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr @@ -0,0 +1,22 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-3.rs:2:5 + | +LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | z.push((x,y)); + | ^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` + +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-3.rs:2:5 + | +LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | z.push((x,y)); + | ^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.nll.stderr new file mode 100644 index 000000000000..4c0ffe5c0901 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-both-are-structs-2.rs:7:5 + | +LL | fn foo(mut x: Ref, y: Ref) { + | ----- - has type `Ref<'_, '1>` + | | + | has type `Ref<'_, '2>` +LL | x.b = y.b; + | ^^^^^^^^^ assignment requires that `'1` must outlive `'2` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.nll.stderr new file mode 100644 index 000000000000..97c665347f6e --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-both-are-structs-3.rs:7:5 + | +LL | fn foo(mut x: Ref) { + | ----- + | | + | has type `Ref<'_, '1>` + | has type `Ref<'2, '_>` +LL | x.a = x.b; + | ^^^^^^^^^ assignment requires that `'1` must outlive `'2` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.nll.stderr new file mode 100644 index 000000000000..a39bb165806f --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs:9:5 + | +LL | fn foo<'a, 'b>(mut x: Vec>, y: Ref<'b>) + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | x.push(y); + | ^^^^^^^^^ argument requires that `'b` must outlive `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.nll.stderr new file mode 100644 index 000000000000..48ce5301adef --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-both-are-structs-latebound-regions.rs:6:5 + | +LL | fn foo<'a, 'b>(mut x: Vec>, y: Ref<'b>) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x.push(y); + | ^^^^^^^^^ argument requires that `'b` must outlive `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.nll.stderr new file mode 100644 index 000000000000..f9c33c248069 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-both-are-structs.rs:6:5 + | +LL | fn foo(mut x: Vec, y: Ref) { + | ----- - has type `Ref<'1>` + | | + | has type `std::vec::Vec>` +LL | x.push(y); + | ^^^^^^^^^ argument requires that `'1` must outlive `'2` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.nll.stderr new file mode 100644 index 000000000000..099606839800 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-latebound-regions.rs:2:5 + | +LL | fn foo<'a,'b>(x: &mut Vec<&'a u8>, y: &'b u8) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x.push(y); + | ^^^^^^^^^ argument requires that `'b` must outlive `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.nll.stderr new file mode 100644 index 000000000000..5751c3194894 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.nll.stderr @@ -0,0 +1,21 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-one-is-struct-2.rs:4:5 + | +LL | fn foo(mut x: Ref, y: &u32) { + | ----- - let's call the lifetime of this reference `'2` + | | + | has type `Ref<'_, '1>` +LL | y = x.b; + | ^^^^^^^ assignment requires that `'1` must outlive `'2` + +error[E0384]: cannot assign to immutable argument `y` + --> $DIR/ex3-both-anon-regions-one-is-struct-2.rs:4:5 + | +LL | fn foo(mut x: Ref, y: &u32) { + | - help: make this binding mutable: `mut y` +LL | y = x.b; + | ^^^^^^^ cannot assign to immutable argument + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0384`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.nll.stderr new file mode 100644 index 000000000000..79e7e8e157d9 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-one-is-struct-3.rs:4:5 + | +LL | fn foo(mut y: Ref, x: &u32) { + | ----- - let's call the lifetime of this reference `'1` + | | + | has type `Ref<'_, '2>` +LL | y.b = x; + | ^^^^^^^ assignment requires that `'1` must outlive `'2` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.nll.stderr new file mode 100644 index 000000000000..53615fd1aba6 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-one-is-struct-4.rs:4:5 + | +LL | fn foo(mut y: Ref, x: &u32) { + | ----- - let's call the lifetime of this reference `'1` + | | + | has type `Ref<'_, '2>` +LL | y.b = x; + | ^^^^^^^ assignment requires that `'1` must outlive `'2` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.nll.stderr new file mode 100644 index 000000000000..6ff441167375 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-one-is-struct.rs:7:5 + | +LL | fn foo(mut x: Ref, y: &u32) { + | ----- - let's call the lifetime of this reference `'1` + | | + | has type `Ref<'_, '2>` +LL | x.b = y; + | ^^^^^^^ assignment requires that `'1` must outlive `'2` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr new file mode 100644 index 000000000000..1c258ad98ba1 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-return-type-is-anon.rs:7:5 + | +LL | fn foo<'a>(&self, x: &i32) -> &i32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | x + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr new file mode 100644 index 000000000000..ffe39fdd8c9f --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-self-is-anon.rs:7:19 + | +LL | fn foo<'a>(&self, x: &Foo) -> &Foo { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | if true { x } else { self } + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr new file mode 100644 index 000000000000..33be98c64910 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr @@ -0,0 +1,21 @@ +error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable + --> $DIR/ex3-both-anon-regions-using-fn-items.rs:2:3 + | +LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) { + | - help: consider changing this to be mutable: `mut y` +LL | y.push(z); + | ^ cannot borrow as mutable + +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-using-fn-items.rs:2:3 + | +LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | y.push(z); + | ^^^^^^^^^ argument requires that `'1` must outlive `'2` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr new file mode 100644 index 000000000000..f3502674849e --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-using-impl-items.rs:6:9 + | +LL | fn foo(x: &mut Vec<&u8>, y: &u8) { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | x.push(y); + | ^^^^^^^^^ argument requires that `'1` must outlive `'2` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr new file mode 100644 index 000000000000..c4e7ff90069d --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr @@ -0,0 +1,21 @@ +error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable + --> $DIR/ex3-both-anon-regions-using-trait-objects.rs:2:3 + | +LL | fn foo(x:Box , y: Vec<&u8>, z: &u8) { + | - help: consider changing this to be mutable: `mut y` +LL | y.push(z); + | ^ cannot borrow as mutable + +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-using-trait-objects.rs:2:3 + | +LL | fn foo(x:Box , y: Vec<&u8>, z: &u8) { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | y.push(z); + | ^^^^^^^^^ argument requires that `'1` must outlive `'2` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.nll.stderr new file mode 100644 index 000000000000..6989acfa1963 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions.rs:2:5 + | +LL | fn foo(x: &mut Vec<&u8>, y: &u8) { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | x.push(y); + | ^^^^^^^^^ argument requires that `'1` must outlive `'2` + +error: aborting due to previous error + diff --git a/src/test/ui/lub-if.nll.stderr b/src/test/ui/lub-if.nll.stderr new file mode 100644 index 000000000000..832688f5162b --- /dev/null +++ b/src/test/ui/lub-if.nll.stderr @@ -0,0 +1,20 @@ +error: lifetime may not live long enough + --> $DIR/lub-if.rs:28:9 + | +LL | pub fn opt_str2<'a>(maybestr: &'a Option) -> &'static str { + | -- lifetime `'a` defined here +... +LL | s + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/lub-if.rs:35:9 + | +LL | pub fn opt_str3<'a>(maybestr: &'a Option) -> &'static str { + | -- lifetime `'a` defined here +... +LL | s + | ^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/lub-match.nll.stderr b/src/test/ui/lub-match.nll.stderr new file mode 100644 index 000000000000..3a344a77d2c2 --- /dev/null +++ b/src/test/ui/lub-match.nll.stderr @@ -0,0 +1,20 @@ +error: lifetime may not live long enough + --> $DIR/lub-match.rs:30:13 + | +LL | pub fn opt_str2<'a>(maybestr: &'a Option) -> &'static str { + | -- lifetime `'a` defined here +... +LL | s + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/lub-match.rs:39:13 + | +LL | pub fn opt_str3<'a>(maybestr: &'a Option) -> &'static str { + | -- lifetime `'a` defined here +... +LL | s + | ^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/match/match-ref-mut-invariance.nll.stderr b/src/test/ui/match/match-ref-mut-invariance.nll.stderr new file mode 100644 index 000000000000..505b8db6a333 --- /dev/null +++ b/src/test/ui/match/match-ref-mut-invariance.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/match-ref-mut-invariance.rs:10:9 + | +LL | impl<'b> S<'b> { + | -- lifetime `'b` defined here +LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { + | -- lifetime `'a` defined here +LL | match self.0 { ref mut x => x } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'b` + +error: aborting due to previous error + diff --git a/src/test/ui/match/match-ref-mut-let-invariance.nll.stderr b/src/test/ui/match/match-ref-mut-let-invariance.nll.stderr new file mode 100644 index 000000000000..ab5f43d02228 --- /dev/null +++ b/src/test/ui/match/match-ref-mut-let-invariance.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/match-ref-mut-let-invariance.rs:11:9 + | +LL | impl<'b> S<'b> { + | -- lifetime `'b` defined here +LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { + | -- lifetime `'a` defined here +LL | let ref mut x = self.0; +LL | x + | ^ returning this value requires that `'a` must outlive `'b` + +error: aborting due to previous error + diff --git a/src/test/ui/nll/get_default.nll.stderr b/src/test/ui/nll/get_default.nll.stderr new file mode 100644 index 000000000000..279123069877 --- /dev/null +++ b/src/test/ui/nll/get_default.nll.stderr @@ -0,0 +1,48 @@ +error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable + --> $DIR/get_default.rs:21:17 + | +LL | fn ok(map: &mut Map) -> &String { + | - let's call the lifetime of this reference `'1` +LL | loop { +LL | match map.get() { + | --- immutable borrow occurs here +LL | Some(v) => { +LL | return v; + | - returning this value requires that `*map` is borrowed for `'1` +... +LL | map.set(String::new()); // Ideally, this would not error. + | ^^^ mutable borrow occurs here + +error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable + --> $DIR/get_default.rs:32:17 + | +LL | fn err(map: &mut Map) -> &String { + | - let's call the lifetime of this reference `'1` +LL | loop { +LL | match map.get() { + | --- immutable borrow occurs here +LL | Some(v) => { +LL | map.set(String::new()); // Both AST and MIR error here + | ^^^ mutable borrow occurs here +LL | +LL | return v; + | - returning this value requires that `*map` is borrowed for `'1` + +error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable + --> $DIR/get_default.rs:37:17 + | +LL | fn err(map: &mut Map) -> &String { + | - let's call the lifetime of this reference `'1` +LL | loop { +LL | match map.get() { + | --- immutable borrow occurs here +... +LL | return v; + | - returning this value requires that `*map` is borrowed for `'1` +... +LL | map.set(String::new()); // Ideally, just AST would error here + | ^^^ mutable borrow occurs here + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/nll/region-ends-after-if-condition.nll.stderr b/src/test/ui/nll/region-ends-after-if-condition.nll.stderr new file mode 100644 index 000000000000..322930984a54 --- /dev/null +++ b/src/test/ui/nll/region-ends-after-if-condition.nll.stderr @@ -0,0 +1,15 @@ +error[E0502]: cannot borrow `my_struct.field` as mutable because it is also borrowed as immutable + --> $DIR/region-ends-after-if-condition.rs:26:9 + | +LL | let value = &my_struct.field; + | ---------------- immutable borrow occurs here +LL | if value.is_empty() { +LL | my_struct.field.push_str("Hello, world!"); + | ^^^^^^^^^^^^^^^ mutable borrow occurs here +... +LL | drop(value); + | ----- immutable borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.nll.stderr b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.nll.stderr new file mode 100644 index 000000000000..58bfb600452e --- /dev/null +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.nll.stderr @@ -0,0 +1,11 @@ +error[E0309]: the associated type `>::Output` may not live long enough + --> $DIR/projection-where-clause-env-wrong-lifetime.rs:14:5 + | +LL | bar::<>::Output>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `>::Output: 'a`... + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/object-lifetime/object-lifetime-default-elision.nll.stderr b/src/test/ui/object-lifetime/object-lifetime-default-elision.nll.stderr new file mode 100644 index 000000000000..19cdd66ef759 --- /dev/null +++ b/src/test/ui/object-lifetime/object-lifetime-default-elision.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/object-lifetime-default-elision.rs:71:5 + | +LL | fn load3<'a,'b>(ss: &'a SomeTrait) -> &'b SomeTrait { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | ss + | ^^ returning this value requires that `'a` must outlive `'b` + +error: aborting due to previous error + diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr new file mode 100644 index 000000000000..9e68647214c2 --- /dev/null +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr @@ -0,0 +1,28 @@ +error[E0621]: explicit lifetime required in the type of `ss` + --> $DIR/object-lifetime-default-from-box-error.rs:18:5 + | +LL | fn load(ss: &mut SomeStruct) -> Box { + | --------------- help: add explicit lifetime `'static` to the type of `ss`: `&mut SomeStruct<'static>` +... +LL | ss.r + | ^^^^ lifetime `'static` required + +error[E0507]: cannot move out of borrowed content + --> $DIR/object-lifetime-default-from-box-error.rs:18:5 + | +LL | ss.r + | ^^^^ cannot move out of borrowed content + +error[E0621]: explicit lifetime required in the type of `ss` + --> $DIR/object-lifetime-default-from-box-error.rs:31:5 + | +LL | fn store1<'b>(ss: &mut SomeStruct, b: Box) { + | --------------- help: add explicit lifetime `'b` to the type of `ss`: `&mut SomeStruct<'b>` +... +LL | ss.r = b; + | ^^^^ lifetime `'b` required + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0507, E0621. +For more information about an error, try `rustc --explain E0507`. diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.nll.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.nll.stderr new file mode 100644 index 000000000000..6d183ddf22d1 --- /dev/null +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.nll.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/object-lifetime-default-from-rptr-box-error.rs:15:5 + | +LL | fn c<'a>(t: &'a Box, mut ss: SomeStruct<'a>) { + | -- lifetime `'a` defined here +LL | ss.t = t; + | ^^^^^^^^ assignment requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.nll.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.nll.stderr new file mode 100644 index 000000000000..fe3b21fa39c5 --- /dev/null +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.nll.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/object-lifetime-default-from-rptr-struct-error.rs:21:5 + | +LL | fn c<'a>(t: &'a MyBox, mut ss: SomeStruct<'a>) { + | -- lifetime `'a` defined here +LL | ss.t = t; + | ^^^^^^^^ assignment requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/object-lifetime/object-lifetime-default-mybox.nll.stderr b/src/test/ui/object-lifetime/object-lifetime-default-mybox.nll.stderr new file mode 100644 index 000000000000..448fe9e55109 --- /dev/null +++ b/src/test/ui/object-lifetime/object-lifetime-default-mybox.nll.stderr @@ -0,0 +1,21 @@ +error: lifetime may not live long enough + --> $DIR/object-lifetime-default-mybox.rs:27:5 + | +LL | fn load1<'a,'b>(a: &'a MyBox, + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | a + | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + +error[E0521]: borrowed data escapes outside of function + --> $DIR/object-lifetime-default-mybox.rs:31:5 + | +LL | fn load2<'a>(ss: &MyBox) -> MyBox { + | -- `ss` is a reference that is only valid in the function body +LL | load0(ss) + | ^^^^^^^^^ `ss` escapes the function body here + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/pattern/pattern-bindings-after-at.nll.stderr b/src/test/ui/pattern/pattern-bindings-after-at.nll.stderr new file mode 100644 index 000000000000..35ee7877f2f7 --- /dev/null +++ b/src/test/ui/pattern/pattern-bindings-after-at.nll.stderr @@ -0,0 +1,22 @@ +error[E0303]: pattern bindings are not allowed after an `@` + --> $DIR/pattern-bindings-after-at.rs:8:31 + | +LL | ref mut z @ &mut Some(ref a) => { + | ^^^^^ not allowed after `@` + +error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable + --> $DIR/pattern-bindings-after-at.rs:8:31 + | +LL | ref mut z @ &mut Some(ref a) => { + | ----------------------^^^^^- + | | | + | | immutable borrow occurs here + | mutable borrow occurs here +... +LL | **z = None; + | ---------- mutable borrow later used here + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0303, E0502. +For more information about an error, try `rustc --explain E0303`. diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr new file mode 100644 index 000000000000..eee331d95b9b --- /dev/null +++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr @@ -0,0 +1,16 @@ +error[E0005]: refutable pattern in local binding: `Err(_)` not covered + --> $DIR/recursive-types-are-not-uninhabited.rs:6:9 + | +LL | let Ok(x) = res; + | ^^^^^ pattern `Err(_)` not covered + +error[E0381]: use of possibly uninitialized variable: `x` + --> $DIR/recursive-types-are-not-uninhabited.rs:8:5 + | +LL | x + | ^ use of possibly uninitialized `x` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0005, E0381. +For more information about an error, try `rustc --explain E0005`. diff --git a/src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr b/src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr new file mode 100644 index 000000000000..76129b4d188d --- /dev/null +++ b/src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr @@ -0,0 +1,11 @@ +error[E0521]: borrowed data escapes outside of function + --> $DIR/region-invariant-static-error-reporting.rs:15:9 + | +LL | fn unify<'a>(x: Option>, f: fn(Invariant<'a>)) { + | - `x` is a reference that is only valid in the function body +LL | let bad = if x.is_some() { +LL | x.unwrap() + | ^^^^^^^^^^ `x` escapes the function body here + +error: aborting due to previous error + diff --git a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.nll.stderr b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.nll.stderr new file mode 100644 index 000000000000..24c9a315badf --- /dev/null +++ b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.nll.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:43 + | +LL | let _: fn(&mut &isize, &mut &isize) = a; + | ^ expected concrete lifetime, found bound lifetime parameter + | + = note: expected type `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)` + found type `for<'r, 's> fn(&'r mut &isize, &'s mut &isize) {a::<'_, '_>}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.nll.stderr b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.nll.stderr new file mode 100644 index 000000000000..6d031e9ac3b9 --- /dev/null +++ b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.nll.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:56 + | +LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; + | ^ expected concrete lifetime, found bound lifetime parameter + | + = note: expected type `for<'r, 's, 't0, 't1, 't2, 't3> fn(&'r mut &'s isize, &'t0 mut &'t1 isize, &'t2 mut &'t3 isize)` + found type `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize) {a::<'_, '_, '_>}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions/region-object-lifetime-2.nll.stderr b/src/test/ui/regions/region-object-lifetime-2.nll.stderr new file mode 100644 index 000000000000..56e8c40c99f7 --- /dev/null +++ b/src/test/ui/regions/region-object-lifetime-2.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/region-object-lifetime-2.rs:10:5 + | +LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a Foo) -> &'b () { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x.borrowed() + | ^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'b` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/region-object-lifetime-4.nll.stderr b/src/test/ui/regions/region-object-lifetime-4.nll.stderr new file mode 100644 index 000000000000..aa91c371f41b --- /dev/null +++ b/src/test/ui/regions/region-object-lifetime-4.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/region-object-lifetime-4.rs:12:5 + | +LL | fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (Foo+'b)) -> &'b () { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x.borrowed() + | ^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr new file mode 100644 index 000000000000..a54f8f5faab5 --- /dev/null +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr @@ -0,0 +1,38 @@ +error[E0621]: explicit lifetime required in the type of `v` + --> $DIR/region-object-lifetime-in-coercion.rs:8:12 + | +LL | fn a(v: &[u8]) -> Box { + | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]` +LL | let x: Box = Box::new(v); + | ^^^^^^^^^^^^^^^^^^ lifetime `'static` required + +error[E0621]: explicit lifetime required in the type of `v` + --> $DIR/region-object-lifetime-in-coercion.rs:14:5 + | +LL | fn b(v: &[u8]) -> Box { + | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]` +LL | Box::new(v) + | ^^^^^^^^^^^ lifetime `'static` required + +error[E0621]: explicit lifetime required in the type of `v` + --> $DIR/region-object-lifetime-in-coercion.rs:21:5 + | +LL | fn c(v: &[u8]) -> Box { + | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]` +... +LL | Box::new(v) + | ^^^^^^^^^^^ lifetime `'static` required + +error: lifetime may not live long enough + --> $DIR/region-object-lifetime-in-coercion.rs:26:5 + | +LL | fn d<'a,'b>(v: &'a [u8]) -> Box { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | Box::new(v) + | ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'b` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/regions/regions-addr-of-self.nll.stderr b/src/test/ui/regions/regions-addr-of-self.nll.stderr new file mode 100644 index 000000000000..3d7aac74bd4f --- /dev/null +++ b/src/test/ui/regions/regions-addr-of-self.nll.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/regions-addr-of-self.rs:7:16 + | +LL | pub fn chase_cat(&mut self) { + | - let's call the lifetime of this reference `'1` +LL | let p: &'static mut usize = &mut self.cats_chased; + | ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr b/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr new file mode 100644 index 000000000000..345e617a7a38 --- /dev/null +++ b/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr @@ -0,0 +1,35 @@ +error: lifetime may not live long enough + --> $DIR/regions-addr-of-upvar-self.rs:10:20 + | +LL | let _f = || { + | -- lifetime `'1` represents this closure's body +LL | let p: &'static mut usize = &mut self.food; + | ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static` + | + = note: closure implements `FnMut`, so references to captured variables can't escape the closure + +error: lifetime may not live long enough + --> $DIR/regions-addr-of-upvar-self.rs:10:20 + | +LL | pub fn chase_cat(&mut self) { + | - let's call the lifetime of this reference `'1` +LL | let _f = || { +LL | let p: &'static mut usize = &mut self.food; + | ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static` + +error[E0597]: `self` does not live long enough + --> $DIR/regions-addr-of-upvar-self.rs:10:46 + | +LL | let _f = || { + | -- value captured here +LL | let p: &'static mut usize = &mut self.food; + | ------------------ ^^^^ borrowed value does not live long enough + | | + | type annotation requires that `self` is borrowed for `'static` +... +LL | } + | - `self` dropped here while still borrowed + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.nll.stderr b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.nll.stderr new file mode 100644 index 000000000000..867eafe2529d --- /dev/null +++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:43:12 + | +LL | fn with_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _: &'a WithAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-bounded-by-trait-requiring-static.nll.stderr b/src/test/ui/regions/regions-bounded-by-trait-requiring-static.nll.stderr new file mode 100644 index 000000000000..86bd100538d7 --- /dev/null +++ b/src/test/ui/regions/regions-bounded-by-trait-requiring-static.nll.stderr @@ -0,0 +1,50 @@ +error: lifetime may not live long enough + --> $DIR/regions-bounded-by-trait-requiring-static.rs:22:5 + | +LL | fn param_not_ok<'a>(x: &'a isize) { + | -- lifetime `'a` defined here +LL | assert_send::<&'a isize>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/regions-bounded-by-trait-requiring-static.rs:26:5 + | +LL | fn param_not_ok1<'a>(_: &'a isize) { + | -- lifetime `'a` defined here +LL | assert_send::<&'a str>(); + | ^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/regions-bounded-by-trait-requiring-static.rs:30:5 + | +LL | fn param_not_ok2<'a>(_: &'a isize) { + | -- lifetime `'a` defined here +LL | assert_send::<&'a [isize]>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/regions-bounded-by-trait-requiring-static.rs:44:5 + | +LL | fn box_with_region_not_ok<'a>() { + | -- lifetime `'a` defined here +LL | assert_send::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/regions-bounded-by-trait-requiring-static.rs:55:5 + | +LL | fn unsafe_ok2<'a>(_: &'a isize) { + | -- lifetime `'a` defined here +LL | assert_send::<*const &'a isize>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/regions-bounded-by-trait-requiring-static.rs:59:5 + | +LL | fn unsafe_ok3<'a>(_: &'a isize) { + | -- lifetime `'a` defined here +LL | assert_send::<*mut &'a isize>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.nll.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.nll.stderr new file mode 100644 index 000000000000..a8ab92d75c06 --- /dev/null +++ b/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/regions-bounded-method-type-parameters-cross-crate.rs:20:5 + | +LL | fn call_bigger_region<'x, 'y>(a: Inv<'x>, b: Inv<'y>) { + | -- -- lifetime `'y` defined here + | | + | lifetime `'x` defined here +LL | // Here the value provided for 'y is 'y, and hence 'y:'x does not hold. +LL | a.bigger_region(b) + | ^^^^^^^^^^^^^^^^^^ argument requires that `'y` must outlive `'x` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr new file mode 100644 index 000000000000..52ad2d9daeb1 --- /dev/null +++ b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr @@ -0,0 +1,13 @@ +error[E0521]: borrowed data escapes outside of function + --> $DIR/regions-bounded-method-type-parameters-trait-bound.rs:20:5 + | +LL | fn caller2<'a,'b,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) { + | - - `b` is a reference that is only valid in the function body + | | + | `a` is declared here, outside of the function body +LL | // Here the value provided for 'y is 'b, and hence 'b:'a does not hold. +LL | f.method(b); + | ^^^^^^^^^^^ `b` escapes the function body here + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters.nll.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters.nll.stderr new file mode 100644 index 000000000000..b6d7b8aac5f1 --- /dev/null +++ b/src/test/ui/regions/regions-bounded-method-type-parameters.nll.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/regions-bounded-method-type-parameters.rs:12:9 + | +LL | fn caller<'a>(x: &isize) { + | -- lifetime `'a` defined here +LL | Foo.some_method::<&'a isize>(); + | ^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-bounds.nll.stderr b/src/test/ui/regions/regions-bounds.nll.stderr new file mode 100644 index 000000000000..3345946bfddf --- /dev/null +++ b/src/test/ui/regions/regions-bounds.nll.stderr @@ -0,0 +1,22 @@ +error: lifetime may not live long enough + --> $DIR/regions-bounds.rs:9:12 + | +LL | fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | return e; + | ^ returning this value requires that `'a` must outlive `'b` + +error: lifetime may not live long enough + --> $DIR/regions-bounds.rs:13:12 + | +LL | fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | return e; + | ^ returning this value requires that `'a` must outlive `'b` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/regions/regions-close-associated-type-into-object.nll.stderr b/src/test/ui/regions/regions-close-associated-type-into-object.nll.stderr new file mode 100644 index 000000000000..92c4956da02d --- /dev/null +++ b/src/test/ui/regions/regions-close-associated-type-into-object.nll.stderr @@ -0,0 +1,36 @@ +error[E0310]: the associated type `::Item` may not live long enough + --> $DIR/regions-close-associated-type-into-object.rs:15:5 + | +LL | Box::new(item) + | ^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `::Item: 'static`... + +error[E0310]: the associated type `::Item` may not live long enough + --> $DIR/regions-close-associated-type-into-object.rs:22:5 + | +LL | Box::new(item) + | ^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `::Item: 'static`... + +error[E0309]: the associated type `::Item` may not live long enough + --> $DIR/regions-close-associated-type-into-object.rs:28:5 + | +LL | Box::new(item) + | ^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `::Item: 'a`... + +error[E0309]: the associated type `::Item` may not live long enough + --> $DIR/regions-close-associated-type-into-object.rs:35:5 + | +LL | Box::new(item) + | ^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `::Item: 'a`... + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0309, E0310. +For more information about an error, try `rustc --explain E0309`. diff --git a/src/test/ui/regions/regions-close-object-into-object-2.nll.stderr b/src/test/ui/regions/regions-close-object-into-object-2.nll.stderr new file mode 100644 index 000000000000..42df9b1c49fb --- /dev/null +++ b/src/test/ui/regions/regions-close-object-into-object-2.nll.stderr @@ -0,0 +1,20 @@ +error: lifetime may not live long enough + --> $DIR/regions-close-object-into-object-2.rs:10:5 + | +LL | fn g<'a, T: 'static>(v: Box+'a>) -> Box { + | -- lifetime `'a` defined here +LL | box B(&*v) as Box + | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error[E0515]: cannot return value referencing local data `*v` + --> $DIR/regions-close-object-into-object-2.rs:10:5 + | +LL | box B(&*v) as Box + | ^^^^^^---^^^^^^^^^^^ + | | | + | | `*v` is borrowed here + | returns a value referencing data owned by the current function + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0515`. diff --git a/src/test/ui/regions/regions-close-object-into-object-4.nll.stderr b/src/test/ui/regions/regions-close-object-into-object-4.nll.stderr new file mode 100644 index 000000000000..8af94fa7e79b --- /dev/null +++ b/src/test/ui/regions/regions-close-object-into-object-4.nll.stderr @@ -0,0 +1,37 @@ +error[E0310]: the parameter type `U` may not live long enough + --> $DIR/regions-close-object-into-object-4.rs:10:5 + | +LL | box B(&*v) as Box + | ^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `U: 'static`... + +error: lifetime may not live long enough + --> $DIR/regions-close-object-into-object-4.rs:10:5 + | +LL | fn i<'a, T, U>(v: Box+'a>) -> Box { + | -- lifetime `'a` defined here +LL | box B(&*v) as Box + | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error[E0515]: cannot return value referencing local data `*v` + --> $DIR/regions-close-object-into-object-4.rs:10:5 + | +LL | box B(&*v) as Box + | ^^^^^^---^^^^^^^^^^^ + | | | + | | `*v` is borrowed here + | returns a value referencing data owned by the current function + +error[E0310]: the parameter type `U` may not live long enough + --> $DIR/regions-close-object-into-object-4.rs:10:9 + | +LL | box B(&*v) as Box + | ^^^^^^ + | + = help: consider adding an explicit lifetime bound `U: 'static`... + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0310, E0515. +For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/regions/regions-close-object-into-object-5.nll.stderr b/src/test/ui/regions/regions-close-object-into-object-5.nll.stderr new file mode 100644 index 000000000000..08ba1b17b566 --- /dev/null +++ b/src/test/ui/regions/regions-close-object-into-object-5.nll.stderr @@ -0,0 +1,29 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/regions-close-object-into-object-5.rs:17:5 + | +LL | box B(&*v) as Box + | ^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `T: 'static`... + +error[E0515]: cannot return value referencing local data `*v` + --> $DIR/regions-close-object-into-object-5.rs:17:5 + | +LL | box B(&*v) as Box + | ^^^^^^---^^^^^^^^^^^ + | | | + | | `*v` is borrowed here + | returns a value referencing data owned by the current function + +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/regions-close-object-into-object-5.rs:17:9 + | +LL | box B(&*v) as Box + | ^^^^^^ + | + = help: consider adding an explicit lifetime bound `T: 'static`... + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0310, E0515. +For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr b/src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr new file mode 100644 index 000000000000..30fdb820e363 --- /dev/null +++ b/src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr @@ -0,0 +1,20 @@ +error[E0310]: the parameter type `A` may not live long enough + --> $DIR/regions-close-over-type-parameter-1.rs:10:5 + | +LL | box v as Box + | ^^^^^ + | + = help: consider adding an explicit lifetime bound `A: 'static`... + +error[E0309]: the parameter type `A` may not live long enough + --> $DIR/regions-close-over-type-parameter-1.rs:20:5 + | +LL | box v as Box + | ^^^^^ + | + = help: consider adding an explicit lifetime bound `A: 'b`... + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0309, E0310. +For more information about an error, try `rustc --explain E0309`. diff --git a/src/test/ui/regions/regions-close-over-type-parameter-multiple.nll.stderr b/src/test/ui/regions/regions-close-over-type-parameter-multiple.nll.stderr new file mode 100644 index 000000000000..001ed7fe4c53 --- /dev/null +++ b/src/test/ui/regions/regions-close-over-type-parameter-multiple.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/regions-close-over-type-parameter-multiple.rs:20:5 + | +LL | fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box { + | -- -- lifetime `'c` defined here + | | + | lifetime `'a` defined here +LL | // A outlives 'a AND 'b...but not 'c. +LL | box v as Box + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'c` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-close-param-into-object.nll.stderr b/src/test/ui/regions/regions-close-param-into-object.nll.stderr new file mode 100644 index 000000000000..7bd7824f00a4 --- /dev/null +++ b/src/test/ui/regions/regions-close-param-into-object.nll.stderr @@ -0,0 +1,36 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/regions-close-param-into-object.rs:6:5 + | +LL | Box::new(v) + | ^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `T: 'static`... + +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/regions-close-param-into-object.rs:12:5 + | +LL | Box::new(v) + | ^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `T: 'static`... + +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/regions-close-param-into-object.rs:18:5 + | +LL | Box::new(v) + | ^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `T: 'a`... + +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/regions-close-param-into-object.rs:24:5 + | +LL | Box::new(v) + | ^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `T: 'a`... + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0309, E0310. +For more information about an error, try `rustc --explain E0309`. diff --git a/src/test/ui/regions/regions-creating-enums3.nll.stderr b/src/test/ui/regions/regions-creating-enums3.nll.stderr new file mode 100644 index 000000000000..e35a878fce17 --- /dev/null +++ b/src/test/ui/regions/regions-creating-enums3.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/regions-creating-enums3.rs:7:5 + | +LL | fn mk_add_bad1<'a,'b>(x: &'a Ast<'a>, y: &'b Ast<'b>) -> Ast<'a> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | Ast::Add(x, y) + | ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-creating-enums4.nll.stderr b/src/test/ui/regions/regions-creating-enums4.nll.stderr new file mode 100644 index 000000000000..4eac457feda2 --- /dev/null +++ b/src/test/ui/regions/regions-creating-enums4.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/regions-creating-enums4.rs:7:5 + | +LL | fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | Ast::Add(x, y) + | ^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'b` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-early-bound-error-method.nll.stderr b/src/test/ui/regions/regions-early-bound-error-method.nll.stderr new file mode 100644 index 000000000000..1540a7bacd7b --- /dev/null +++ b/src/test/ui/regions/regions-early-bound-error-method.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/regions-early-bound-error-method.rs:20:9 + | +LL | impl<'a> Box<'a> { + | -- lifetime `'a` defined here +LL | fn or<'b,G:GetRef<'b>>(&self, g2: G) -> &'a isize { + | -- lifetime `'b` defined here +LL | g2.get() + | ^^^^^^^^ returning this value requires that `'b` must outlive `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-early-bound-error.nll.stderr b/src/test/ui/regions/regions-early-bound-error.nll.stderr new file mode 100644 index 000000000000..7836291a7caa --- /dev/null +++ b/src/test/ui/regions/regions-early-bound-error.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/regions-early-bound-error.rs:19:5 + | +LL | fn get<'a,'b,G:GetRef<'a, isize>>(g1: G, b: &'b isize) -> &'b isize { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | g1.get() + | ^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-escape-method.nll.stderr b/src/test/ui/regions/regions-escape-method.nll.stderr new file mode 100644 index 000000000000..9f425125b989 --- /dev/null +++ b/src/test/ui/regions/regions-escape-method.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/regions-escape-method.rs:15:13 + | +LL | s.f(|p| p) + | -- ^ returning this value requires that `'1` must outlive `'2` + | || + | |return type of closure is &'2 i32 + | has type `&'1 i32` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-escape-via-trait-or-not.nll.stderr b/src/test/ui/regions/regions-escape-via-trait-or-not.nll.stderr new file mode 100644 index 000000000000..cae6c33ac6e1 --- /dev/null +++ b/src/test/ui/regions/regions-escape-via-trait-or-not.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/regions-escape-via-trait-or-not.rs:18:14 + | +LL | with(|o| o) + | -- ^ returning this value requires that `'1` must outlive `'2` + | || + | |return type of closure is &'2 isize + | has type `&'1 isize` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-free-region-ordering-callee.nll.stderr b/src/test/ui/regions/regions-free-region-ordering-callee.nll.stderr new file mode 100644 index 000000000000..9ae484eaf455 --- /dev/null +++ b/src/test/ui/regions/regions-free-region-ordering-callee.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/regions-free-region-ordering-callee.rs:13:5 + | +LL | fn ordering2<'a, 'b>(x: &'a &'b usize, y: &'a usize) -> &'b usize { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | // However, it is not safe to assume that 'b <= 'a +LL | &*y + | ^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + +error: lifetime may not live long enough + --> $DIR/regions-free-region-ordering-callee.rs:18:12 + | +LL | fn ordering3<'a, 'b>(x: &'a usize, y: &'b usize) -> &'a &'b usize { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | // Do not infer an ordering from the return value. +LL | let z: &'b usize = &*x; + | ^^^^^^^^^ type annotation requires that `'a` must outlive `'b` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/regions/regions-free-region-ordering-caller.migrate.nll.stderr b/src/test/ui/regions/regions-free-region-ordering-caller.migrate.nll.stderr new file mode 100644 index 000000000000..16eda2844c64 --- /dev/null +++ b/src/test/ui/regions/regions-free-region-ordering-caller.migrate.nll.stderr @@ -0,0 +1,33 @@ +error: lifetime may not live long enough + --> $DIR/regions-free-region-ordering-caller.rs:11:12 + | +LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let z: Option<&'b &'a usize> = None; + | ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b` + +error: lifetime may not live long enough + --> $DIR/regions-free-region-ordering-caller.rs:17:12 + | +LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let y: Paramd<'a> = Paramd { x: a }; +LL | let z: Option<&'b Paramd<'a>> = None; + | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b` + +error: lifetime may not live long enough + --> $DIR/regions-free-region-ordering-caller.rs:22:12 + | +LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let z: Option<&'a &'b usize> = None; + | ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/regions/regions-free-region-ordering-incorrect.nll.stderr b/src/test/ui/regions/regions-free-region-ordering-incorrect.nll.stderr new file mode 100644 index 000000000000..480a81d33f64 --- /dev/null +++ b/src/test/ui/regions/regions-free-region-ordering-incorrect.nll.stderr @@ -0,0 +1,15 @@ +error: lifetime may not live long enough + --> $DIR/regions-free-region-ordering-incorrect.rs:15:9 + | +LL | impl<'b, T> Node<'b, T> { + | -- lifetime `'b` defined here +LL | fn get<'a>(&'a self) -> &'b T { + | -- lifetime `'a` defined here +LL | / match self.next { +LL | | Some(ref next) => next.get(), +LL | | None => &self.val +LL | | } + | |_________^ returning this value requires that `'a` must outlive `'b` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr new file mode 100644 index 000000000000..0f0f86dfcdd6 --- /dev/null +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr @@ -0,0 +1,11 @@ +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/regions-implied-bounds-projection-gap-1.rs:16:5 + | +LL | wf::<&'x T>(); + | ^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `T: 'x`... + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/regions/regions-infer-bound-from-trait-self.nll.stderr b/src/test/ui/regions/regions-infer-bound-from-trait-self.nll.stderr new file mode 100644 index 000000000000..0651e305cde3 --- /dev/null +++ b/src/test/ui/regions/regions-infer-bound-from-trait-self.nll.stderr @@ -0,0 +1,11 @@ +error[E0309]: the parameter type `Self` may not live long enough + --> $DIR/regions-infer-bound-from-trait-self.rs:46:9 + | +LL | check_bound(x, self) + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `Self: 'a`... + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/regions/regions-infer-bound-from-trait.nll.stderr b/src/test/ui/regions/regions-infer-bound-from-trait.nll.stderr new file mode 100644 index 000000000000..1f7b34fc6996 --- /dev/null +++ b/src/test/ui/regions/regions-infer-bound-from-trait.nll.stderr @@ -0,0 +1,19 @@ +error[E0309]: the parameter type `A` may not live long enough + --> $DIR/regions-infer-bound-from-trait.rs:33:5 + | +LL | check_bound(x, a) + | ^^^^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `A: 'a`... + +error[E0309]: the parameter type `A` may not live long enough + --> $DIR/regions-infer-bound-from-trait.rs:37:5 + | +LL | check_bound(x, a) + | ^^^^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `A: 'a`... + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/regions/regions-infer-call-3.nll.stderr b/src/test/ui/regions/regions-infer-call-3.nll.stderr new file mode 100644 index 000000000000..ca51555a0774 --- /dev/null +++ b/src/test/ui/regions/regions-infer-call-3.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/regions-infer-call-3.rs:8:24 + | +LL | let z = with(|y| { select(x, y) }); + | -- ^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` + | || + | |return type of closure is &'2 isize + | has type `&'1 isize` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr b/src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr new file mode 100644 index 000000000000..cefeecf16e2d --- /dev/null +++ b/src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/regions-infer-contravariance-due-to-decl.rs:25:12 + | +LL | fn use_<'short,'long>(c: Contravariant<'short>, + | ------ ----- lifetime `'long` defined here + | | + | lifetime `'short` defined here +... +LL | let _: Contravariant<'long> = c; + | ^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr b/src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr new file mode 100644 index 000000000000..1bddecba50a7 --- /dev/null +++ b/src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/regions-infer-covariance-due-to-decl.rs:22:12 + | +LL | fn use_<'short,'long>(c: Covariant<'long>, + | ------ ----- lifetime `'long` defined here + | | + | lifetime `'short` defined here +... +LL | let _: Covariant<'short> = c; + | ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-decl.nll.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-decl.nll.stderr new file mode 100644 index 000000000000..0c1e3989b234 --- /dev/null +++ b/src/test/ui/regions/regions-infer-invariance-due-to-decl.nll.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/regions-infer-invariance-due-to-decl.rs:12:5 + | +LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { + | -- lifetime `'r` defined here +LL | b_isize + | ^^^^^^^ returning this value requires that `'r` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.nll.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.nll.stderr new file mode 100644 index 000000000000..0edeb2723998 --- /dev/null +++ b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.nll.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/regions-infer-invariance-due-to-mutability-3.rs:10:5 + | +LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { + | -- lifetime `'r` defined here +LL | b_isize + | ^^^^^^^ returning this value requires that `'r` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.nll.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.nll.stderr new file mode 100644 index 000000000000..724dd7e3f6d3 --- /dev/null +++ b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.nll.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/regions-infer-invariance-due-to-mutability-4.rs:10:5 + | +LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { + | -- lifetime `'r` defined here +LL | b_isize + | ^^^^^^^ returning this value requires that `'r` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-infer-not-param.nll.stderr b/src/test/ui/regions/regions-infer-not-param.nll.stderr new file mode 100644 index 000000000000..2064b060ec41 --- /dev/null +++ b/src/test/ui/regions/regions-infer-not-param.nll.stderr @@ -0,0 +1,26 @@ +error: lifetime may not live long enough + --> $DIR/regions-infer-not-param.rs:15:54 + | +LL | fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p } + | -- -- lifetime `'b` defined here ^ returning this value requires that `'a` must outlive `'b` + | | + | lifetime `'a` defined here + +error: lifetime may not live long enough + --> $DIR/regions-infer-not-param.rs:19:63 + | +LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } + | -- -- lifetime `'b` defined here ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | | + | lifetime `'a` defined here + +error: lifetime may not live long enough + --> $DIR/regions-infer-not-param.rs:19:63 + | +LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } + | -- -- lifetime `'b` defined here ^ returning this value requires that `'a` must outlive `'b` + | | + | lifetime `'a` defined here + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/regions/regions-infer-paramd-indirect.nll.stderr b/src/test/ui/regions/regions-infer-paramd-indirect.nll.stderr new file mode 100644 index 000000000000..a86e6ccdc5ed --- /dev/null +++ b/src/test/ui/regions/regions-infer-paramd-indirect.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/regions-infer-paramd-indirect.rs:22:9 + | +LL | impl<'a> SetF<'a> for C<'a> { + | -- lifetime `'a` defined here +... +LL | fn set_f_bad(&mut self, b: Box) { + | - has type `std::boxed::Box>` +LL | self.f = b; + | ^^^^^^ assignment requires that `'1` must outlive `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-lifetime-bounds-on-fns.nll.stderr b/src/test/ui/regions/regions-lifetime-bounds-on-fns.nll.stderr new file mode 100644 index 000000000000..e1f14fc0cd91 --- /dev/null +++ b/src/test/ui/regions/regions-lifetime-bounds-on-fns.nll.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/regions-lifetime-bounds-on-fns.rs:20:43 + | +LL | let _: fn(&mut &isize, &mut &isize) = a; + | ^ expected concrete lifetime, found bound lifetime parameter + | + = note: expected type `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)` + found type `for<'r, 's> fn(&'r mut &isize, &'s mut &isize) {a::<'_, '_>}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions/regions-nested-fns.nll.stderr b/src/test/ui/regions/regions-nested-fns.nll.stderr new file mode 100644 index 000000000000..c11c09b6d0d5 --- /dev/null +++ b/src/test/ui/regions/regions-nested-fns.nll.stderr @@ -0,0 +1,51 @@ +error[E0521]: borrowed data escapes outside of closure + --> $DIR/regions-nested-fns.rs:10:9 + | +LL | let mut ay = &y; + | ------ `ay` is declared here, outside of the closure body +LL | +LL | ignore:: FnMut(&'z isize)>>(Box::new(|z| { + | - `z` is a reference that is only valid in the closure body +... +LL | ay = z; + | ^^^^^^ `z` escapes the closure body here + +error[E0597]: `y` does not live long enough + --> $DIR/regions-nested-fns.rs:5:18 + | +LL | let mut ay = &y; + | ^^ borrowed value does not live long enough +... +LL | if false { return ay; } + | -- returning this value requires that `y` is borrowed for `'static` +... +LL | } + | - `y` dropped here while still borrowed + +error[E0597]: `y` does not live long enough + --> $DIR/regions-nested-fns.rs:9:15 + | +LL | ignore:: FnMut(&'z isize)>>(Box::new(|z| { + | --- value captured here +LL | ay = x; +LL | ay = &y; + | ^ borrowed value does not live long enough +... +LL | if false { return ay; } + | -- returning this value requires that `y` is borrowed for `'static` +... +LL | } + | - `y` dropped here while still borrowed + +error: lifetime may not live long enough + --> $DIR/regions-nested-fns.rs:14:27 + | +LL | fn nested<'x>(x: &'x isize) { + | -- lifetime `'x` defined here +... +LL | if false { return x; } + | ^ returning this value requires that `'x` must outlive `'static` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.nll.stderr new file mode 100644 index 000000000000..5028663ba6d0 --- /dev/null +++ b/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/regions-outlives-projection-container-hrtb.rs:35:12 + | +LL | fn with_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _: &'a WithHrAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: lifetime may not live long enough + --> $DIR/regions-outlives-projection-container-hrtb.rs:57:12 + | +LL | fn with_assoc_sub<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _: &'a WithHrAssocSub> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.nll.stderr new file mode 100644 index 000000000000..880fe17b740e --- /dev/null +++ b/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/regions-outlives-projection-container-wc.rs:37:12 + | +LL | fn with_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _: &'a WithAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-outlives-projection-container.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container.nll.stderr new file mode 100644 index 000000000000..ef87d02ec081 --- /dev/null +++ b/src/test/ui/regions/regions-outlives-projection-container.nll.stderr @@ -0,0 +1,46 @@ +error: lifetime may not live long enough + --> $DIR/regions-outlives-projection-container.rs:40:13 + | +LL | fn with_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _x: &'a WithAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: lifetime may not live long enough + --> $DIR/regions-outlives-projection-container.rs:58:13 + | +LL | fn without_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _x: &'a WithoutAssoc> = loop { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a` + +error: lifetime may not live long enough + --> $DIR/regions-outlives-projection-container.rs:67:5 + | +LL | fn call_with_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | call::<&'a WithAssoc>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a` + +error: lifetime may not live long enough + --> $DIR/regions-outlives-projection-container.rs:74:5 + | +LL | fn call_without_assoc<'a,'b>() { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | call::<&'a WithoutAssoc>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.nll.stderr b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.nll.stderr new file mode 100644 index 000000000000..c8582f8bfe7f --- /dev/null +++ b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/regions-reborrow-from-shorter-mut-ref-mut-ref.rs:4:5 + | +LL | fn copy_borrowed_ptr<'a, 'b, 'c>(p: &'a mut &'b mut &'c mut isize) -> &'b mut isize { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | &mut ***p + | ^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.nll.stderr b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.nll.stderr new file mode 100644 index 000000000000..5946e7bf8495 --- /dev/null +++ b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/regions-reborrow-from-shorter-mut-ref.rs:6:5 + | +LL | fn copy_borrowed_ptr<'a, 'b>(p: &'a mut &'b mut isize) -> &'b mut isize { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | &mut **p + | ^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-ret-borrowed-1.nll.stderr b/src/test/ui/regions/regions-ret-borrowed-1.nll.stderr new file mode 100644 index 000000000000..0784e894ea92 --- /dev/null +++ b/src/test/ui/regions/regions-ret-borrowed-1.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/regions-ret-borrowed-1.rs:10:14 + | +LL | with(|o| o) + | -- ^ returning this value requires that `'1` must outlive `'2` + | || + | |return type of closure is &'2 isize + | has type `&'1 isize` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-ret-borrowed.nll.stderr b/src/test/ui/regions/regions-ret-borrowed.nll.stderr new file mode 100644 index 000000000000..d9be5ef89cce --- /dev/null +++ b/src/test/ui/regions/regions-ret-borrowed.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/regions-ret-borrowed.rs:13:14 + | +LL | with(|o| o) + | -- ^ returning this value requires that `'1` must outlive `'2` + | || + | |return type of closure is &'2 isize + | has type `&'1 isize` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.nll.stderr b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.nll.stderr new file mode 100644 index 000000000000..4c275b19492c --- /dev/null +++ b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.nll.stderr @@ -0,0 +1,13 @@ +error: captured variable cannot escape `FnMut` closure body + --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:24 + | +LL | let mut f = || &mut x; + | - ^^^^^^ returns a reference to a captured variable which escapes the closure body + | | + | inferred to be a `FnMut` closure + | + = note: `FnMut` closures only have access to their captured variables while they are executing... + = note: ...therefore, they cannot allow references to captured variables to escape + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-static-bound.ll.nll.stderr b/src/test/ui/regions/regions-static-bound.ll.nll.stderr new file mode 100644 index 000000000000..d6cec03e0ff2 --- /dev/null +++ b/src/test/ui/regions/regions-static-bound.ll.nll.stderr @@ -0,0 +1,28 @@ +error: lifetime may not live long enough + --> $DIR/regions-static-bound.rs:9:5 + | +LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { + | -- lifetime `'a` defined here +LL | t //[ll]~ ERROR E0312 + | ^ returning this value requires that `'a` must outlive `'static` + +error[E0621]: explicit lifetime required in the type of `u` + --> $DIR/regions-static-bound.rs:14:5 + | +LL | fn error(u: &(), v: &()) { + | --- help: add explicit lifetime `'static` to the type of `u`: `&'static ()` +LL | static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of `u` [E0621] + | ^^^^^^^^^^^^^ lifetime `'static` required + +error[E0621]: explicit lifetime required in the type of `v` + --> $DIR/regions-static-bound.rs:16:5 + | +LL | fn error(u: &(), v: &()) { + | --- help: add explicit lifetime `'static` to the type of `v`: `&'static ()` +... +LL | static_id_indirect(&v); //[ll]~ ERROR explicit lifetime required in the type of `v` [E0621] + | ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/regions/regions-static-bound.migrate.nll.stderr b/src/test/ui/regions/regions-static-bound.migrate.nll.stderr new file mode 100644 index 000000000000..b5f3e6cfaba0 --- /dev/null +++ b/src/test/ui/regions/regions-static-bound.migrate.nll.stderr @@ -0,0 +1,28 @@ +error: lifetime may not live long enough + --> $DIR/regions-static-bound.rs:9:5 + | +LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { + | -- lifetime `'a` defined here +LL | t + | ^ returning this value requires that `'a` must outlive `'static` + +error[E0621]: explicit lifetime required in the type of `u` + --> $DIR/regions-static-bound.rs:14:5 + | +LL | fn error(u: &(), v: &()) { + | --- help: add explicit lifetime `'static` to the type of `u`: `&'static ()` +LL | static_id(&u); + | ^^^^^^^^^^^^^ lifetime `'static` required + +error[E0621]: explicit lifetime required in the type of `v` + --> $DIR/regions-static-bound.rs:16:5 + | +LL | fn error(u: &(), v: &()) { + | --- help: add explicit lifetime `'static` to the type of `v`: `&'static ()` +... +LL | static_id_indirect(&v); + | ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/regions/regions-trait-object-subtyping.nll.stderr b/src/test/ui/regions/regions-trait-object-subtyping.nll.stderr new file mode 100644 index 000000000000..eccf1b5e8cf7 --- /dev/null +++ b/src/test/ui/regions/regions-trait-object-subtyping.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/regions-trait-object-subtyping.rs:15:5 + | +LL | fn foo3<'a,'b>(x: &'a mut Dummy) -> &'b mut Dummy { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | // Without knowing 'a:'b, we can't coerce +LL | x + | ^ returning this value requires that `'a` must outlive `'b` + +error: lifetime may not live long enough + --> $DIR/regions-trait-object-subtyping.rs:22:5 + | +LL | fn foo4<'a:'b,'b>(x: Wrapper<&'a mut Dummy>) -> Wrapper<&'b mut Dummy> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | // We can't coerce because it is packed in `Wrapper` +LL | x + | ^ returning this value requires that `'b` must outlive `'a` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr new file mode 100644 index 000000000000..f5b96f314c57 --- /dev/null +++ b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:25:12 + | +LL | fn use_<'short,'long>(c: S<'long, 'short>, + | ------ ----- lifetime `'long` defined here + | | + | lifetime `'short` defined here +... +LL | let _: S<'long, 'long> = c; + | ^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr b/src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr new file mode 100644 index 000000000000..372510a2f7e2 --- /dev/null +++ b/src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/regions-variance-contravariant-use-covariant.rs:23:12 + | +LL | fn use_<'short,'long>(c: Contravariant<'short>, + | ------ ----- lifetime `'long` defined here + | | + | lifetime `'short` defined here +... +LL | let _: Contravariant<'long> = c; + | ^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr b/src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr new file mode 100644 index 000000000000..e87e914727c5 --- /dev/null +++ b/src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/regions-variance-covariant-use-contravariant.rs:23:12 + | +LL | fn use_<'short,'long>(c: Covariant<'long>, + | ------ ----- lifetime `'long` defined here + | | + | lifetime `'short` defined here +... +LL | let _: Covariant<'short> = c; + | ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr b/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr new file mode 100644 index 000000000000..adee33bfc7e8 --- /dev/null +++ b/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/regions-variance-invariant-use-contravariant.rs:20:12 + | +LL | fn use_<'short,'long>(c: Invariant<'long>, + | ------ ----- lifetime `'long` defined here + | | + | lifetime `'short` defined here +... +LL | let _: Invariant<'short> = c; + | ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr b/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr new file mode 100644 index 000000000000..15853e6ca5d6 --- /dev/null +++ b/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/regions-variance-invariant-use-covariant.rs:17:12 + | +LL | fn use_<'b>(c: Invariant<'b>) { + | -- lifetime `'b` defined here +... +LL | let _: Invariant<'static> = c; + | ^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.nll.stderr b/src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.nll.stderr new file mode 100644 index 000000000000..c74b82dbbd82 --- /dev/null +++ b/src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.nll.stderr @@ -0,0 +1,14 @@ +error[E0502]: cannot borrow `foo` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-issue-49631.rs:20:9 + | +LL | while let Some(Ok(string)) = foo.get() { + | --- immutable borrow occurs here +LL | foo.mutate(); + | ^^^ mutable borrow occurs here +LL | +LL | println!("foo={:?}", *string); + | ------- immutable borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.nll.stderr b/src/test/ui/suggestions/suggest-impl-trait-lifetime.nll.stderr new file mode 100644 index 000000000000..f4eb9813c1ac --- /dev/null +++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.nll.stderr @@ -0,0 +1,11 @@ +error[E0310]: the parameter type `impl Debug` may not live long enough + --> $DIR/suggest-impl-trait-lifetime.rs:7:5 + | +LL | bar(d); + | ^^^^^^ + | + = help: consider adding an explicit lifetime bound `impl Debug: 'static`... + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/src/test/ui/thread-local-in-ctfe.nll.stderr b/src/test/ui/thread-local-in-ctfe.nll.stderr new file mode 100644 index 000000000000..18d01b187901 --- /dev/null +++ b/src/test/ui/thread-local-in-ctfe.nll.stderr @@ -0,0 +1,49 @@ +error[E0625]: thread-local statics cannot be accessed at compile-time + --> $DIR/thread-local-in-ctfe.rs:6:17 + | +LL | static B: u32 = A; + | ^ + +error[E0625]: thread-local statics cannot be accessed at compile-time + --> $DIR/thread-local-in-ctfe.rs:9:18 + | +LL | static C: &u32 = &A; + | ^^ + +error[E0712]: thread-local variable borrowed past end of function + --> $DIR/thread-local-in-ctfe.rs:9:18 + | +LL | static C: &u32 = &A; + | ^^- end of enclosing function is here + | | + | thread-local variables cannot be borrowed beyond the end of the function + +error[E0625]: thread-local statics cannot be accessed at compile-time + --> $DIR/thread-local-in-ctfe.rs:15:16 + | +LL | const D: u32 = A; + | ^ + +error[E0625]: thread-local statics cannot be accessed at compile-time + --> $DIR/thread-local-in-ctfe.rs:18:17 + | +LL | const E: &u32 = &A; + | ^^ + +error[E0712]: thread-local variable borrowed past end of function + --> $DIR/thread-local-in-ctfe.rs:18:17 + | +LL | const E: &u32 = &A; + | ^^- end of enclosing function is here + | | + | thread-local variables cannot be borrowed beyond the end of the function + +error[E0625]: thread-local statics cannot be accessed at compile-time + --> $DIR/thread-local-in-ctfe.rs:25:5 + | +LL | A + | ^ + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0712`. diff --git a/src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.nll.stderr b/src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.nll.stderr new file mode 100644 index 000000000000..ead42c148896 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/unboxed-closures-infer-argument-types-two-region-pointers.rs:17:9 + | +LL | doit(0, &|x, y| { + | - - has type `&'1 i32` + | | + | has type `&std::cell::Cell<&'2 i32>` +LL | x.set(y); + | ^^^^^^^^ argument requires that `'1` must outlive `'2` + +error: aborting due to previous error + diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr new file mode 100644 index 000000000000..8ed48bda26e8 --- /dev/null +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/dyn-trait-underscore.rs:8:5 + | +LL | fn a(items: &[T]) -> Box> { + | - let's call the lifetime of this reference `'1` +LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` +LL | Box::new(items.iter()) + | ^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr new file mode 100644 index 000000000000..e1d57b8ba1ed --- /dev/null +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/underscore-lifetime-elison-mismatch.rs:1:42 + | +LL | fn foo(x: &mut Vec<&'_ u8>, y: &'_ u8) { x.push(y); } + | - - ^^^^^^^^^ argument requires that `'1` must outlive `'2` + | | | + | | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` + +error: aborting due to previous error + diff --git a/src/test/ui/variance/variance-btree-invariant-types.nll.stderr b/src/test/ui/variance/variance-btree-invariant-types.nll.stderr new file mode 100644 index 000000000000..344437f74e49 --- /dev/null +++ b/src/test/ui/variance/variance-btree-invariant-types.nll.stderr @@ -0,0 +1,106 @@ +error: lifetime may not live long enough + --> $DIR/variance-btree-invariant-types.rs:4:5 + | +LL | fn iter_cov_key<'a, 'new>(v: IterMut<'a, &'static (), ()>) -> IterMut<'a, &'new (), ()> { + | ---- lifetime `'new` defined here +LL | v + | ^ returning this value requires that `'new` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/variance-btree-invariant-types.rs:7:5 + | +LL | fn iter_cov_val<'a, 'new>(v: IterMut<'a, (), &'static ()>) -> IterMut<'a, (), &'new ()> { + | ---- lifetime `'new` defined here +LL | v + | ^ returning this value requires that `'new` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/variance-btree-invariant-types.rs:10:5 + | +LL | fn iter_contra_key<'a, 'new>(v: IterMut<'a, &'new (), ()>) -> IterMut<'a, &'static (), ()> { + | ---- lifetime `'new` defined here +LL | v + | ^ returning this value requires that `'new` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/variance-btree-invariant-types.rs:13:5 + | +LL | fn iter_contra_val<'a, 'new>(v: IterMut<'a, (), &'new ()>) -> IterMut<'a, (), &'static ()> { + | ---- lifetime `'new` defined here +LL | v + | ^ returning this value requires that `'new` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/variance-btree-invariant-types.rs:18:5 + | +LL | fn occ_cov_key<'a, 'new>(v: OccupiedEntry<'a, &'static (), ()>) + | ---- lifetime `'new` defined here +LL | -> OccupiedEntry<'a, &'new (), ()> { +LL | v + | ^ returning this value requires that `'new` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/variance-btree-invariant-types.rs:22:5 + | +LL | fn occ_cov_val<'a, 'new>(v: OccupiedEntry<'a, (), &'static ()>) + | ---- lifetime `'new` defined here +LL | -> OccupiedEntry<'a, (), &'new ()> { +LL | v + | ^ returning this value requires that `'new` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/variance-btree-invariant-types.rs:26:5 + | +LL | fn occ_contra_key<'a, 'new>(v: OccupiedEntry<'a, &'new (), ()>) + | ---- lifetime `'new` defined here +LL | -> OccupiedEntry<'a, &'static (), ()> { +LL | v + | ^ returning this value requires that `'new` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/variance-btree-invariant-types.rs:30:5 + | +LL | fn occ_contra_val<'a, 'new>(v: OccupiedEntry<'a, (), &'new ()>) + | ---- lifetime `'new` defined here +LL | -> OccupiedEntry<'a, (), &'static ()> { +LL | v + | ^ returning this value requires that `'new` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/variance-btree-invariant-types.rs:35:5 + | +LL | fn vac_cov_key<'a, 'new>(v: VacantEntry<'a, &'static (), ()>) + | ---- lifetime `'new` defined here +LL | -> VacantEntry<'a, &'new (), ()> { +LL | v + | ^ returning this value requires that `'new` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/variance-btree-invariant-types.rs:39:5 + | +LL | fn vac_cov_val<'a, 'new>(v: VacantEntry<'a, (), &'static ()>) + | ---- lifetime `'new` defined here +LL | -> VacantEntry<'a, (), &'new ()> { +LL | v + | ^ returning this value requires that `'new` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/variance-btree-invariant-types.rs:43:5 + | +LL | fn vac_contra_key<'a, 'new>(v: VacantEntry<'a, &'new (), ()>) + | ---- lifetime `'new` defined here +LL | -> VacantEntry<'a, &'static (), ()> { +LL | v + | ^ returning this value requires that `'new` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/variance-btree-invariant-types.rs:47:5 + | +LL | fn vac_contra_val<'a, 'new>(v: VacantEntry<'a, (), &'new ()>) + | ---- lifetime `'new` defined here +LL | -> VacantEntry<'a, (), &'static ()> { +LL | v + | ^ returning this value requires that `'new` must outlive `'static` + +error: aborting due to 12 previous errors + diff --git a/src/test/ui/variance/variance-cell-is-invariant.nll.stderr b/src/test/ui/variance/variance-cell-is-invariant.nll.stderr new file mode 100644 index 000000000000..a3ae5320c90d --- /dev/null +++ b/src/test/ui/variance/variance-cell-is-invariant.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/variance-cell-is-invariant.rs:14:12 + | +LL | fn use_<'short,'long>(c: Foo<'short>, + | ------ ----- lifetime `'long` defined here + | | + | lifetime `'short` defined here +... +LL | let _: Foo<'long> = c; + | ^^^^^^^^^^ type annotation requires that `'short` must outlive `'long` + +error: aborting due to previous error + diff --git a/src/test/ui/variance/variance-contravariant-arg-object.nll.stderr b/src/test/ui/variance/variance-contravariant-arg-object.nll.stderr new file mode 100644 index 000000000000..8b5ecbe56ff2 --- /dev/null +++ b/src/test/ui/variance/variance-contravariant-arg-object.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/variance-contravariant-arg-object.rs:14:5 + | +LL | fn get_min_from_max<'min, 'max>(v: Box>) + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | v + | ^ returning this value requires that `'min` must outlive `'max` + +error: lifetime may not live long enough + --> $DIR/variance-contravariant-arg-object.rs:22:5 + | +LL | fn get_max_from_min<'min, 'max, G>(v: Box>) + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | v + | ^ returning this value requires that `'min` must outlive `'max` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/variance/variance-contravariant-arg-trait-match.nll.stderr b/src/test/ui/variance/variance-contravariant-arg-trait-match.nll.stderr new file mode 100644 index 000000000000..dbd75cb52fa8 --- /dev/null +++ b/src/test/ui/variance/variance-contravariant-arg-trait-match.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/variance-contravariant-arg-trait-match.rs:13:5 + | +LL | fn get_min_from_max<'min, 'max, G>() + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | impls_get::() + | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max` + +error: lifetime may not live long enough + --> $DIR/variance-contravariant-arg-trait-match.rs:21:5 + | +LL | fn get_max_from_min<'min, 'max, G>() + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | impls_get::() + | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/variance/variance-contravariant-self-trait-match.nll.stderr b/src/test/ui/variance/variance-contravariant-self-trait-match.nll.stderr new file mode 100644 index 000000000000..9212cf24be3b --- /dev/null +++ b/src/test/ui/variance/variance-contravariant-self-trait-match.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/variance-contravariant-self-trait-match.rs:13:5 + | +LL | fn get_min_from_max<'min, 'max, G>() + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | impls_get::<&'min G>(); + | ^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max` + +error: lifetime may not live long enough + --> $DIR/variance-contravariant-self-trait-match.rs:22:5 + | +LL | fn get_max_from_min<'min, 'max, G>() + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | impls_get::<&'max G>(); + | ^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/variance/variance-covariant-arg-object.nll.stderr b/src/test/ui/variance/variance-covariant-arg-object.nll.stderr new file mode 100644 index 000000000000..acf9f2e060ce --- /dev/null +++ b/src/test/ui/variance/variance-covariant-arg-object.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/variance-covariant-arg-object.rs:15:5 + | +LL | fn get_min_from_max<'min, 'max>(v: Box>) + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | v + | ^ returning this value requires that `'min` must outlive `'max` + +error: lifetime may not live long enough + --> $DIR/variance-covariant-arg-object.rs:22:5 + | +LL | fn get_max_from_min<'min, 'max, G>(v: Box>) + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | v + | ^ returning this value requires that `'min` must outlive `'max` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/variance/variance-covariant-arg-trait-match.nll.stderr b/src/test/ui/variance/variance-covariant-arg-trait-match.nll.stderr new file mode 100644 index 000000000000..33589121c4b8 --- /dev/null +++ b/src/test/ui/variance/variance-covariant-arg-trait-match.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/variance-covariant-arg-trait-match.rs:14:5 + | +LL | fn get_min_from_max<'min, 'max, G>() + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | impls_get::() + | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max` + +error: lifetime may not live long enough + --> $DIR/variance-covariant-arg-trait-match.rs:20:5 + | +LL | fn get_max_from_min<'min, 'max, G>() + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | impls_get::() + | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/variance/variance-covariant-self-trait-match.nll.stderr b/src/test/ui/variance/variance-covariant-self-trait-match.nll.stderr new file mode 100644 index 000000000000..6b2413d68be2 --- /dev/null +++ b/src/test/ui/variance/variance-covariant-self-trait-match.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/variance-covariant-self-trait-match.rs:14:5 + | +LL | fn get_min_from_max<'min, 'max, G>() + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | impls_get::<&'min G>(); + | ^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max` + +error: lifetime may not live long enough + --> $DIR/variance-covariant-self-trait-match.rs:20:5 + | +LL | fn get_max_from_min<'min, 'max, G>() + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | impls_get::<&'max G>(); + | ^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/variance/variance-invariant-arg-object.nll.stderr b/src/test/ui/variance/variance-invariant-arg-object.nll.stderr new file mode 100644 index 000000000000..3c1ee7fc707f --- /dev/null +++ b/src/test/ui/variance/variance-invariant-arg-object.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/variance-invariant-arg-object.rs:11:5 + | +LL | fn get_min_from_max<'min, 'max>(v: Box>) + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | v + | ^ returning this value requires that `'min` must outlive `'max` + +error: lifetime may not live long enough + --> $DIR/variance-invariant-arg-object.rs:18:5 + | +LL | fn get_max_from_min<'min, 'max, G>(v: Box>) + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | v + | ^ returning this value requires that `'min` must outlive `'max` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/variance/variance-invariant-arg-trait-match.nll.stderr b/src/test/ui/variance/variance-invariant-arg-trait-match.nll.stderr new file mode 100644 index 000000000000..2ab44c54c721 --- /dev/null +++ b/src/test/ui/variance/variance-invariant-arg-trait-match.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/variance-invariant-arg-trait-match.rs:10:5 + | +LL | fn get_min_from_max<'min, 'max, G>() + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | impls_get::() + | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max` + +error: lifetime may not live long enough + --> $DIR/variance-invariant-arg-trait-match.rs:16:5 + | +LL | fn get_max_from_min<'min, 'max, G>() + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | impls_get::() + | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/variance/variance-invariant-self-trait-match.nll.stderr b/src/test/ui/variance/variance-invariant-self-trait-match.nll.stderr new file mode 100644 index 000000000000..7b7c42fea8da --- /dev/null +++ b/src/test/ui/variance/variance-invariant-self-trait-match.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/variance-invariant-self-trait-match.rs:10:5 + | +LL | fn get_min_from_max<'min, 'max, G>() + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | impls_get::<&'min G>(); + | ^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max` + +error: lifetime may not live long enough + --> $DIR/variance-invariant-self-trait-match.rs:16:5 + | +LL | fn get_max_from_min<'min, 'max, G>() + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | impls_get::<&'max G>(); + | ^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/variance/variance-trait-matching.nll.stderr b/src/test/ui/variance/variance-trait-matching.nll.stderr new file mode 100644 index 000000000000..3308cc6d2501 --- /dev/null +++ b/src/test/ui/variance/variance-trait-matching.nll.stderr @@ -0,0 +1,12 @@ +error[E0621]: explicit lifetime required in the type of `get` + --> $DIR/variance-trait-matching.rs:24:5 + | +LL | fn get<'a, G>(get: &G) -> i32 + | -- help: add explicit lifetime `'a` to the type of `get`: `&'a G` +... +LL | pick(get, &22) + | ^^^^^^^^^^^^^^ lifetime `'a` required + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/variance/variance-use-contravariant-struct-1.nll.stderr b/src/test/ui/variance/variance-use-contravariant-struct-1.nll.stderr new file mode 100644 index 000000000000..8468448b27bd --- /dev/null +++ b/src/test/ui/variance/variance-use-contravariant-struct-1.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/variance-use-contravariant-struct-1.rs:12:5 + | +LL | fn foo<'min,'max>(v: SomeStruct<&'max ()>) + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | v + | ^ returning this value requires that `'min` must outlive `'max` + +error: aborting due to previous error + diff --git a/src/test/ui/variance/variance-use-covariant-struct-1.nll.stderr b/src/test/ui/variance/variance-use-covariant-struct-1.nll.stderr new file mode 100644 index 000000000000..19a22f064beb --- /dev/null +++ b/src/test/ui/variance/variance-use-covariant-struct-1.nll.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/variance-use-covariant-struct-1.rs:10:5 + | +LL | fn foo<'min,'max>(v: SomeStruct<&'min ()>) + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | v + | ^ returning this value requires that `'min` must outlive `'max` + +error: aborting due to previous error + diff --git a/src/test/ui/variance/variance-use-invariant-struct-1.nll.stderr b/src/test/ui/variance/variance-use-invariant-struct-1.nll.stderr new file mode 100644 index 000000000000..61f80fe77e63 --- /dev/null +++ b/src/test/ui/variance/variance-use-invariant-struct-1.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/variance-use-invariant-struct-1.rs:12:5 + | +LL | fn foo<'min,'max>(v: SomeStruct<&'max ()>) + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | v + | ^ returning this value requires that `'min` must outlive `'max` + +error: lifetime may not live long enough + --> $DIR/variance-use-invariant-struct-1.rs:19:5 + | +LL | fn bar<'min,'max>(v: SomeStruct<&'min ()>) + | ---- ---- lifetime `'max` defined here + | | + | lifetime `'min` defined here +... +LL | v + | ^ returning this value requires that `'min` must outlive `'max` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/wf/wf-static-method.nll.stderr b/src/test/ui/wf/wf-static-method.nll.stderr new file mode 100644 index 000000000000..338de6db1800 --- /dev/null +++ b/src/test/ui/wf/wf-static-method.nll.stderr @@ -0,0 +1,65 @@ +error: lifetime may not live long enough + --> $DIR/wf-static-method.rs:17:9 + | +LL | impl<'a, 'b> Foo<'a, 'b, Evil<'a, 'b>> for () { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | u + | ^ returning this value requires that `'b` must outlive `'a` + +error: lifetime may not live long enough + --> $DIR/wf-static-method.rs:26:18 + | +LL | impl<'a, 'b> Foo<'a, 'b, ()> for IndirectEvil<'a, 'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let me = Self::make_me(); + | ^^^^^^^^^^^^^ requires that `'b` must outlive `'a` + +error: lifetime may not live long enough + --> $DIR/wf-static-method.rs:33:9 + | +LL | impl<'a, 'b> Evil<'a, 'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | fn inherent_evil(u: &'b u32) -> &'a u32 { +LL | u + | ^ returning this value requires that `'b` must outlive `'a` + +error: lifetime may not live long enough + --> $DIR/wf-static-method.rs:41:5 + | +LL | fn evil<'a, 'b>(b: &'b u32) -> &'a u32 { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | <()>::static_evil(b) + | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a` + +error: lifetime may not live long enough + --> $DIR/wf-static-method.rs:45:5 + | +LL | fn indirect_evil<'a, 'b>(b: &'b u32) -> &'a u32 { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | ::static_evil(b) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a` + +error: lifetime may not live long enough + --> $DIR/wf-static-method.rs:50:5 + | +LL | fn inherent_evil<'a, 'b>(b: &'b u32) -> &'a u32 { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | ::inherent_evil(b) // bug? shouldn't this be an error + | ^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a` + +error: aborting due to 6 previous errors + diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 10b8133326bb..2579f1f51bd2 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1912,8 +1912,7 @@ impl<'test> TestCx<'test> { match self.config.compare_mode { Some(CompareMode::Nll) => { - // FIXME(#56993) use -Zborrowck=mir - rustc.args(&["-Zborrowck=migrate"]); + rustc.args(&["-Zborrowck=mir"]); } Some(CompareMode::Polonius) => { rustc.args(&["-Zpolonius", "-Zborrowck=mir"]); From be5fe051a843cfbbc1ba4fcd347b641417181b8f Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 7 Apr 2019 16:07:36 +0100 Subject: [PATCH 112/239] Remove feature(nll) when compare mode is sufficient --- src/test/codegen/enum-debug-niche-2.rs | 1 - src/test/mir-opt/remove_fake_borrows.rs | 2 - src/test/run-fail/issue-51345.rs | 2 - ...orrowck-multiple-borrows-interior-boxes.rs | 2 - .../borrowck/borrowck-unused-mut-locals.rs | 1 - .../run-pass/borrowck/two-phase-bin-ops.rs | 4 - ...535-allow-mutable-borrow-in-match-guard.rs | 1 - src/test/run-pass/issues/issue-48962.rs | 1 - src/test/run-pass/issues/issue-51345.rs | 1 - .../run-pass/nll/issue-47153-generic-const.rs | 1 - src/test/run-pass/nll/issue-47589.rs | 2 - src/test/run-pass/nll/issue-48623-closure.rs | 2 - .../run-pass/nll/issue-48623-generator.rs | 1 - src/test/run-pass/nll/issue-50343.rs | 1 - .../nll/issue-50461-used-mut-from-moves.rs | 1 - .../nll/issue-53123-raw-pointer-cast.rs | 1 - src/test/run-pass/nll/mutating_references.rs | 2 - .../run-pass/nll/process_or_insert_default.rs | 2 - src/test/run-pass/nll/rc-loop.rs | 2 - src/test/ui/borrowck/borrowck-issue-48962.rs | 2 - .../ui/borrowck/borrowck-issue-48962.stderr | 4 +- src/test/ui/borrowck/issue-10876.rs | 2 - .../issue-51348-multi-ref-mut-in-guard.rs | 2 - src/test/ui/borrowck/issue-52713-bug.rs | 2 - src/test/ui/borrowck/issue-52713-bug.stderr | 2 +- ...54597-reject-move-out-of-borrow-via-pat.rs | 2 - ...7-reject-move-out-of-borrow-via-pat.stderr | 2 +- .../issue-58776-borrowck-scans-children.rs | 12 +- ...ssue-58776-borrowck-scans-children.stderr} | 4 +- src/test/ui/borrowck/two-phase-across-loop.rs | 2 - .../ui/borrowck/two-phase-across-loop.stderr | 2 +- src/test/ui/borrowck/two-phase-multi-mut.rs | 2 - .../ui/borrowck/two-phase-multi-mut.stderr | 4 +- src/test/ui/c-variadic/variadic-ffi-5.rs | 31 --- src/test/ui/c-variadic/variadic-ffi-5.stderr | 73 ------ .../promote_mutable_zst_mir_borrowck.rs | 2 - src/test/ui/consts/issue-54224.rs | 2 - src/test/ui/consts/issue-54224.stderr | 4 +- .../promote_evaluation_unused_result.rs | 2 - src/test/ui/consts/promote_fn_calls.rs | 2 - src/test/ui/consts/promote_fn_calls_std.rs | 2 - .../generator-region-requirements.rs | 7 +- ...r => generator-region-requirements.stderr} | 2 +- src/test/ui/generator/generator-with-nll.rs | 1 - .../ui/generator/generator-with-nll.stderr | 2 +- .../impl-trait/closure-calling-parent-fn.rs | 2 - ...-escape-via-bound-contravariant-closure.rs | 1 - .../region-escape-via-bound-contravariant.rs | 1 - .../ui/impl-trait/region-escape-via-bound.rs | 1 - .../impl-trait/region-escape-via-bound.stderr | 6 +- src/test/ui/issues/issue-34721.rs | 2 - src/test/ui/issues/issue-34721.stderr | 2 +- .../issue-45696-no-variant-box-recur.rs | 5 - src/test/ui/issues/issue-46036.rs | 1 - src/test/ui/issues/issue-46036.stderr | 2 +- src/test/ui/issues/issue-46983.rs | 2 - src/test/ui/issues/issue-46983.stderr | 2 +- src/test/ui/issues/issue-47184.rs | 2 - src/test/ui/issues/issue-47184.stderr | 2 +- src/test/ui/issues/issue-47646.rs | 3 - src/test/ui/issues/issue-47646.stderr | 2 +- src/test/ui/issues/issue-47703-1.rs | 2 - src/test/ui/issues/issue-47703-tuple.rs | 2 - src/test/ui/issues/issue-47703.rs | 2 - src/test/ui/issues/issue-47722.rs | 2 - src/test/ui/issues/issue-47789.rs | 3 - src/test/ui/issues/issue-48132.rs | 3 - src/test/ui/issues/issue-48179.rs | 3 - src/test/ui/issues/issue-48803.rs | 2 - src/test/ui/issues/issue-48803.stderr | 2 +- src/test/ui/issues/issue-49579.rs | 2 - src/test/ui/issues/issue-51515.rs | 2 - src/test/ui/issues/issue-51515.stderr | 4 +- src/test/ui/issues/issue-52057.rs | 2 - src/test/ui/issues/issue-52992.rs | 2 - src/test/ui/issues/issue-53568.rs | 3 - src/test/ui/issues/issue-54943-1.rs | 2 - src/test/ui/issues/issue-54943-2.rs | 2 - src/test/ui/issues/issue-54943.nll.stderr | 11 + src/test/ui/issues/issue-54943.rs | 5 +- src/test/ui/issues/issue-54943.stderr | 11 +- src/test/ui/mir-dataflow/def-inits-1.rs | 1 - src/test/ui/mir-dataflow/def-inits-1.stderr | 8 +- src/test/ui/mir-dataflow/inits-1.rs | 1 - src/test/ui/mir-dataflow/inits-1.stderr | 6 +- src/test/ui/mir-dataflow/uninits-1.rs | 1 - src/test/ui/mir-dataflow/uninits-1.stderr | 10 +- src/test/ui/mir-dataflow/uninits-2.rs | 1 - src/test/ui/mir-dataflow/uninits-2.stderr | 2 +- src/test/ui/nll/borrow-use-issue-46875.rs | 2 - ...ead-local-static-mut-borrow-outlives-fn.rs | 1 - src/test/ui/nll/borrowed-local-error.rs | 2 - src/test/ui/nll/borrowed-local-error.stderr | 2 +- .../ui/nll/borrowed-referent-issue-38899.rs | 1 - .../nll/borrowed-referent-issue-38899.stderr | 2 +- src/test/ui/nll/borrowed-temporary-error.rs | 2 - .../ui/nll/borrowed-temporary-error.stderr | 2 +- src/test/ui/nll/borrowed-universal-error-2.rs | 3 - .../ui/nll/borrowed-universal-error-2.stderr | 2 +- src/test/ui/nll/borrowed-universal-error.rs | 3 - .../ui/nll/borrowed-universal-error.stderr | 2 +- src/test/ui/nll/capture-mut-ref.rs | 1 - src/test/ui/nll/capture-mut-ref.stderr | 4 +- src/test/ui/nll/capture-ref-in-struct.rs | 3 - src/test/ui/nll/capture-ref-in-struct.stderr | 2 +- src/test/ui/nll/closure-access-spans.rs | 2 - src/test/ui/nll/closure-access-spans.stderr | 18 +- src/test/ui/nll/closure-borrow-spans.rs | 2 - src/test/ui/nll/closure-borrow-spans.stderr | 28 +- src/test/ui/nll/closure-captures.rs | 3 - src/test/ui/nll/closure-captures.stderr | 62 ++--- src/test/ui/nll/closure-move-spans.rs | 2 - src/test/ui/nll/closure-move-spans.stderr | 6 +- .../issue-58127-mutliple-requirements.rs | 4 - .../propagate-multiple-requirements.rs | 2 - .../propagate-multiple-requirements.stderr | 2 +- src/test/ui/nll/closure-use-spans.rs | 2 - src/test/ui/nll/closure-use-spans.stderr | 6 +- src/test/ui/nll/closures-in-loops.rs | 2 - src/test/ui/nll/closures-in-loops.stderr | 6 +- .../nll/constant-thread-locals-issue-47053.rs | 1 - .../constant-thread-locals-issue-47053.stderr | 2 +- src/test/ui/nll/decl-macro-illegal-copy.rs | 1 - .../ui/nll/decl-macro-illegal-copy.stderr | 2 +- src/test/ui/nll/issue-16223.rs | 1 - src/test/ui/nll/issue-21114-ebfull.rs | 2 - src/test/ui/nll/issue-21114-kixunil.rs | 2 - ...ue-21232-partial-init-and-erroneous-use.rs | 2 - ...1232-partial-init-and-erroneous-use.stderr | 12 +- .../ui/nll/issue-22323-temp-destruction.rs | 2 - src/test/ui/nll/issue-30104.rs | 2 - ...ue-32382-index-assoc-type-with-lifetime.rs | 1 - src/test/ui/nll/issue-43058.rs | 2 - src/test/ui/nll/issue-46589.rs | 2 - src/test/ui/nll/issue-46589.stderr | 2 +- src/test/ui/nll/issue-47022.rs | 3 - src/test/ui/nll/issue-47388.rs | 1 - src/test/ui/nll/issue-47388.stderr | 2 +- src/test/ui/nll/issue-47470.rs | 2 - src/test/ui/nll/issue-47470.stderr | 2 +- src/test/ui/nll/issue-48070.rs | 2 - src/test/ui/nll/issue-48697.rs | 2 - src/test/ui/nll/issue-48697.stderr | 2 +- src/test/ui/nll/issue-50716-1.rs | 4 - src/test/ui/nll/issue-50716.nll.stderr | 11 + src/test/ui/nll/issue-50716.rs | 2 - src/test/ui/nll/issue-50716.stderr | 19 +- src/test/ui/nll/issue-51191.rs | 2 - src/test/ui/nll/issue-51191.stderr | 12 +- src/test/ui/nll/issue-51244.rs | 2 - src/test/ui/nll/issue-51244.stderr | 2 +- src/test/ui/nll/issue-51268.rs | 2 - src/test/ui/nll/issue-51268.stderr | 2 +- src/test/ui/nll/issue-51351.rs | 2 - src/test/ui/nll/issue-51512.rs | 3 - src/test/ui/nll/issue-51512.stderr | 2 +- ...59-report-when-borrow-and-drop-conflict.rs | 1 - ...eport-when-borrow-and-drop-conflict.stderr | 8 +- src/test/ui/nll/issue-52078.rs | 3 - src/test/ui/nll/issue-52086.rs | 2 - src/test/ui/nll/issue-52086.stderr | 4 +- src/test/ui/nll/issue-52113.rs | 3 - src/test/ui/nll/issue-52113.stderr | 2 +- src/test/ui/nll/issue-52534-1.rs | 3 - src/test/ui/nll/issue-52534-1.stderr | 16 +- src/test/ui/nll/issue-52534-2.rs | 3 - src/test/ui/nll/issue-52534-2.stderr | 2 +- src/test/ui/nll/issue-52534.rs | 3 - src/test/ui/nll/issue-52534.stderr | 4 +- ...issue-52663-span-decl-captured-variable.rs | 2 - ...e-52663-span-decl-captured-variable.stderr | 2 +- src/test/ui/nll/issue-52663-trait-object.rs | 1 - .../ui/nll/issue-52663-trait-object.stderr | 2 +- src/test/ui/nll/issue-52669.rs | 2 - src/test/ui/nll/issue-52669.stderr | 2 +- src/test/ui/nll/issue-52742.nll.stderr | 12 + src/test/ui/nll/issue-52742.rs | 3 +- src/test/ui/nll/issue-52742.stderr | 24 +- src/test/ui/nll/issue-53119.rs | 2 - src/test/ui/nll/issue-53570.rs | 4 - src/test/ui/nll/issue-55288.rs | 2 - src/test/ui/nll/issue-55344.rs | 2 - src/test/ui/nll/issue-55394.nll.stderr | 12 + src/test/ui/nll/issue-55394.rs | 4 +- src/test/ui/nll/issue-55394.stderr | 31 ++- src/test/ui/nll/issue-55401.nll.stderr | 11 + src/test/ui/nll/issue-55401.rs | 2 - src/test/ui/nll/issue-55401.stderr | 16 +- .../nll/issue-57265-return-type-wf-check.rs | 2 - .../issue-57265-return-type-wf-check.stderr | 2 +- src/test/ui/nll/issue-57280-1.rs | 2 - src/test/ui/nll/issue-57280.rs | 2 - src/test/ui/nll/issue-57989.rs | 2 - src/test/ui/nll/issue-57989.stderr | 4 +- src/test/ui/nll/issue-58053.rs | 1 - src/test/ui/nll/issue-58053.stderr | 4 +- src/test/ui/nll/issue-58299.rs | 1 - src/test/ui/nll/issue-58299.stderr | 4 +- ...initialized-drop-implicit-fragment-drop.rs | 3 - ...ialized-drop-implicit-fragment-drop.stderr | 2 +- src/test/ui/nll/move-errors.rs | 3 - src/test/ui/nll/move-errors.stderr | 44 ++-- src/test/ui/nll/move-subpaths-moves-root.rs | 2 - .../ui/nll/move-subpaths-moves-root.stderr | 2 +- src/test/ui/nll/normalization-bounds-error.rs | 1 - .../ui/nll/normalization-bounds-error.stderr | 10 +- src/test/ui/nll/normalization-bounds.rs | 1 - .../promotable-mutable-zst-doesnt-conflict.rs | 2 - src/test/ui/nll/promoted-bounds.rs | 2 - src/test/ui/nll/promoted-bounds.stderr | 2 +- src/test/ui/nll/promoted-closure-pair.rs | 2 - src/test/ui/nll/promoted-closure-pair.stderr | 2 +- src/test/ui/nll/relate_tys/issue-48071.rs | 4 - .../ui/nll/relate_tys/var-appears-twice.rs | 3 - .../nll/relate_tys/var-appears-twice.stderr | 2 +- src/test/ui/nll/return-ref-mut-issue-46557.rs | 3 - .../ui/nll/return-ref-mut-issue-46557.stderr | 2 +- src/test/ui/nll/ty-outlives/issue-53789-1.rs | 3 - src/test/ui/nll/ty-outlives/issue-53789-2.rs | 3 - ...on-where-clause-env-wrong-bound.nll.stderr | 11 + ...projection-where-clause-env-wrong-bound.rs | 2 - ...ection-where-clause-env-wrong-bound.stderr | 11 +- .../projection-where-clause-env.rs | 2 - .../ty-param-fn-body-nll-feature.rs | 30 --- .../ty-param-fn-body-nll-feature.stderr | 11 - .../ui/nll/type-alias-free-regions.nll.stderr | 22 ++ src/test/ui/nll/type-alias-free-regions.rs | 2 - .../ui/nll/type-alias-free-regions.stderr | 58 ++++- src/test/ui/nll/unused-mut-issue-50343.rs | 1 - src/test/ui/nll/unused-mut-issue-50343.stderr | 4 +- .../nll/user-annotations/adt-brace-enums.rs | 2 - .../user-annotations/adt-brace-enums.stderr | 6 +- .../nll/user-annotations/adt-brace-structs.rs | 2 - .../user-annotations/adt-brace-structs.stderr | 6 +- .../nll/user-annotations/adt-nullary-enums.rs | 1 - .../user-annotations/adt-nullary-enums.stderr | 6 +- .../nll/user-annotations/adt-tuple-enums.rs | 1 - .../user-annotations/adt-tuple-enums.stderr | 6 +- .../nll/user-annotations/adt-tuple-struct.rs | 2 - .../user-annotations/adt-tuple-struct.stderr | 6 +- .../user-annotations/cast_static_lifetime.rs | 1 - .../cast_static_lifetime.stderr | 2 +- .../constant-in-expr-inherent-1.nll.stderr | 10 + .../constant-in-expr-inherent-1.rs | 2 - .../constant-in-expr-inherent-1.stderr | 21 +- .../constant-in-expr-inherent-2.rs | 2 - .../constant-in-expr-inherent-2.stderr | 8 +- .../constant-in-expr-normalize.nll.stderr | 10 + .../constant-in-expr-normalize.rs | 2 - .../constant-in-expr-normalize.stderr | 15 +- .../constant-in-expr-trait-item-1.nll.stderr | 10 + .../constant-in-expr-trait-item-1.rs | 2 - .../constant-in-expr-trait-item-1.stderr | 15 +- .../constant-in-expr-trait-item-2.nll.stderr | 10 + .../constant-in-expr-trait-item-2.rs | 2 - .../constant-in-expr-trait-item-2.stderr | 15 +- .../constant-in-expr-trait-item-3.nll.stderr | 10 + .../constant-in-expr-trait-item-3.rs | 2 - .../constant-in-expr-trait-item-3.stderr | 21 +- src/test/ui/nll/user-annotations/fns.rs | 2 - src/test/ui/nll/user-annotations/fns.stderr | 6 +- .../issue-54570-bootstrapping.rs | 1 - .../ui/nll/user-annotations/issue-55219.rs | 2 - .../ui/nll/user-annotations/issue-55241.rs | 2 - .../ui/nll/user-annotations/method-call.rs | 2 - .../nll/user-annotations/method-call.stderr | 6 +- .../ui/nll/user-annotations/method-ufcs-1.rs | 2 - .../nll/user-annotations/method-ufcs-1.stderr | 6 +- .../ui/nll/user-annotations/method-ufcs-2.rs | 2 - .../nll/user-annotations/method-ufcs-2.stderr | 6 +- .../ui/nll/user-annotations/method-ufcs-3.rs | 2 - .../nll/user-annotations/method-ufcs-3.stderr | 6 +- .../method-ufcs-inherent-2.rs | 2 - .../method-ufcs-inherent-2.stderr | 4 +- .../method-ufcs-inherent-4.rs | 2 - .../method-ufcs-inherent-4.stderr | 4 +- .../ui/nll/user-annotations/normalization.rs | 2 - .../nll/user-annotations/normalization.stderr | 2 +- .../nll/user-annotations/normalize-self-ty.rs | 2 - .../pattern_substs_on_brace_enum_variant.rs | 2 - ...attern_substs_on_brace_enum_variant.stderr | 4 +- .../pattern_substs_on_brace_struct.rs | 2 - .../pattern_substs_on_brace_struct.stderr | 4 +- .../pattern_substs_on_tuple_enum_variant.rs | 2 - ...attern_substs_on_tuple_enum_variant.stderr | 4 +- .../pattern_substs_on_tuple_struct.rs | 2 - .../pattern_substs_on_tuple_struct.stderr | 4 +- .../user-annotations/promoted-annotation.rs | 2 - .../promoted-annotation.stderr | 2 +- .../type_ascription_static_lifetime.rs | 1 - .../type_ascription_static_lifetime.stderr | 2 +- .../bind-by-move-no-guards.rs | 1 - .../rfc-basic-examples.rs | 1 - .../dont-suggest-ref/duplicate-suggestions.rs | 2 - .../duplicate-suggestions.stderr | 68 ++--- .../dont-suggest-ref/move-into-closure.rs | 2 - .../dont-suggest-ref/move-into-closure.stderr | 84 +++--- .../ui/suggestions/dont-suggest-ref/simple.rs | 2 - .../dont-suggest-ref/simple.stderr | 240 +++++++++--------- src/test/ui/suggestions/suggest-ref-mut.rs | 2 - .../ui/suggestions/suggest-ref-mut.stderr | 8 +- 301 files changed, 774 insertions(+), 1029 deletions(-) rename src/test/ui/borrowck/{issue-58776-borrowck-scans-children.nll.stderr => issue-58776-borrowck-scans-children.stderr} (91%) delete mode 100644 src/test/ui/c-variadic/variadic-ffi-5.rs delete mode 100644 src/test/ui/c-variadic/variadic-ffi-5.stderr rename src/test/ui/generator/{generator-region-requirements.nll.stderr => generator-region-requirements.stderr} (90%) create mode 100644 src/test/ui/issues/issue-54943.nll.stderr create mode 100644 src/test/ui/nll/issue-50716.nll.stderr create mode 100644 src/test/ui/nll/issue-52742.nll.stderr create mode 100644 src/test/ui/nll/issue-55394.nll.stderr create mode 100644 src/test/ui/nll/issue-55401.nll.stderr create mode 100644 src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.nll.stderr delete mode 100644 src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.rs delete mode 100644 src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.stderr create mode 100644 src/test/ui/nll/type-alias-free-regions.nll.stderr create mode 100644 src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.nll.stderr create mode 100644 src/test/ui/nll/user-annotations/constant-in-expr-normalize.nll.stderr create mode 100644 src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.nll.stderr create mode 100644 src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.nll.stderr create mode 100644 src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.nll.stderr diff --git a/src/test/codegen/enum-debug-niche-2.rs b/src/test/codegen/enum-debug-niche-2.rs index aa6cbf66b4aa..0f17976ef496 100644 --- a/src/test/codegen/enum-debug-niche-2.rs +++ b/src/test/codegen/enum-debug-niche-2.rs @@ -13,7 +13,6 @@ // CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Error",{{.*}}extraData: i64 0{{[,)].*}} #![feature(never_type)] -#![feature(nll)] #[derive(Copy, Clone)] pub struct Entity { diff --git a/src/test/mir-opt/remove_fake_borrows.rs b/src/test/mir-opt/remove_fake_borrows.rs index 144348450a91..8348f9a77467 100644 --- a/src/test/mir-opt/remove_fake_borrows.rs +++ b/src/test/mir-opt/remove_fake_borrows.rs @@ -2,8 +2,6 @@ // ignore-wasm32-bare -#![feature(nll)] - fn match_guard(x: Option<&&i32>, c: bool) -> i32 { match x { Some(0) if c => 0, diff --git a/src/test/run-fail/issue-51345.rs b/src/test/run-fail/issue-51345.rs index 3c7f6a68db54..c62f98ea78d1 100644 --- a/src/test/run-fail/issue-51345.rs +++ b/src/test/run-fail/issue-51345.rs @@ -1,7 +1,5 @@ // error-pattern: thread 'main' panicked at 'explicit panic' -#![feature(nll)] - fn main() { let mut vec = vec![]; vec.push((vec.len(), panic!())); diff --git a/src/test/run-pass/borrowck/borrowck-multiple-borrows-interior-boxes.rs b/src/test/run-pass/borrowck/borrowck-multiple-borrows-interior-boxes.rs index c953bed26f49..96d2663500ef 100644 --- a/src/test/run-pass/borrowck/borrowck-multiple-borrows-interior-boxes.rs +++ b/src/test/run-pass/borrowck/borrowck-multiple-borrows-interior-boxes.rs @@ -3,8 +3,6 @@ #![allow(unused_variables)] // Test case from #39963. -#![feature(nll)] - #[derive(Clone)] struct Foo(Option>, Option>); diff --git a/src/test/run-pass/borrowck/borrowck-unused-mut-locals.rs b/src/test/run-pass/borrowck/borrowck-unused-mut-locals.rs index 8f0434c0e2b5..fd0e346e2b42 100644 --- a/src/test/run-pass/borrowck/borrowck-unused-mut-locals.rs +++ b/src/test/run-pass/borrowck/borrowck-unused-mut-locals.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(nll)] #![deny(unused_mut)] #[derive(Debug)] diff --git a/src/test/run-pass/borrowck/two-phase-bin-ops.rs b/src/test/run-pass/borrowck/two-phase-bin-ops.rs index 5e1d436e31bf..1242ae307d39 100644 --- a/src/test/run-pass/borrowck/two-phase-bin-ops.rs +++ b/src/test/run-pass/borrowck/two-phase-bin-ops.rs @@ -1,8 +1,4 @@ // run-pass -// revisions: lxl nll - -#![cfg_attr(nll, feature(nll))] - use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign}; use std::ops::{BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssign}; diff --git a/src/test/run-pass/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs b/src/test/run-pass/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs index 68f7dfd38f4f..48362d0bb628 100644 --- a/src/test/run-pass/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs +++ b/src/test/run-pass/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs @@ -5,7 +5,6 @@ // See further discussion on rust-lang/rust#24535, // rust-lang/rfcs#1006, and rust-lang/rfcs#107 -#![feature(nll)] #![feature(bind_by_move_pattern_guards)] fn main() { diff --git a/src/test/run-pass/issues/issue-48962.rs b/src/test/run-pass/issues/issue-48962.rs index 7c644789834d..80d815379bec 100644 --- a/src/test/run-pass/issues/issue-48962.rs +++ b/src/test/run-pass/issues/issue-48962.rs @@ -1,7 +1,6 @@ // run-pass #![allow(unused_must_use)] // Test that we are able to reinitialize box with moved referent -#![feature(nll)] static mut ORDER: [usize; 3] = [0, 0, 0]; static mut INDEX: usize = 0; diff --git a/src/test/run-pass/issues/issue-51345.rs b/src/test/run-pass/issues/issue-51345.rs index 29a0a328503e..15571e8bf5b2 100644 --- a/src/test/run-pass/issues/issue-51345.rs +++ b/src/test/run-pass/issues/issue-51345.rs @@ -1,6 +1,5 @@ // run-pass #![allow(unreachable_code)] -#![feature(nll)] fn main() { let mut v = Vec::new(); diff --git a/src/test/run-pass/nll/issue-47153-generic-const.rs b/src/test/run-pass/nll/issue-47153-generic-const.rs index 4f021fda4e34..9f4d57111bbe 100644 --- a/src/test/run-pass/nll/issue-47153-generic-const.rs +++ b/src/test/run-pass/nll/issue-47153-generic-const.rs @@ -3,7 +3,6 @@ // Regression test for #47153: constants in a generic context (such as // a trait) used to ICE. -#![feature(nll)] #![allow(warnings)] trait Foo { diff --git a/src/test/run-pass/nll/issue-47589.rs b/src/test/run-pass/nll/issue-47589.rs index 5bbed3a85904..280bf081138c 100644 --- a/src/test/run-pass/nll/issue-47589.rs +++ b/src/test/run-pass/nll/issue-47589.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(nll)] - pub struct DescriptorSet<'a> { pub slots: Vec> } diff --git a/src/test/run-pass/nll/issue-48623-closure.rs b/src/test/run-pass/nll/issue-48623-closure.rs index 5a41fff11a1f..3f8587eed41b 100644 --- a/src/test/run-pass/nll/issue-48623-closure.rs +++ b/src/test/run-pass/nll/issue-48623-closure.rs @@ -2,8 +2,6 @@ #![allow(path_statements)] #![allow(dead_code)] -#![feature(nll)] - struct WithDrop; impl Drop for WithDrop { diff --git a/src/test/run-pass/nll/issue-48623-generator.rs b/src/test/run-pass/nll/issue-48623-generator.rs index b404daca7256..ba3eccff495e 100644 --- a/src/test/run-pass/nll/issue-48623-generator.rs +++ b/src/test/run-pass/nll/issue-48623-generator.rs @@ -2,7 +2,6 @@ #![allow(path_statements)] #![allow(dead_code)] -#![feature(nll)] #![feature(generators, generator_trait)] struct WithDrop; diff --git a/src/test/run-pass/nll/issue-50343.rs b/src/test/run-pass/nll/issue-50343.rs index 8d2992b3b4f8..55a2d231e19f 100644 --- a/src/test/run-pass/nll/issue-50343.rs +++ b/src/test/run-pass/nll/issue-50343.rs @@ -1,6 +1,5 @@ // run-pass -#![feature(nll)] #![deny(unused_mut)] fn main() { diff --git a/src/test/run-pass/nll/issue-50461-used-mut-from-moves.rs b/src/test/run-pass/nll/issue-50461-used-mut-from-moves.rs index dc5257cfb922..69d7cdd83a6a 100644 --- a/src/test/run-pass/nll/issue-50461-used-mut-from-moves.rs +++ b/src/test/run-pass/nll/issue-50461-used-mut-from-moves.rs @@ -1,6 +1,5 @@ // run-pass -#![feature(nll)] #![deny(unused_mut)] struct Foo { diff --git a/src/test/run-pass/nll/issue-53123-raw-pointer-cast.rs b/src/test/run-pass/nll/issue-53123-raw-pointer-cast.rs index c3f818812aa5..941c9eeb411d 100644 --- a/src/test/run-pass/nll/issue-53123-raw-pointer-cast.rs +++ b/src/test/run-pass/nll/issue-53123-raw-pointer-cast.rs @@ -1,6 +1,5 @@ // run-pass -#![feature(nll)] #![allow(unused_variables)] pub trait TryTransform { diff --git a/src/test/run-pass/nll/mutating_references.rs b/src/test/run-pass/nll/mutating_references.rs index 0af8751494e0..eb46b30b6b94 100644 --- a/src/test/run-pass/nll/mutating_references.rs +++ b/src/test/run-pass/nll/mutating_references.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(nll)] - struct List { value: T, next: Option>>, diff --git a/src/test/run-pass/nll/process_or_insert_default.rs b/src/test/run-pass/nll/process_or_insert_default.rs index e9cd4014bc35..84ac9bbd0ddc 100644 --- a/src/test/run-pass/nll/process_or_insert_default.rs +++ b/src/test/run-pass/nll/process_or_insert_default.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(nll)] - use std::collections::HashMap; fn process_or_insert_default(map: &mut HashMap, key: usize) { diff --git a/src/test/run-pass/nll/rc-loop.rs b/src/test/run-pass/nll/rc-loop.rs index a4ef546c25f4..e59303d1f788 100644 --- a/src/test/run-pass/nll/rc-loop.rs +++ b/src/test/run-pass/nll/rc-loop.rs @@ -6,8 +6,6 @@ // `x`. The lexical checker makes this very painful. The NLL checker // does not. -#![feature(nll)] - use std::rc::Rc; #[derive(Debug, PartialEq, Eq)] diff --git a/src/test/ui/borrowck/borrowck-issue-48962.rs b/src/test/ui/borrowck/borrowck-issue-48962.rs index e7df319a0bb7..86061c8cd6e8 100644 --- a/src/test/ui/borrowck/borrowck-issue-48962.rs +++ b/src/test/ui/borrowck/borrowck-issue-48962.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - struct Node { elem: i32, next: Option>, diff --git a/src/test/ui/borrowck/borrowck-issue-48962.stderr b/src/test/ui/borrowck/borrowck-issue-48962.stderr index a5462b413968..ee174f6736e1 100644 --- a/src/test/ui/borrowck/borrowck-issue-48962.stderr +++ b/src/test/ui/borrowck/borrowck-issue-48962.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `src` - --> $DIR/borrowck-issue-48962.rs:16:5 + --> $DIR/borrowck-issue-48962.rs:14:5 | LL | let mut src = &mut node; | ------- move occurs because `src` has type `&mut Node`, which does not implement the `Copy` trait @@ -9,7 +9,7 @@ LL | src.next = None; | ^^^^^^^^ value used here after move error[E0382]: use of moved value: `src` - --> $DIR/borrowck-issue-48962.rs:22:5 + --> $DIR/borrowck-issue-48962.rs:20:5 | LL | let mut src = &mut (22, 44); | ------- move occurs because `src` has type `&mut (i32, i32)`, which does not implement the `Copy` trait diff --git a/src/test/ui/borrowck/issue-10876.rs b/src/test/ui/borrowck/issue-10876.rs index d8fff5f17760..20ab905fec46 100644 --- a/src/test/ui/borrowck/issue-10876.rs +++ b/src/test/ui/borrowck/issue-10876.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(nll)] - enum Nat { S(Box), Z diff --git a/src/test/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs b/src/test/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs index a8bfdbad38ba..7d5acb95751e 100644 --- a/src/test/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs +++ b/src/test/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs @@ -8,8 +8,6 @@ // run-pass -#![feature(nll)] - fn foo(x: &mut Result<(u32, u32), (u32, u32)>) -> u32 { match *x { Ok((ref mut v, _)) | Err((_, ref mut v)) if *v > 0 => { *v } diff --git a/src/test/ui/borrowck/issue-52713-bug.rs b/src/test/ui/borrowck/issue-52713-bug.rs index 460e6b4bbae4..671e83dfadc8 100644 --- a/src/test/ui/borrowck/issue-52713-bug.rs +++ b/src/test/ui/borrowck/issue-52713-bug.rs @@ -2,8 +2,6 @@ // computing liveness that wound up accidentally causing the program // below to be accepted. -#![feature(nll)] - fn foo<'a>(x: &'a mut u32) -> u32 { let mut x = 22; let y = &x; diff --git a/src/test/ui/borrowck/issue-52713-bug.stderr b/src/test/ui/borrowck/issue-52713-bug.stderr index e3216f5d33f9..4abb6fb2c718 100644 --- a/src/test/ui/borrowck/issue-52713-bug.stderr +++ b/src/test/ui/borrowck/issue-52713-bug.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/issue-52713-bug.rs:14:5 + --> $DIR/issue-52713-bug.rs:12:5 | LL | let y = &x; | -- borrow of `x` occurs here diff --git a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs index ad4accbbeeef..51df40016d8a 100644 --- a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs +++ b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - #![allow(dead_code)] #[derive(Debug)] diff --git a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr index 6a12016b2a5e..519f1d6fb279 100644 --- a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr +++ b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of borrowed content - --> $DIR/issue-54597-reject-move-out-of-borrow-via-pat.rs:16:13 + --> $DIR/issue-54597-reject-move-out-of-borrow-via-pat.rs:14:13 | LL | *array | ^^^^^^ diff --git a/src/test/ui/borrowck/issue-58776-borrowck-scans-children.rs b/src/test/ui/borrowck/issue-58776-borrowck-scans-children.rs index 0f3f1a639f7e..efa313a9d23f 100644 --- a/src/test/ui/borrowck/issue-58776-borrowck-scans-children.rs +++ b/src/test/ui/borrowck/issue-58776-borrowck-scans-children.rs @@ -1,19 +1,11 @@ -// ignore-compare-mode-nll - -// revisions: migrate nll - -#![cfg_attr(nll, feature(nll))] - fn main() { let mut greeting = "Hello world!".to_string(); let res = (|| (|| &greeting)())(); greeting = "DEALLOCATED".to_string(); - //[migrate]~^ ERROR cannot assign - //[nll]~^^ ERROR cannot assign + //~^ ERROR cannot assign drop(greeting); - //[migrate]~^ ERROR cannot move - //[nll]~^^ ERROR cannot move + //~^ ERROR cannot move println!("thread result: {:?}", res); } diff --git a/src/test/ui/borrowck/issue-58776-borrowck-scans-children.nll.stderr b/src/test/ui/borrowck/issue-58776-borrowck-scans-children.stderr similarity index 91% rename from src/test/ui/borrowck/issue-58776-borrowck-scans-children.nll.stderr rename to src/test/ui/borrowck/issue-58776-borrowck-scans-children.stderr index efd4e1a1716d..9b1d6fa7d357 100644 --- a/src/test/ui/borrowck/issue-58776-borrowck-scans-children.nll.stderr +++ b/src/test/ui/borrowck/issue-58776-borrowck-scans-children.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `greeting` because it is borrowed - --> $DIR/issue-58776-borrowck-scans-children.rs:11:5 + --> $DIR/issue-58776-borrowck-scans-children.rs:5:5 | LL | let res = (|| (|| &greeting)())(); | -- -------- borrow occurs due to use in closure @@ -13,7 +13,7 @@ LL | println!("thread result: {:?}", res); | --- borrow later used here error[E0505]: cannot move out of `greeting` because it is borrowed - --> $DIR/issue-58776-borrowck-scans-children.rs:14:10 + --> $DIR/issue-58776-borrowck-scans-children.rs:7:10 | LL | let res = (|| (|| &greeting)())(); | -- -------- borrow occurs due to use in closure diff --git a/src/test/ui/borrowck/two-phase-across-loop.rs b/src/test/ui/borrowck/two-phase-across-loop.rs index b1a4c54f49b1..12222342c95a 100644 --- a/src/test/ui/borrowck/two-phase-across-loop.rs +++ b/src/test/ui/borrowck/two-phase-across-loop.rs @@ -1,8 +1,6 @@ // Test that a borrow which starts as a 2-phase borrow and gets // carried around a loop winds up conflicting with itself. -#![feature(nll)] - struct Foo { x: String } impl Foo { diff --git a/src/test/ui/borrowck/two-phase-across-loop.stderr b/src/test/ui/borrowck/two-phase-across-loop.stderr index 933d3eb71117..38993a50bf6b 100644 --- a/src/test/ui/borrowck/two-phase-across-loop.stderr +++ b/src/test/ui/borrowck/two-phase-across-loop.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `foo` as mutable more than once at a time - --> $DIR/two-phase-across-loop.rs:19:22 + --> $DIR/two-phase-across-loop.rs:17:22 | LL | strings.push(foo.get_string()); | ^^^ mutable borrow starts here in previous iteration of loop diff --git a/src/test/ui/borrowck/two-phase-multi-mut.rs b/src/test/ui/borrowck/two-phase-multi-mut.rs index ed3d257da9f0..bb646d7caf1e 100644 --- a/src/test/ui/borrowck/two-phase-multi-mut.rs +++ b/src/test/ui/borrowck/two-phase-multi-mut.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - struct Foo { } diff --git a/src/test/ui/borrowck/two-phase-multi-mut.stderr b/src/test/ui/borrowck/two-phase-multi-mut.stderr index c4168503e4cc..33fa4a3a1507 100644 --- a/src/test/ui/borrowck/two-phase-multi-mut.stderr +++ b/src/test/ui/borrowck/two-phase-multi-mut.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `foo` as mutable more than once at a time - --> $DIR/two-phase-multi-mut.rs:13:5 + --> $DIR/two-phase-multi-mut.rs:11:5 | LL | foo.method(&mut foo); | ^^^^------^--------^ @@ -9,7 +9,7 @@ LL | foo.method(&mut foo); | second mutable borrow occurs here error[E0499]: cannot borrow `foo` as mutable more than once at a time - --> $DIR/two-phase-multi-mut.rs:13:16 + --> $DIR/two-phase-multi-mut.rs:11:16 | LL | foo.method(&mut foo); | --- ------ ^^^^^^^^ second mutable borrow occurs here diff --git a/src/test/ui/c-variadic/variadic-ffi-5.rs b/src/test/ui/c-variadic/variadic-ffi-5.rs deleted file mode 100644 index fcc80d9b0cca..000000000000 --- a/src/test/ui/c-variadic/variadic-ffi-5.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![crate_type="lib"] -#![no_std] -#![feature(c_variadic)] -// The tests in this file are similar to that of variadic-ffi-4, but this -// one enables nll. -#![feature(nll)] - -use core::ffi::VaList; - -pub unsafe extern "C" fn no_escape0<'a>(_: usize, ap: ...) -> VaList<'a> { - ap //~ ERROR: explicit lifetime required -} - -pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> { - ap //~ ERROR: explicit lifetime required -} - -pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) { - let _ = ap.with_copy(|ap| { ap }); //~ ERROR: lifetime may not live long enough -} - -pub unsafe extern "C" fn no_escape3(_: usize, ap0: &mut VaList, mut ap1: ...) { - *ap0 = ap1; //~ ERROR: lifetime may not live long enough -} - -pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) { - ap0 = &mut ap1; - //~^ ERROR: lifetime may not live long enough - //~^^ ERROR: lifetime may not live long enough - //~^^^ ERROR: `ap1` does not live long enough -} diff --git a/src/test/ui/c-variadic/variadic-ffi-5.stderr b/src/test/ui/c-variadic/variadic-ffi-5.stderr deleted file mode 100644 index 27421010a97c..000000000000 --- a/src/test/ui/c-variadic/variadic-ffi-5.stderr +++ /dev/null @@ -1,73 +0,0 @@ -error[E0621]: explicit lifetime required in the type of `ap` - --> $DIR/variadic-ffi-5.rs:11:5 - | -LL | pub unsafe extern "C" fn no_escape0<'a>(_: usize, ap: ...) -> VaList<'a> { - | --- help: add explicit lifetime `'a` to the type of `ap`: `core::ffi::VaList<'a>` -LL | ap - | ^^ lifetime `'a` required - -error[E0621]: explicit lifetime required in the type of `ap` - --> $DIR/variadic-ffi-5.rs:15:5 - | -LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> { - | --- help: add explicit lifetime `'static` to the type of `ap`: `core::ffi::VaList<'static>` -LL | ap - | ^^ lifetime `'static` required - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-5.rs:19:33 - | -LL | let _ = ap.with_copy(|ap| { ap }); - | --- ^^ returning this value requires that `'1` must outlive `'2` - | | | - | | return type of closure is core::ffi::VaList<'2> - | has type `core::ffi::VaList<'1>` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-5.rs:23:5 - | -LL | pub unsafe extern "C" fn no_escape3(_: usize, ap0: &mut VaList, mut ap1: ...) { - | --- ------- has type `core::ffi::VaList<'1>` - | | - | has type `&mut core::ffi::VaList<'2>` -LL | *ap0 = ap1; - | ^^^^^^^^^^ assignment requires that `'1` must outlive `'2` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-5.rs:27:5 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) { - | ------- ------- has type `core::ffi::VaList<'2>` - | | - | has type `&mut core::ffi::VaList<'1>` -LL | ap0 = &mut ap1; - | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-5.rs:27:5 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) { - | ------- ------- has type `core::ffi::VaList<'1>` - | | - | has type `&mut core::ffi::VaList<'2>` -LL | ap0 = &mut ap1; - | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` - -error[E0597]: `ap1` does not live long enough - --> $DIR/variadic-ffi-5.rs:27:11 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) { - | - let's call the lifetime of this reference `'1` -LL | ap0 = &mut ap1; - | ------^^^^^^^^ - | | | - | | borrowed value does not live long enough - | assignment requires that `ap1` is borrowed for `'1` -... -LL | } - | - `ap1` dropped here while still borrowed - -error: aborting due to 7 previous errors - -Some errors have detailed explanations: E0597, E0621. -For more information about an error, try `rustc --explain E0597`. diff --git a/src/test/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs b/src/test/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs index 06b1727258dc..34f61ed5a347 100644 --- a/src/test/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs +++ b/src/test/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs @@ -1,7 +1,5 @@ // compile-pass -#![feature(nll)] - pub fn main() { let y: &'static mut [u8; 0] = &mut []; } diff --git a/src/test/ui/consts/issue-54224.rs b/src/test/ui/consts/issue-54224.rs index b5a8fe8819cd..f1947933d670 100644 --- a/src/test/ui/consts/issue-54224.rs +++ b/src/test/ui/consts/issue-54224.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]); //~ ERROR temporary value dropped while borrowed use std::borrow::Cow; diff --git a/src/test/ui/consts/issue-54224.stderr b/src/test/ui/consts/issue-54224.stderr index 9b6638b228e7..8dcb4daca3b7 100644 --- a/src/test/ui/consts/issue-54224.stderr +++ b/src/test/ui/consts/issue-54224.stderr @@ -1,5 +1,5 @@ error[E0716]: temporary value dropped while borrowed - --> $DIR/issue-54224.rs:3:39 + --> $DIR/issue-54224.rs:1:39 | LL | const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]); | ------^^^^^^^^^- @@ -9,7 +9,7 @@ LL | const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]); | using this value as a constant requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/issue-54224.rs:11:57 + --> $DIR/issue-54224.rs:9:57 | LL | pub const Z: Cow<'static, [ [u8; 3] ]> = Cow::Borrowed(&[*b"ABC"]); | ---------------^^^^^^^^^- diff --git a/src/test/ui/consts/promote_evaluation_unused_result.rs b/src/test/ui/consts/promote_evaluation_unused_result.rs index d199e34775e4..dc21b9fe8cd1 100644 --- a/src/test/ui/consts/promote_evaluation_unused_result.rs +++ b/src/test/ui/consts/promote_evaluation_unused_result.rs @@ -1,7 +1,5 @@ //compile-pass -#![feature(nll)] - fn main() { let _: &'static usize = &(loop {}, 1).1; diff --git a/src/test/ui/consts/promote_fn_calls.rs b/src/test/ui/consts/promote_fn_calls.rs index 045322de3470..6b6eea36361b 100644 --- a/src/test/ui/consts/promote_fn_calls.rs +++ b/src/test/ui/consts/promote_fn_calls.rs @@ -1,8 +1,6 @@ // compile-pass // aux-build:promotable_const_fn_lib.rs -#![feature(nll)] - extern crate promotable_const_fn_lib; use promotable_const_fn_lib::{foo, Foo}; diff --git a/src/test/ui/consts/promote_fn_calls_std.rs b/src/test/ui/consts/promote_fn_calls_std.rs index 0350708d673d..d982f350208e 100644 --- a/src/test/ui/consts/promote_fn_calls_std.rs +++ b/src/test/ui/consts/promote_fn_calls_std.rs @@ -1,7 +1,5 @@ // compile-pass -#![feature(nll)] - fn main() { let x: &'static u8 = &u8::max_value(); let x: &'static u16 = &u16::max_value(); diff --git a/src/test/ui/generator/generator-region-requirements.rs b/src/test/ui/generator/generator-region-requirements.rs index cd9abaae056c..41cb339f4591 100644 --- a/src/test/ui/generator/generator-region-requirements.rs +++ b/src/test/ui/generator/generator-region-requirements.rs @@ -1,8 +1,4 @@ -// revisions: migrate nll -// ignore-compare-mode-nll - #![feature(generators, generator_trait)] -#![cfg_attr(nll, feature(nll))] use std::ops::{Generator, GeneratorState}; use std::pin::Pin; @@ -14,8 +10,7 @@ fn dangle(x: &mut i32) -> &'static mut i32 { loop { match Pin::new(&mut g).resume() { GeneratorState::Complete(c) => return c, -//[nll]~^ ERROR explicit lifetime required -//[migrate]~^^ ERROR explicit lifetime required + //~^ ERROR explicit lifetime required GeneratorState::Yielded(_) => (), } } diff --git a/src/test/ui/generator/generator-region-requirements.nll.stderr b/src/test/ui/generator/generator-region-requirements.stderr similarity index 90% rename from src/test/ui/generator/generator-region-requirements.nll.stderr rename to src/test/ui/generator/generator-region-requirements.stderr index 8a96d187f6b1..53d48bc4f56a 100644 --- a/src/test/ui/generator/generator-region-requirements.nll.stderr +++ b/src/test/ui/generator/generator-region-requirements.stderr @@ -1,5 +1,5 @@ error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/generator-region-requirements.rs:16:51 + --> $DIR/generator-region-requirements.rs:12:51 | LL | fn dangle(x: &mut i32) -> &'static mut i32 { | -------- help: add explicit lifetime `'static` to the type of `x`: `&'static mut i32` diff --git a/src/test/ui/generator/generator-with-nll.rs b/src/test/ui/generator/generator-with-nll.rs index 87afa57ab519..cee3e6d226c1 100644 --- a/src/test/ui/generator/generator-with-nll.rs +++ b/src/test/ui/generator/generator-with-nll.rs @@ -1,5 +1,4 @@ #![feature(generators)] -#![feature(nll)] fn main() { || { diff --git a/src/test/ui/generator/generator-with-nll.stderr b/src/test/ui/generator/generator-with-nll.stderr index bd5abb202068..14199aeb9305 100644 --- a/src/test/ui/generator/generator-with-nll.stderr +++ b/src/test/ui/generator/generator-with-nll.stderr @@ -1,5 +1,5 @@ error[E0626]: borrow may still be in use when generator yields - --> $DIR/generator-with-nll.rs:8:17 + --> $DIR/generator-with-nll.rs:7:17 | LL | let b = &mut true; | ^^^^^^^^^ diff --git a/src/test/ui/impl-trait/closure-calling-parent-fn.rs b/src/test/ui/impl-trait/closure-calling-parent-fn.rs index cb5f78bd6fc0..58d7875ccd03 100644 --- a/src/test/ui/impl-trait/closure-calling-parent-fn.rs +++ b/src/test/ui/impl-trait/closure-calling-parent-fn.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - // Regression test for #54593: the MIR type checker was going wrong // when a closure returns the `impl Copy` from its parent fn. It was // (incorrectly) replacing the `impl Copy` in its return type with the diff --git a/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs b/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs index cb40d90ae551..adaa474474f6 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs +++ b/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs @@ -9,7 +9,6 @@ #![allow(dead_code)] #![feature(in_band_lifetimes)] -#![feature(nll)] fn foo(x: &'x u32) -> impl Fn() -> &'y u32 where 'x: 'y diff --git a/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs b/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs index e2310a3907f7..204c2ff30411 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs +++ b/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs @@ -9,7 +9,6 @@ #![allow(dead_code)] #![feature(in_band_lifetimes)] -#![feature(nll)] trait Trait<'a> { } diff --git a/src/test/ui/impl-trait/region-escape-via-bound.rs b/src/test/ui/impl-trait/region-escape-via-bound.rs index d62aec800e8c..29243699e44f 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound.rs +++ b/src/test/ui/impl-trait/region-escape-via-bound.rs @@ -5,7 +5,6 @@ #![allow(dead_code)] #![feature(in_band_lifetimes)] -#![feature(nll)] use std::cell::Cell; diff --git a/src/test/ui/impl-trait/region-escape-via-bound.stderr b/src/test/ui/impl-trait/region-escape-via-bound.stderr index 81b44b7eba7f..5c8e322f712d 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound.stderr +++ b/src/test/ui/impl-trait/region-escape-via-bound.stderr @@ -1,11 +1,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/region-escape-via-bound.rs:16:29 + --> $DIR/region-escape-via-bound.rs:15:29 | LL | fn foo(x: Cell<&'x u32>) -> impl Trait<'y> | ^^^^^^^^^^^^^^ | -note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime 'x as defined on the function body at 18:7 - --> $DIR/region-escape-via-bound.rs:18:7 +note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime 'x as defined on the function body at 17:7 + --> $DIR/region-escape-via-bound.rs:17:7 | LL | where 'x: 'y | ^^ diff --git a/src/test/ui/issues/issue-34721.rs b/src/test/ui/issues/issue-34721.rs index 226c21446b1e..bdc9fe43a8bd 100644 --- a/src/test/ui/issues/issue-34721.rs +++ b/src/test/ui/issues/issue-34721.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - pub trait Foo { fn zero(self) -> Self; } diff --git a/src/test/ui/issues/issue-34721.stderr b/src/test/ui/issues/issue-34721.stderr index 2ed7b543e713..d5cede990a33 100644 --- a/src/test/ui/issues/issue-34721.stderr +++ b/src/test/ui/issues/issue-34721.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `x` - --> $DIR/issue-34721.rs:27:9 + --> $DIR/issue-34721.rs:25:9 | LL | pub fn baz(x: T) -> T { | - - move occurs because `x` has type `T`, which does not implement the `Copy` trait diff --git a/src/test/ui/issues/issue-45696-no-variant-box-recur.rs b/src/test/ui/issues/issue-45696-no-variant-box-recur.rs index b5d9036aba67..c688261fa1cb 100644 --- a/src/test/ui/issues/issue-45696-no-variant-box-recur.rs +++ b/src/test/ui/issues/issue-45696-no-variant-box-recur.rs @@ -6,11 +6,6 @@ // We will explicitly test NLL, and migration modes; thus we will also skip the // automated compare-mode=nll. -// revisions: nll migrate -// ignore-compare-mode-nll - -#![cfg_attr(nll, feature(nll))] - // run-pass // This test has structs and functions that are by definition unusable diff --git a/src/test/ui/issues/issue-46036.rs b/src/test/ui/issues/issue-46036.rs index c517bbe57e82..18af33c1821c 100644 --- a/src/test/ui/issues/issue-46036.rs +++ b/src/test/ui/issues/issue-46036.rs @@ -1,6 +1,5 @@ // Issue 46036: [NLL] false edges on infinite loops // Infinite loops should create false edges to the cleanup block. -#![feature(nll)] struct Foo { x: &'static u32 } diff --git a/src/test/ui/issues/issue-46036.stderr b/src/test/ui/issues/issue-46036.stderr index 9c1746e0fa1e..49dd0e267b8e 100644 --- a/src/test/ui/issues/issue-46036.stderr +++ b/src/test/ui/issues/issue-46036.stderr @@ -1,5 +1,5 @@ error[E0597]: `a` does not live long enough - --> $DIR/issue-46036.rs:9:24 + --> $DIR/issue-46036.rs:8:24 | LL | let foo = Foo { x: &a }; | ^^ diff --git a/src/test/ui/issues/issue-46983.rs b/src/test/ui/issues/issue-46983.rs index a5c1e17a58c3..c1fd7729bdef 100644 --- a/src/test/ui/issues/issue-46983.rs +++ b/src/test/ui/issues/issue-46983.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - fn foo(x: &u32) -> &'static u32 { &*x //~^ ERROR explicit lifetime required in the type of `x` [E0621] diff --git a/src/test/ui/issues/issue-46983.stderr b/src/test/ui/issues/issue-46983.stderr index 43d351ec905e..8a4a6bdb39fa 100644 --- a/src/test/ui/issues/issue-46983.stderr +++ b/src/test/ui/issues/issue-46983.stderr @@ -1,5 +1,5 @@ error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/issue-46983.rs:4:5 + --> $DIR/issue-46983.rs:2:5 | LL | fn foo(x: &u32) -> &'static u32 { | ---- help: add explicit lifetime `'static` to the type of `x`: `&'static u32` diff --git a/src/test/ui/issues/issue-47184.rs b/src/test/ui/issues/issue-47184.rs index 04f1146a8f8f..2f78ce0002ba 100644 --- a/src/test/ui/issues/issue-47184.rs +++ b/src/test/ui/issues/issue-47184.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - fn main() { let _vec: Vec<&'static String> = vec![&String::new()]; //~^ ERROR temporary value dropped while borrowed [E0716] diff --git a/src/test/ui/issues/issue-47184.stderr b/src/test/ui/issues/issue-47184.stderr index 2b4d576e726f..f97713b4ac43 100644 --- a/src/test/ui/issues/issue-47184.stderr +++ b/src/test/ui/issues/issue-47184.stderr @@ -1,5 +1,5 @@ error[E0716]: temporary value dropped while borrowed - --> $DIR/issue-47184.rs:4:44 + --> $DIR/issue-47184.rs:2:44 | LL | let _vec: Vec<&'static String> = vec![&String::new()]; | -------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement diff --git a/src/test/ui/issues/issue-47646.rs b/src/test/ui/issues/issue-47646.rs index c3c07bf64116..ace6cdce841a 100644 --- a/src/test/ui/issues/issue-47646.rs +++ b/src/test/ui/issues/issue-47646.rs @@ -1,6 +1,3 @@ -#![allow(warnings)] -#![feature(nll)] - use std::collections::BinaryHeap; fn main() { diff --git a/src/test/ui/issues/issue-47646.stderr b/src/test/ui/issues/issue-47646.stderr index db9f227d6b77..c0b876368480 100644 --- a/src/test/ui/issues/issue-47646.stderr +++ b/src/test/ui/issues/issue-47646.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `heap` as immutable because it is also borrowed as mutable - --> $DIR/issue-47646.rs:12:30 + --> $DIR/issue-47646.rs:9:30 | LL | let borrow = heap.peek_mut(); | ---- mutable borrow occurs here diff --git a/src/test/ui/issues/issue-47703-1.rs b/src/test/ui/issues/issue-47703-1.rs index 9add314fdaf0..74323317f195 100644 --- a/src/test/ui/issues/issue-47703-1.rs +++ b/src/test/ui/issues/issue-47703-1.rs @@ -1,6 +1,4 @@ // compile-pass -#![allow(dead_code)] -#![feature(nll)] struct AtomicRefMut<'a> { value: &'a mut i32, diff --git a/src/test/ui/issues/issue-47703-tuple.rs b/src/test/ui/issues/issue-47703-tuple.rs index 850771cffd0c..377eeb67ae1b 100644 --- a/src/test/ui/issues/issue-47703-tuple.rs +++ b/src/test/ui/issues/issue-47703-tuple.rs @@ -1,6 +1,4 @@ // compile-pass -#![allow(dead_code)] -#![feature(nll)] struct WithDrop; diff --git a/src/test/ui/issues/issue-47703.rs b/src/test/ui/issues/issue-47703.rs index 06b17e931a97..22f2a1f364d1 100644 --- a/src/test/ui/issues/issue-47703.rs +++ b/src/test/ui/issues/issue-47703.rs @@ -1,6 +1,4 @@ // compile-pass -#![allow(dead_code)] -#![feature(nll)] struct MyStruct<'a> { field: &'a mut (), diff --git a/src/test/ui/issues/issue-47722.rs b/src/test/ui/issues/issue-47722.rs index c9bc6147aa9c..cefc872668ce 100644 --- a/src/test/ui/issues/issue-47722.rs +++ b/src/test/ui/issues/issue-47722.rs @@ -1,10 +1,8 @@ // compile-pass -#![allow(dead_code)] // Tests that automatic coercions from &mut T to *mut T // allow borrows of T to expire immediately - essentially, that // they work identically to 'foo as *mut T' -#![feature(nll)] struct SelfReference { self_reference: *mut SelfReference, diff --git a/src/test/ui/issues/issue-47789.rs b/src/test/ui/issues/issue-47789.rs index d15a27a2a2e6..334bd608add1 100644 --- a/src/test/ui/issues/issue-47789.rs +++ b/src/test/ui/issues/issue-47789.rs @@ -1,9 +1,6 @@ // compile-pass -#![allow(dead_code)] #![allow(non_upper_case_globals)] -#![feature(nll)] - static mut x: &'static u32 = &0; fn foo() { diff --git a/src/test/ui/issues/issue-48132.rs b/src/test/ui/issues/issue-48132.rs index b3cef78f3e6b..ea325ea695f6 100644 --- a/src/test/ui/issues/issue-48132.rs +++ b/src/test/ui/issues/issue-48132.rs @@ -3,9 +3,6 @@ // run-pass -#![feature(nll)] -#![allow(warnings)] - struct Inner { iterator: I, item: V, diff --git a/src/test/ui/issues/issue-48179.rs b/src/test/ui/issues/issue-48179.rs index 245f13b2b609..90e9858d7419 100644 --- a/src/test/ui/issues/issue-48179.rs +++ b/src/test/ui/issues/issue-48179.rs @@ -3,9 +3,6 @@ // run-pass -#![feature(nll)] -#![allow(warnings)] - pub struct Container { value: Option, } diff --git a/src/test/ui/issues/issue-48803.rs b/src/test/ui/issues/issue-48803.rs index bc1bc29c98f2..f7fd04179f26 100644 --- a/src/test/ui/issues/issue-48803.rs +++ b/src/test/ui/issues/issue-48803.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - fn flatten<'a, 'b, T>(x: &'a &'b T) -> &'a T { x } diff --git a/src/test/ui/issues/issue-48803.stderr b/src/test/ui/issues/issue-48803.stderr index 9a6da9e625da..2f94039c0c3a 100644 --- a/src/test/ui/issues/issue-48803.stderr +++ b/src/test/ui/issues/issue-48803.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/issue-48803.rs:12:5 + --> $DIR/issue-48803.rs:10:5 | LL | let y = &x; | -- borrow of `x` occurs here diff --git a/src/test/ui/issues/issue-49579.rs b/src/test/ui/issues/issue-49579.rs index 34f277af01e9..dd7b9eeb8d54 100644 --- a/src/test/ui/issues/issue-49579.rs +++ b/src/test/ui/issues/issue-49579.rs @@ -1,8 +1,6 @@ // compile-pass // ignore-emscripten no i128 support -#![feature(nll)] - fn fibs(n: u32) -> impl Iterator { (0 .. n) .scan((0, 1), |st, _| { diff --git a/src/test/ui/issues/issue-51515.rs b/src/test/ui/issues/issue-51515.rs index 64d9822bab4d..8eab7b2fa3ae 100644 --- a/src/test/ui/issues/issue-51515.rs +++ b/src/test/ui/issues/issue-51515.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - fn main() { let foo = &16; //~^ HELP consider changing this to be a mutable reference diff --git a/src/test/ui/issues/issue-51515.stderr b/src/test/ui/issues/issue-51515.stderr index 0e6c8fd48f19..827bb8fe2b89 100644 --- a/src/test/ui/issues/issue-51515.stderr +++ b/src/test/ui/issues/issue-51515.stderr @@ -1,5 +1,5 @@ error[E0594]: cannot assign to `*foo` which is behind a `&` reference - --> $DIR/issue-51515.rs:7:5 + --> $DIR/issue-51515.rs:5:5 | LL | let foo = &16; | --- help: consider changing this to be a mutable reference: `&mut 16` @@ -8,7 +8,7 @@ LL | *foo = 32; | ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written error[E0594]: cannot assign to `*bar` which is behind a `&` reference - --> $DIR/issue-51515.rs:12:5 + --> $DIR/issue-51515.rs:10:5 | LL | let bar = foo; | --- help: consider changing this to be a mutable reference: `&mut i32` diff --git a/src/test/ui/issues/issue-52057.rs b/src/test/ui/issues/issue-52057.rs index 356efd5dfedb..911983445e6d 100644 --- a/src/test/ui/issues/issue-52057.rs +++ b/src/test/ui/issues/issue-52057.rs @@ -4,8 +4,6 @@ // // run-pass -#![feature(nll)] - pub trait Parser { type Input; diff --git a/src/test/ui/issues/issue-52992.rs b/src/test/ui/issues/issue-52992.rs index 0fdf077d2fc1..c58656330e12 100644 --- a/src/test/ui/issues/issue-52992.rs +++ b/src/test/ui/issues/issue-52992.rs @@ -4,8 +4,6 @@ // // compile-pass -#![feature(nll)] - fn main() {} fn fail<'a>() -> Struct<'a, Generic<()>> { diff --git a/src/test/ui/issues/issue-53568.rs b/src/test/ui/issues/issue-53568.rs index f04d861250b4..4d3b3f80a97e 100644 --- a/src/test/ui/issues/issue-53568.rs +++ b/src/test/ui/issues/issue-53568.rs @@ -3,9 +3,6 @@ // // compile-pass -#![feature(nll)] -#![allow(dead_code)] - trait Future { type Item; } diff --git a/src/test/ui/issues/issue-54943-1.rs b/src/test/ui/issues/issue-54943-1.rs index 7750e3403619..8d3a4e72de41 100644 --- a/src/test/ui/issues/issue-54943-1.rs +++ b/src/test/ui/issues/issue-54943-1.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - // This test is a minimal version of an ICE in the dropck-eyepatch tests // found in the fix for #54943. diff --git a/src/test/ui/issues/issue-54943-2.rs b/src/test/ui/issues/issue-54943-2.rs index f829c38c35d2..41ca7c149826 100644 --- a/src/test/ui/issues/issue-54943-2.rs +++ b/src/test/ui/issues/issue-54943-2.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - // This test is a minimal version of an ICE in the dropck-eyepatch tests // found in the fix for #54943. In particular, this test is in unreachable // code as the initial fix for this ICE only worked if the code was reachable. diff --git a/src/test/ui/issues/issue-54943.nll.stderr b/src/test/ui/issues/issue-54943.nll.stderr new file mode 100644 index 000000000000..59be0f983b90 --- /dev/null +++ b/src/test/ui/issues/issue-54943.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/issue-54943.rs:6:13 + | +LL | fn boo<'a>() { + | -- lifetime `'a` defined here +... +LL | let x = foo::<&'a u32>(); + | ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-54943.rs b/src/test/ui/issues/issue-54943.rs index ce4e01067435..85722300bf00 100644 --- a/src/test/ui/issues/issue-54943.rs +++ b/src/test/ui/issues/issue-54943.rs @@ -1,13 +1,10 @@ -#![feature(nll)] -#![allow(warnings)] - fn foo() { } fn boo<'a>() { return; let x = foo::<&'a u32>(); - //~^ ERROR lifetime may not live long enough + //~^ ERROR } fn main() {} diff --git a/src/test/ui/issues/issue-54943.stderr b/src/test/ui/issues/issue-54943.stderr index aa68177bcdb5..d0f03f90c833 100644 --- a/src/test/ui/issues/issue-54943.stderr +++ b/src/test/ui/issues/issue-54943.stderr @@ -1,11 +1,10 @@ -error: lifetime may not live long enough - --> $DIR/issue-54943.rs:9:13 +error[E0477]: the type `&'a u32` does not fulfill the required lifetime + --> $DIR/issue-54943.rs:6:13 | -LL | fn boo<'a>() { - | -- lifetime `'a` defined here -... LL | let x = foo::<&'a u32>(); - | ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + | ^^^^^^^^^^^^^^ + | + = note: type must satisfy the static lifetime error: aborting due to previous error diff --git a/src/test/ui/mir-dataflow/def-inits-1.rs b/src/test/ui/mir-dataflow/def-inits-1.rs index 07ac1900bc71..91d41e9b5794 100644 --- a/src/test/ui/mir-dataflow/def-inits-1.rs +++ b/src/test/ui/mir-dataflow/def-inits-1.rs @@ -1,6 +1,5 @@ // General test of maybe_uninits state computed by MIR dataflow. -#![feature(nll)] #![feature(core_intrinsics, rustc_attrs)] use std::intrinsics::rustc_peek; diff --git a/src/test/ui/mir-dataflow/def-inits-1.stderr b/src/test/ui/mir-dataflow/def-inits-1.stderr index 6bc5f7dcb99f..48d845048948 100644 --- a/src/test/ui/mir-dataflow/def-inits-1.stderr +++ b/src/test/ui/mir-dataflow/def-inits-1.stderr @@ -1,23 +1,23 @@ error: rustc_peek: bit not set - --> $DIR/def-inits-1.rs:15:14 + --> $DIR/def-inits-1.rs:14:14 | LL | unsafe { rustc_peek(&ret); } | ^^^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/def-inits-1.rs:31:14 + --> $DIR/def-inits-1.rs:30:14 | LL | unsafe { rustc_peek(&z); } | ^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/def-inits-1.rs:34:14 + --> $DIR/def-inits-1.rs:33:14 | LL | unsafe { rustc_peek(&y); } | ^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/def-inits-1.rs:42:14 + --> $DIR/def-inits-1.rs:41:14 | LL | unsafe { rustc_peek(&x); } | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/mir-dataflow/inits-1.rs b/src/test/ui/mir-dataflow/inits-1.rs index 13f900e4a75e..4a4786a2a737 100644 --- a/src/test/ui/mir-dataflow/inits-1.rs +++ b/src/test/ui/mir-dataflow/inits-1.rs @@ -1,6 +1,5 @@ // General test of maybe_inits state computed by MIR dataflow. -#![feature(nll)] #![feature(core_intrinsics, rustc_attrs)] use std::intrinsics::rustc_peek; diff --git a/src/test/ui/mir-dataflow/inits-1.stderr b/src/test/ui/mir-dataflow/inits-1.stderr index 38a9c60b168d..23d0679cb1ac 100644 --- a/src/test/ui/mir-dataflow/inits-1.stderr +++ b/src/test/ui/mir-dataflow/inits-1.stderr @@ -1,17 +1,17 @@ error: rustc_peek: bit not set - --> $DIR/inits-1.rs:15:14 + --> $DIR/inits-1.rs:14:14 | LL | unsafe { rustc_peek(&ret); } | ^^^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/inits-1.rs:35:14 + --> $DIR/inits-1.rs:34:14 | LL | unsafe { rustc_peek(&y); } | ^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/inits-1.rs:43:14 + --> $DIR/inits-1.rs:42:14 | LL | unsafe { rustc_peek(&x); } | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/mir-dataflow/uninits-1.rs b/src/test/ui/mir-dataflow/uninits-1.rs index 4c6435969329..66b3f458a515 100644 --- a/src/test/ui/mir-dataflow/uninits-1.rs +++ b/src/test/ui/mir-dataflow/uninits-1.rs @@ -1,6 +1,5 @@ // General test of maybe_uninits state computed by MIR dataflow. -#![feature(nll)] #![feature(core_intrinsics, rustc_attrs)] use std::intrinsics::rustc_peek; diff --git a/src/test/ui/mir-dataflow/uninits-1.stderr b/src/test/ui/mir-dataflow/uninits-1.stderr index c60987050e63..5f6dbde212d0 100644 --- a/src/test/ui/mir-dataflow/uninits-1.stderr +++ b/src/test/ui/mir-dataflow/uninits-1.stderr @@ -1,29 +1,29 @@ error: rustc_peek: bit not set - --> $DIR/uninits-1.rs:19:14 + --> $DIR/uninits-1.rs:18:14 | LL | unsafe { rustc_peek(&x) }; | ^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/uninits-1.rs:20:14 + --> $DIR/uninits-1.rs:19:14 | LL | unsafe { rustc_peek(&y) }; | ^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/uninits-1.rs:21:14 + --> $DIR/uninits-1.rs:20:14 | LL | unsafe { rustc_peek(&z) }; | ^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/uninits-1.rs:37:14 + --> $DIR/uninits-1.rs:36:14 | LL | unsafe { rustc_peek(&x); } | ^^^^^^^^^^^^^^ error: rustc_peek: bit not set - --> $DIR/uninits-1.rs:45:14 + --> $DIR/uninits-1.rs:44:14 | LL | unsafe { rustc_peek(&ret); } | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/mir-dataflow/uninits-2.rs b/src/test/ui/mir-dataflow/uninits-2.rs index 2247e68d097f..2ccf1c7f9d6c 100644 --- a/src/test/ui/mir-dataflow/uninits-2.rs +++ b/src/test/ui/mir-dataflow/uninits-2.rs @@ -1,6 +1,5 @@ // General test of maybe_uninits state computed by MIR dataflow. -#![feature(nll)] #![feature(core_intrinsics, rustc_attrs)] use std::intrinsics::rustc_peek; diff --git a/src/test/ui/mir-dataflow/uninits-2.stderr b/src/test/ui/mir-dataflow/uninits-2.stderr index de3e58e52de4..dcb61371994d 100644 --- a/src/test/ui/mir-dataflow/uninits-2.stderr +++ b/src/test/ui/mir-dataflow/uninits-2.stderr @@ -1,5 +1,5 @@ error: rustc_peek: bit not set - --> $DIR/uninits-2.rs:15:14 + --> $DIR/uninits-2.rs:14:14 | LL | unsafe { rustc_peek(&x) }; | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/nll/borrow-use-issue-46875.rs b/src/test/ui/nll/borrow-use-issue-46875.rs index 03db28fc508b..42e28b9674b3 100644 --- a/src/test/ui/nll/borrow-use-issue-46875.rs +++ b/src/test/ui/nll/borrow-use-issue-46875.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - // run-pass fn vec() { diff --git a/src/test/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs b/src/test/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs index 59936a809253..7d3b00dfc716 100644 --- a/src/test/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs +++ b/src/test/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs @@ -3,7 +3,6 @@ // // FIXME(#54366) - We probably shouldn't allow #[thread_local] static mut to get a 'static lifetime. -#![feature(nll)] #![feature(thread_local)] #[thread_local] diff --git a/src/test/ui/nll/borrowed-local-error.rs b/src/test/ui/nll/borrowed-local-error.rs index d37e61b63a81..d333356d964c 100644 --- a/src/test/ui/nll/borrowed-local-error.rs +++ b/src/test/ui/nll/borrowed-local-error.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - fn gimme(x: &(u32,)) -> &u32 { &x.0 } diff --git a/src/test/ui/nll/borrowed-local-error.stderr b/src/test/ui/nll/borrowed-local-error.stderr index 799eec9d3422..d629caa43531 100644 --- a/src/test/ui/nll/borrowed-local-error.stderr +++ b/src/test/ui/nll/borrowed-local-error.stderr @@ -1,5 +1,5 @@ error[E0597]: `v` does not live long enough - --> $DIR/borrowed-local-error.rs:10:9 + --> $DIR/borrowed-local-error.rs:8:9 | LL | let x = gimme({ | ----- borrow later used by call diff --git a/src/test/ui/nll/borrowed-referent-issue-38899.rs b/src/test/ui/nll/borrowed-referent-issue-38899.rs index 7bad6dc2cd33..d4b05fb79316 100644 --- a/src/test/ui/nll/borrowed-referent-issue-38899.rs +++ b/src/test/ui/nll/borrowed-referent-issue-38899.rs @@ -1,7 +1,6 @@ // Regression test for issue #38899 #![feature(nll)] -#![allow(dead_code)] pub struct Block<'a> { current: &'a u8, diff --git a/src/test/ui/nll/borrowed-referent-issue-38899.stderr b/src/test/ui/nll/borrowed-referent-issue-38899.stderr index 5c9c48f5b1d8..38a6e27a0e56 100644 --- a/src/test/ui/nll/borrowed-referent-issue-38899.stderr +++ b/src/test/ui/nll/borrowed-referent-issue-38899.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable - --> $DIR/borrowed-referent-issue-38899.rs:14:21 + --> $DIR/borrowed-referent-issue-38899.rs:13:21 | LL | let x = &mut block; | ---------- mutable borrow occurs here diff --git a/src/test/ui/nll/borrowed-temporary-error.rs b/src/test/ui/nll/borrowed-temporary-error.rs index 5ad987c72147..37d0e670d350 100644 --- a/src/test/ui/nll/borrowed-temporary-error.rs +++ b/src/test/ui/nll/borrowed-temporary-error.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - fn gimme(x: &(u32,)) -> &u32 { &x.0 } diff --git a/src/test/ui/nll/borrowed-temporary-error.stderr b/src/test/ui/nll/borrowed-temporary-error.stderr index c0d42312eb1a..2c6bd92641f6 100644 --- a/src/test/ui/nll/borrowed-temporary-error.stderr +++ b/src/test/ui/nll/borrowed-temporary-error.stderr @@ -1,5 +1,5 @@ error[E0716]: temporary value dropped while borrowed - --> $DIR/borrowed-temporary-error.rs:10:10 + --> $DIR/borrowed-temporary-error.rs:8:10 | LL | &(v,) | ^^^^ creates a temporary which is freed while still in use diff --git a/src/test/ui/nll/borrowed-universal-error-2.rs b/src/test/ui/nll/borrowed-universal-error-2.rs index a10a62b470d7..3f9b2f2924c2 100644 --- a/src/test/ui/nll/borrowed-universal-error-2.rs +++ b/src/test/ui/nll/borrowed-universal-error-2.rs @@ -1,6 +1,3 @@ -#![feature(nll)] -#![allow(warnings)] - fn foo<'a>(x: &'a (u32,)) -> &'a u32 { let v = 22; &v diff --git a/src/test/ui/nll/borrowed-universal-error-2.stderr b/src/test/ui/nll/borrowed-universal-error-2.stderr index e89a77a2d360..7213ed3bafb3 100644 --- a/src/test/ui/nll/borrowed-universal-error-2.stderr +++ b/src/test/ui/nll/borrowed-universal-error-2.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return reference to local variable `v` - --> $DIR/borrowed-universal-error-2.rs:6:5 + --> $DIR/borrowed-universal-error-2.rs:3:5 | LL | &v | ^^ returns a reference to data owned by the current function diff --git a/src/test/ui/nll/borrowed-universal-error.rs b/src/test/ui/nll/borrowed-universal-error.rs index 18a0a72c4bb8..fc9ffd47061b 100644 --- a/src/test/ui/nll/borrowed-universal-error.rs +++ b/src/test/ui/nll/borrowed-universal-error.rs @@ -1,6 +1,3 @@ -#![feature(nll)] -#![allow(warnings)] - fn gimme(x: &(u32,)) -> &u32 { &x.0 } diff --git a/src/test/ui/nll/borrowed-universal-error.stderr b/src/test/ui/nll/borrowed-universal-error.stderr index 4b76795943e6..88a2d8fcf8cc 100644 --- a/src/test/ui/nll/borrowed-universal-error.stderr +++ b/src/test/ui/nll/borrowed-universal-error.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return value referencing temporary value - --> $DIR/borrowed-universal-error.rs:10:5 + --> $DIR/borrowed-universal-error.rs:7:5 | LL | gimme(&(v,)) | ^^^^^^^----^ diff --git a/src/test/ui/nll/capture-mut-ref.rs b/src/test/ui/nll/capture-mut-ref.rs index 222f4e71c52f..9d2624a9d6fa 100644 --- a/src/test/ui/nll/capture-mut-ref.rs +++ b/src/test/ui/nll/capture-mut-ref.rs @@ -1,7 +1,6 @@ // Check that capturing a mutable reference by move and assigning to its // referent doesn't make the unused mut lint think that it is mutable. -#![feature(nll)] #![deny(unused_mut)] fn mutable_upvar() { diff --git a/src/test/ui/nll/capture-mut-ref.stderr b/src/test/ui/nll/capture-mut-ref.stderr index 327ce0c6e81f..883b2d05a7f5 100644 --- a/src/test/ui/nll/capture-mut-ref.stderr +++ b/src/test/ui/nll/capture-mut-ref.stderr @@ -1,5 +1,5 @@ error: variable does not need to be mutable - --> $DIR/capture-mut-ref.rs:8:9 + --> $DIR/capture-mut-ref.rs:7:9 | LL | let mut x = &mut 0; | ----^ @@ -7,7 +7,7 @@ LL | let mut x = &mut 0; | help: remove this `mut` | note: lint level defined here - --> $DIR/capture-mut-ref.rs:5:9 + --> $DIR/capture-mut-ref.rs:4:9 | LL | #![deny(unused_mut)] | ^^^^^^^^^^ diff --git a/src/test/ui/nll/capture-ref-in-struct.rs b/src/test/ui/nll/capture-ref-in-struct.rs index bf2db32901e6..db6ac7d66ccc 100644 --- a/src/test/ui/nll/capture-ref-in-struct.rs +++ b/src/test/ui/nll/capture-ref-in-struct.rs @@ -1,9 +1,6 @@ // Test that a structure which tries to store a pointer to `y` into // `p` (indirectly) fails to compile. -#![feature(rustc_attrs)] -#![feature(nll)] - struct SomeStruct<'a, 'b: 'a> { p: &'a mut &'b i32, y: &'b i32, diff --git a/src/test/ui/nll/capture-ref-in-struct.stderr b/src/test/ui/nll/capture-ref-in-struct.stderr index 7fafb4474fdb..521e543bd269 100644 --- a/src/test/ui/nll/capture-ref-in-struct.stderr +++ b/src/test/ui/nll/capture-ref-in-struct.stderr @@ -1,5 +1,5 @@ error[E0597]: `y` does not live long enough - --> $DIR/capture-ref-in-struct.rs:21:16 + --> $DIR/capture-ref-in-struct.rs:18:16 | LL | y: &y, | ^^ borrowed value does not live long enough diff --git a/src/test/ui/nll/closure-access-spans.rs b/src/test/ui/nll/closure-access-spans.rs index 1e11b4818183..2a59e80b25cd 100644 --- a/src/test/ui/nll/closure-access-spans.rs +++ b/src/test/ui/nll/closure-access-spans.rs @@ -1,7 +1,5 @@ // check that accesses due to a closure capture give a special note -#![feature(nll)] - fn closure_imm_capture_conflict(mut x: i32) { let r = &mut x; || x; //~ ERROR diff --git a/src/test/ui/nll/closure-access-spans.stderr b/src/test/ui/nll/closure-access-spans.stderr index 32958e28a3d0..4a8086905b7d 100644 --- a/src/test/ui/nll/closure-access-spans.stderr +++ b/src/test/ui/nll/closure-access-spans.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable - --> $DIR/closure-access-spans.rs:7:5 + --> $DIR/closure-access-spans.rs:5:5 | LL | let r = &mut x; | ------ mutable borrow occurs here @@ -11,7 +11,7 @@ LL | r.use_mut(); | - mutable borrow later used here error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/closure-access-spans.rs:13:5 + --> $DIR/closure-access-spans.rs:11:5 | LL | let r = &mut x; | ------ first mutable borrow occurs here @@ -23,7 +23,7 @@ LL | r.use_mut(); | - first borrow later used here error[E0500]: closure requires unique access to `x` but it is already borrowed - --> $DIR/closure-access-spans.rs:19:5 + --> $DIR/closure-access-spans.rs:17:5 | LL | let r = &mut x; | ------ borrow occurs here @@ -35,7 +35,7 @@ LL | r.use_mut(); | - first borrow later used here error[E0503]: cannot use `x` because it was mutably borrowed - --> $DIR/closure-access-spans.rs:25:13 + --> $DIR/closure-access-spans.rs:23:13 | LL | let r = &mut x; | ------ borrow of `x` occurs here @@ -45,7 +45,7 @@ LL | r.use_ref(); | - borrow later used here error[E0505]: cannot move out of `x` because it is borrowed - --> $DIR/closure-access-spans.rs:31:5 + --> $DIR/closure-access-spans.rs:29:5 | LL | let r = &x; | -- borrow of `x` occurs here @@ -57,7 +57,7 @@ LL | r.use_ref(); | - borrow later used here error[E0382]: borrow of moved value: `x` - --> $DIR/closure-access-spans.rs:37:5 + --> $DIR/closure-access-spans.rs:35:5 | LL | fn closure_imm_capture_moved(mut x: String) { | ----- move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait @@ -69,7 +69,7 @@ LL | || x.len(); | value borrowed here after move error[E0382]: borrow of moved value: `x` - --> $DIR/closure-access-spans.rs:42:5 + --> $DIR/closure-access-spans.rs:40:5 | LL | fn closure_mut_capture_moved(mut x: String) { | ----- move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait @@ -81,7 +81,7 @@ LL | || x = String::new(); | value borrowed here after move error[E0382]: borrow of moved value: `x` - --> $DIR/closure-access-spans.rs:47:5 + --> $DIR/closure-access-spans.rs:45:5 | LL | fn closure_unique_capture_moved(x: &mut String) { | - move occurs because `x` has type `&mut std::string::String`, which does not implement the `Copy` trait @@ -93,7 +93,7 @@ LL | || *x = String::new(); | value borrowed here after move error[E0382]: use of moved value: `x` - --> $DIR/closure-access-spans.rs:52:5 + --> $DIR/closure-access-spans.rs:50:5 | LL | fn closure_move_capture_moved(x: &mut String) { | - move occurs because `x` has type `&mut std::string::String`, which does not implement the `Copy` trait diff --git a/src/test/ui/nll/closure-borrow-spans.rs b/src/test/ui/nll/closure-borrow-spans.rs index 7fc301b70380..b38f7900e8e5 100644 --- a/src/test/ui/nll/closure-borrow-spans.rs +++ b/src/test/ui/nll/closure-borrow-spans.rs @@ -1,7 +1,5 @@ // check that existing borrows due to a closure capture give a special note -#![feature(nll)] - fn move_while_borrowed(x: String) { let f = || x.len(); let y = x; //~ ERROR diff --git a/src/test/ui/nll/closure-borrow-spans.stderr b/src/test/ui/nll/closure-borrow-spans.stderr index 30d99d56678c..a3bcbbab3ec6 100644 --- a/src/test/ui/nll/closure-borrow-spans.stderr +++ b/src/test/ui/nll/closure-borrow-spans.stderr @@ -1,5 +1,5 @@ error[E0505]: cannot move out of `x` because it is borrowed - --> $DIR/closure-borrow-spans.rs:7:13 + --> $DIR/closure-borrow-spans.rs:5:13 | LL | let f = || x.len(); | -- - borrow occurs due to use in closure @@ -11,7 +11,7 @@ LL | f.use_ref(); | - borrow later used here error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable - --> $DIR/closure-borrow-spans.rs:13:13 + --> $DIR/closure-borrow-spans.rs:11:13 | LL | let f = || x; | -- - first borrow occurs due to use of `x` in closure @@ -23,7 +23,7 @@ LL | f.use_ref(); | - immutable borrow later used here error[E0597]: `x` does not live long enough - --> $DIR/closure-borrow-spans.rs:21:16 + --> $DIR/closure-borrow-spans.rs:19:16 | LL | f = || x; | -- ^ borrowed value does not live long enough @@ -35,7 +35,7 @@ LL | f.use_ref(); | - borrow later used here error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/closure-borrow-spans.rs:28:5 + --> $DIR/closure-borrow-spans.rs:26:5 | LL | let f = || x; | -- - borrow occurs due to use in closure @@ -47,7 +47,7 @@ LL | f.use_ref(); | - borrow later used here error[E0503]: cannot use `x` because it was mutably borrowed - --> $DIR/closure-borrow-spans.rs:34:13 + --> $DIR/closure-borrow-spans.rs:32:13 | LL | let f = || x = 0; | -- - borrow occurs due to use of `x` in closure @@ -59,7 +59,7 @@ LL | f.use_ref(); | - borrow later used here error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable - --> $DIR/closure-borrow-spans.rs:40:13 + --> $DIR/closure-borrow-spans.rs:38:13 | LL | let f = || x = 0; | -- - first borrow occurs due to use of `x` in closure @@ -71,7 +71,7 @@ LL | f.use_ref(); | - mutable borrow later used here error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/closure-borrow-spans.rs:46:13 + --> $DIR/closure-borrow-spans.rs:44:13 | LL | let f = || x = 0; | -- - first borrow occurs due to use of `x` in closure @@ -83,7 +83,7 @@ LL | f.use_ref(); | - first borrow later used here error[E0597]: `x` does not live long enough - --> $DIR/closure-borrow-spans.rs:54:16 + --> $DIR/closure-borrow-spans.rs:52:16 | LL | f = || x = 0; | -- ^ borrowed value does not live long enough @@ -95,7 +95,7 @@ LL | f.use_ref(); | - borrow later used here error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/closure-borrow-spans.rs:61:5 + --> $DIR/closure-borrow-spans.rs:59:5 | LL | let f = || x = 0; | -- - borrow occurs due to use in closure @@ -107,7 +107,7 @@ LL | f.use_ref(); | - borrow later used here error[E0505]: cannot move out of `x` because it is borrowed - --> $DIR/closure-borrow-spans.rs:67:13 + --> $DIR/closure-borrow-spans.rs:65:13 | LL | let f = || *x = 0; | -- - borrow occurs due to use in closure @@ -119,7 +119,7 @@ LL | f.use_ref(); | - borrow later used here error[E0501]: cannot borrow `x` as immutable because previous closure requires unique access - --> $DIR/closure-borrow-spans.rs:73:13 + --> $DIR/closure-borrow-spans.rs:71:13 | LL | let f = || *x = 0; | -- - first borrow occurs due to use of `x` in closure @@ -131,7 +131,7 @@ LL | f.use_ref(); | - first borrow later used here error[E0501]: cannot borrow `x` as mutable because previous closure requires unique access - --> $DIR/closure-borrow-spans.rs:79:13 + --> $DIR/closure-borrow-spans.rs:77:13 | LL | let f = || *x = 0; | -- - first borrow occurs due to use of `x` in closure @@ -143,7 +143,7 @@ LL | f.use_ref(); | - first borrow later used here error[E0597]: `x` does not live long enough - --> $DIR/closure-borrow-spans.rs:88:17 + --> $DIR/closure-borrow-spans.rs:86:17 | LL | f = || *x = 0; | -- ^ borrowed value does not live long enough @@ -155,7 +155,7 @@ LL | f.use_ref(); | - borrow later used here error[E0506]: cannot assign to `*x` because it is borrowed - --> $DIR/closure-borrow-spans.rs:95:5 + --> $DIR/closure-borrow-spans.rs:93:5 | LL | let f = || *x = 0; | -- - borrow occurs due to use in closure diff --git a/src/test/ui/nll/closure-captures.rs b/src/test/ui/nll/closure-captures.rs index 3a01f86cad89..16d90b971745 100644 --- a/src/test/ui/nll/closure-captures.rs +++ b/src/test/ui/nll/closure-captures.rs @@ -1,8 +1,5 @@ // Some cases with closures that might be problems -#![allow(unused)] -#![feature(nll)] - // Should have one error per assignment fn one_closure(x: i32) { diff --git a/src/test/ui/nll/closure-captures.stderr b/src/test/ui/nll/closure-captures.stderr index fbd02bc8095a..77f7d815eeb4 100644 --- a/src/test/ui/nll/closure-captures.stderr +++ b/src/test/ui/nll/closure-captures.stderr @@ -1,5 +1,5 @@ error[E0594]: cannot assign to `x`, as it is not declared as mutable - --> $DIR/closure-captures.rs:10:5 + --> $DIR/closure-captures.rs:7:5 | LL | fn one_closure(x: i32) { | - help: consider changing this to be mutable: `mut x` @@ -8,7 +8,7 @@ LL | x = 1; | ^^^^^ cannot assign error[E0594]: cannot assign to `x`, as it is not declared as mutable - --> $DIR/closure-captures.rs:12:5 + --> $DIR/closure-captures.rs:9:5 | LL | fn one_closure(x: i32) { | - help: consider changing this to be mutable: `mut x` @@ -17,7 +17,7 @@ LL | x = 1; | ^^^^^ cannot assign error[E0594]: cannot assign to `x`, as it is not declared as mutable - --> $DIR/closure-captures.rs:18:9 + --> $DIR/closure-captures.rs:15:9 | LL | fn two_closures(x: i32) { | - help: consider changing this to be mutable: `mut x` @@ -26,7 +26,7 @@ LL | x = 1; | ^^^^^ cannot assign error[E0594]: cannot assign to `x`, as it is not declared as mutable - --> $DIR/closure-captures.rs:22:9 + --> $DIR/closure-captures.rs:19:9 | LL | fn two_closures(x: i32) { | - help: consider changing this to be mutable: `mut x` @@ -35,7 +35,7 @@ LL | x = 1; | ^^^^^ cannot assign error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure - --> $DIR/closure-captures.rs:30:9 + --> $DIR/closure-captures.rs:27:9 | LL | || | ^^ cannot borrow as mutable @@ -43,7 +43,7 @@ LL | x = 1;} | - mutable borrow occurs due to use of `x` in closure | help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:29:12 + --> $DIR/closure-captures.rs:26:12 | LL | fn_ref(|| { | ____________^ @@ -52,7 +52,7 @@ LL | | x = 1;} | |________________^ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure - --> $DIR/closure-captures.rs:34:9 + --> $DIR/closure-captures.rs:31:9 | LL | || | ^^ cannot borrow as mutable @@ -60,7 +60,7 @@ LL | x = 1;}); | - mutable borrow occurs due to use of `x` in closure | help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:33:12 + --> $DIR/closure-captures.rs:30:12 | LL | fn_ref(move || { | ____________^ @@ -69,7 +69,7 @@ LL | | x = 1;}); | |___________^ error[E0594]: cannot assign to `x`, as it is not declared as mutable - --> $DIR/closure-captures.rs:42:10 + --> $DIR/closure-captures.rs:39:10 | LL | fn two_closures_ref(x: i32) { | - help: consider changing this to be mutable: `mut x` @@ -78,7 +78,7 @@ LL | x = 1;} | ^^^^^ cannot assign error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure - --> $DIR/closure-captures.rs:41:9 + --> $DIR/closure-captures.rs:38:9 | LL | || | ^^ cannot borrow as mutable @@ -86,7 +86,7 @@ LL | x = 1;} | - mutable borrow occurs due to use of `x` in closure | help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:40:12 + --> $DIR/closure-captures.rs:37:12 | LL | fn_ref(|| { | ____________^ @@ -95,7 +95,7 @@ LL | | x = 1;} | |________________^ error[E0594]: cannot assign to `x`, as it is not declared as mutable - --> $DIR/closure-captures.rs:46:5 + --> $DIR/closure-captures.rs:43:5 | LL | fn two_closures_ref(x: i32) { | - help: consider changing this to be mutable: `mut x` @@ -104,7 +104,7 @@ LL | x = 1;}); | ^^^^^ cannot assign error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure - --> $DIR/closure-captures.rs:45:9 + --> $DIR/closure-captures.rs:42:9 | LL | || | ^^ cannot borrow as mutable @@ -112,7 +112,7 @@ LL | x = 1;}); | - mutable borrow occurs due to use of `x` in closure | help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:44:12 + --> $DIR/closure-captures.rs:41:12 | LL | fn_ref(move || { | ____________^ @@ -120,6 +120,23 @@ LL | | || LL | | x = 1;}); | |___________^ +error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure + --> $DIR/closure-captures.rs:48:9 + | +LL | || + | ^^ cannot borrow as mutable +LL | *x = 1;}); + | - mutable borrow occurs due to use of `x` in closure + | +help: consider changing this to accept closures that implement `FnMut` + --> $DIR/closure-captures.rs:47:12 + | +LL | fn_ref(|| { + | ____________^ +LL | | || +LL | | *x = 1;}); + | |________________^ + error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:51:9 | @@ -131,23 +148,6 @@ LL | *x = 1;}); help: consider changing this to accept closures that implement `FnMut` --> $DIR/closure-captures.rs:50:12 | -LL | fn_ref(|| { - | ____________^ -LL | | || -LL | | *x = 1;}); - | |________________^ - -error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure - --> $DIR/closure-captures.rs:54:9 - | -LL | || - | ^^ cannot borrow as mutable -LL | *x = 1;}); - | - mutable borrow occurs due to use of `x` in closure - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:53:12 - | LL | fn_ref(move || { | ____________^ LL | | || diff --git a/src/test/ui/nll/closure-move-spans.rs b/src/test/ui/nll/closure-move-spans.rs index ffbfa9f8ae48..bf2431870a94 100644 --- a/src/test/ui/nll/closure-move-spans.rs +++ b/src/test/ui/nll/closure-move-spans.rs @@ -1,7 +1,5 @@ // check that moves due to a closure capture give a special note -#![feature(nll)] - fn move_after_move(x: String) { || x; let y = x; //~ ERROR diff --git a/src/test/ui/nll/closure-move-spans.stderr b/src/test/ui/nll/closure-move-spans.stderr index 1cc4ca85b9ff..972dbc6a61d0 100644 --- a/src/test/ui/nll/closure-move-spans.stderr +++ b/src/test/ui/nll/closure-move-spans.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `x` - --> $DIR/closure-move-spans.rs:7:13 + --> $DIR/closure-move-spans.rs:5:13 | LL | fn move_after_move(x: String) { | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait @@ -11,7 +11,7 @@ LL | let y = x; | ^ value used here after move error[E0382]: borrow of moved value: `x` - --> $DIR/closure-move-spans.rs:12:13 + --> $DIR/closure-move-spans.rs:10:13 | LL | fn borrow_after_move(x: String) { | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait @@ -23,7 +23,7 @@ LL | let y = &x; | ^^ value borrowed here after move error[E0382]: borrow of moved value: `x` - --> $DIR/closure-move-spans.rs:17:13 + --> $DIR/closure-move-spans.rs:15:13 | LL | fn borrow_mut_after_move(mut x: String) { | ----- move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait diff --git a/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs b/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs index 71d5d4053ee2..8ed6554877ea 100644 --- a/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs +++ b/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs @@ -1,7 +1,3 @@ -// revisions: migrate nll -//[migrate]compile-flags: -Z borrowck=migrate -#![cfg_attr(nll, feature(nll))] - // compile-pass // Test that we propagate region relations from closures precisely when there is diff --git a/src/test/ui/nll/closure-requirements/propagate-multiple-requirements.rs b/src/test/ui/nll/closure-requirements/propagate-multiple-requirements.rs index dbc659b4aeef..a9d2a07715d4 100644 --- a/src/test/ui/nll/closure-requirements/propagate-multiple-requirements.rs +++ b/src/test/ui/nll/closure-requirements/propagate-multiple-requirements.rs @@ -1,8 +1,6 @@ // Test that we propagate *all* requirements to the caller, not just the first // one. -#![feature(nll)] - fn once U>(f: F, s: S, t: T) -> U { f(s, t) } diff --git a/src/test/ui/nll/closure-requirements/propagate-multiple-requirements.stderr b/src/test/ui/nll/closure-requirements/propagate-multiple-requirements.stderr index 332724daaa8b..2fec9bc62d1c 100644 --- a/src/test/ui/nll/closure-requirements/propagate-multiple-requirements.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-multiple-requirements.stderr @@ -1,5 +1,5 @@ error[E0597]: `local_arr` does not live long enough - --> $DIR/propagate-multiple-requirements.rs:17:14 + --> $DIR/propagate-multiple-requirements.rs:15:14 | LL | let mut out: &mut &'static [i32] = &mut (&[1] as _); | ------------------- type annotation requires that `local_arr` is borrowed for `'static` diff --git a/src/test/ui/nll/closure-use-spans.rs b/src/test/ui/nll/closure-use-spans.rs index c7cd519cffbc..6768250dcbc0 100644 --- a/src/test/ui/nll/closure-use-spans.rs +++ b/src/test/ui/nll/closure-use-spans.rs @@ -1,7 +1,5 @@ // check that liveness due to a closure capture gives a special note -#![feature(nll)] - fn use_as_borrow_capture(mut x: i32) { let y = &x; x = 0; //~ ERROR diff --git a/src/test/ui/nll/closure-use-spans.stderr b/src/test/ui/nll/closure-use-spans.stderr index 20696da3b8e8..ec7e0f308557 100644 --- a/src/test/ui/nll/closure-use-spans.stderr +++ b/src/test/ui/nll/closure-use-spans.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/closure-use-spans.rs:7:5 + --> $DIR/closure-use-spans.rs:5:5 | LL | let y = &x; | -- borrow of `x` occurs here @@ -9,7 +9,7 @@ LL | || *y; | - borrow later captured here by closure error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/closure-use-spans.rs:13:5 + --> $DIR/closure-use-spans.rs:11:5 | LL | let y = &mut x; | ------ borrow of `x` occurs here @@ -19,7 +19,7 @@ LL | || *y = 1; | - borrow later captured here by closure error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/closure-use-spans.rs:19:5 + --> $DIR/closure-use-spans.rs:17:5 | LL | let y = &x; | -- borrow of `x` occurs here diff --git a/src/test/ui/nll/closures-in-loops.rs b/src/test/ui/nll/closures-in-loops.rs index d2afa564734c..491c186ecb5a 100644 --- a/src/test/ui/nll/closures-in-loops.rs +++ b/src/test/ui/nll/closures-in-loops.rs @@ -1,8 +1,6 @@ // Test messages where a closure capture conflicts with itself because it's in // a loop. -#![feature(nll)] - fn repreated_move(x: String) { for i in 0..10 { || x; //~ ERROR diff --git a/src/test/ui/nll/closures-in-loops.stderr b/src/test/ui/nll/closures-in-loops.stderr index 692eaea92b83..7603f9650b54 100644 --- a/src/test/ui/nll/closures-in-loops.stderr +++ b/src/test/ui/nll/closures-in-loops.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `x` - --> $DIR/closures-in-loops.rs:8:9 + --> $DIR/closures-in-loops.rs:6:9 | LL | fn repreated_move(x: String) { | - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait @@ -10,7 +10,7 @@ LL | || x; | value moved into closure here, in previous iteration of loop error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/closures-in-loops.rs:15:16 + --> $DIR/closures-in-loops.rs:13:16 | LL | v.push(|| x = String::new()); | ^^ - borrows occur due to use of `x` in closure @@ -18,7 +18,7 @@ LL | v.push(|| x = String::new()); | mutable borrow starts here in previous iteration of loop error[E0524]: two closures require unique access to `x` at the same time - --> $DIR/closures-in-loops.rs:22:16 + --> $DIR/closures-in-loops.rs:20:16 | LL | v.push(|| *x = String::new()); | ^^ - borrows occur due to use of `x` in closure diff --git a/src/test/ui/nll/constant-thread-locals-issue-47053.rs b/src/test/ui/nll/constant-thread-locals-issue-47053.rs index 4dd01410c5e4..dde0ef7a5bb8 100644 --- a/src/test/ui/nll/constant-thread-locals-issue-47053.rs +++ b/src/test/ui/nll/constant-thread-locals-issue-47053.rs @@ -1,6 +1,5 @@ // Regression test for issue #47053 -#![feature(nll)] #![feature(thread_local)] #[thread_local] diff --git a/src/test/ui/nll/constant-thread-locals-issue-47053.stderr b/src/test/ui/nll/constant-thread-locals-issue-47053.stderr index 16a6e59e4da3..8afb42d66a61 100644 --- a/src/test/ui/nll/constant-thread-locals-issue-47053.stderr +++ b/src/test/ui/nll/constant-thread-locals-issue-47053.stderr @@ -1,5 +1,5 @@ error[E0594]: cannot assign to immutable static item `FOO` - --> $DIR/constant-thread-locals-issue-47053.rs:10:5 + --> $DIR/constant-thread-locals-issue-47053.rs:9:5 | LL | FOO = 6; | ^^^^^^^ cannot assign diff --git a/src/test/ui/nll/decl-macro-illegal-copy.rs b/src/test/ui/nll/decl-macro-illegal-copy.rs index 38bdb7dd270f..f7243294669a 100644 --- a/src/test/ui/nll/decl-macro-illegal-copy.rs +++ b/src/test/ui/nll/decl-macro-illegal-copy.rs @@ -1,6 +1,5 @@ // Regression test for #46314 -#![feature(nll)] #![feature(decl_macro)] struct NonCopy(String); diff --git a/src/test/ui/nll/decl-macro-illegal-copy.stderr b/src/test/ui/nll/decl-macro-illegal-copy.stderr index 9232ff52393e..7948485bd686 100644 --- a/src/test/ui/nll/decl-macro-illegal-copy.stderr +++ b/src/test/ui/nll/decl-macro-illegal-copy.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `wrapper.inner` - --> $DIR/decl-macro-illegal-copy.rs:22:9 + --> $DIR/decl-macro-illegal-copy.rs:21:9 | LL | $wrapper.inner | -------------- value moved here diff --git a/src/test/ui/nll/issue-16223.rs b/src/test/ui/nll/issue-16223.rs index 881e202acf8d..e75362750645 100644 --- a/src/test/ui/nll/issue-16223.rs +++ b/src/test/ui/nll/issue-16223.rs @@ -15,7 +15,6 @@ // compile-pass -#![feature(nll)] #![feature(box_patterns)] struct Root { diff --git a/src/test/ui/nll/issue-21114-ebfull.rs b/src/test/ui/nll/issue-21114-ebfull.rs index f5738968746e..1fe4fffa324a 100644 --- a/src/test/ui/nll/issue-21114-ebfull.rs +++ b/src/test/ui/nll/issue-21114-ebfull.rs @@ -1,6 +1,4 @@ -// (this works, but only in NLL) // compile-pass -#![feature(nll)] use std::collections::HashMap; use std::sync::Mutex; diff --git a/src/test/ui/nll/issue-21114-kixunil.rs b/src/test/ui/nll/issue-21114-kixunil.rs index 2add951b70bc..80a85293e5a5 100644 --- a/src/test/ui/nll/issue-21114-kixunil.rs +++ b/src/test/ui/nll/issue-21114-kixunil.rs @@ -1,6 +1,4 @@ -// (this works, but only in NLL) // compile-pass -#![feature(nll)] fn from_stdin(min: u64) -> Vec { use std::io::BufRead; diff --git a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs index abafd330573e..906ea32b9c42 100644 --- a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs +++ b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs @@ -8,8 +8,6 @@ // meant to compile and run successfully once rust-lang/rust#54987 is // implemented. -#![feature(nll)] - struct D { x: u32, s: S, diff --git a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr index 862432a5bc6a..153d9bdf3215 100644 --- a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr +++ b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr @@ -1,17 +1,17 @@ error[E0381]: assign of possibly uninitialized variable: `d` - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:30:5 + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:28:5 | LL | d.x = 10; | ^^^^^^^^ use of possibly uninitialized `d` error[E0381]: assign of possibly uninitialized variable: `d` - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:36:5 + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:34:5 | LL | d.x = 10; | ^^^^^^^^ use of possibly uninitialized `d` error[E0382]: assign of moved value: `d` - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:43:5 + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:41:5 | LL | let mut d = D { x: 0, s: S{ y: 0, z: 0 } }; | ----- move occurs because `d` has type `D`, which does not implement the `Copy` trait @@ -21,19 +21,19 @@ LL | d.x = 10; | ^^^^^^^^ value assigned here after move error[E0381]: assign to part of possibly uninitialized variable: `d` - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:49:5 + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:47:5 | LL | d.s.y = 20; | ^^^^^^^^^^ use of possibly uninitialized `d.s` error[E0381]: assign to part of possibly uninitialized variable: `d` - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:55:5 + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:53:5 | LL | d.s.y = 20; | ^^^^^^^^^^ use of possibly uninitialized `d.s` error[E0382]: assign to part of moved value: `d` - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:62:5 + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:60:5 | LL | let mut d = D { x: 0, s: S{ y: 0, z: 0} }; | ----- move occurs because `d` has type `D`, which does not implement the `Copy` trait diff --git a/src/test/ui/nll/issue-22323-temp-destruction.rs b/src/test/ui/nll/issue-22323-temp-destruction.rs index 2c547fb7c7da..6357c3ccef1f 100644 --- a/src/test/ui/nll/issue-22323-temp-destruction.rs +++ b/src/test/ui/nll/issue-22323-temp-destruction.rs @@ -3,8 +3,6 @@ // compile-pass -#![feature(nll)] - fn main() { let _s = construct().borrow().consume_borrowed(); } diff --git a/src/test/ui/nll/issue-30104.rs b/src/test/ui/nll/issue-30104.rs index 88e49bf8df70..27e519005f62 100644 --- a/src/test/ui/nll/issue-30104.rs +++ b/src/test/ui/nll/issue-30104.rs @@ -2,8 +2,6 @@ // compile-pass -#![feature(nll)] - use std::ops::{Deref, DerefMut}; fn box_two_field(v: &mut Box<(i32, i32)>) { diff --git a/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs b/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs index a114d7092ecf..7e0ffd6cf364 100644 --- a/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs +++ b/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs @@ -1,4 +1,3 @@ -#![feature(nll)] // compile-pass // rust-lang/rust#32382: Borrow checker used to complain about diff --git a/src/test/ui/nll/issue-43058.rs b/src/test/ui/nll/issue-43058.rs index c5bae7a12d7e..c50473511f11 100644 --- a/src/test/ui/nll/issue-43058.rs +++ b/src/test/ui/nll/issue-43058.rs @@ -1,7 +1,5 @@ // compile-pass -#![feature(nll)] - use std::borrow::Cow; #[derive(Clone, Debug)] diff --git a/src/test/ui/nll/issue-46589.rs b/src/test/ui/nll/issue-46589.rs index 690f6f269ebc..8c0c356e9672 100644 --- a/src/test/ui/nll/issue-46589.rs +++ b/src/test/ui/nll/issue-46589.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - struct Foo; impl Foo { diff --git a/src/test/ui/nll/issue-46589.stderr b/src/test/ui/nll/issue-46589.stderr index 7b02b905303f..397909a43661 100644 --- a/src/test/ui/nll/issue-46589.stderr +++ b/src/test/ui/nll/issue-46589.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `**other` as mutable more than once at a time - --> $DIR/issue-46589.rs:19:21 + --> $DIR/issue-46589.rs:17:21 | LL | *other = match (*other).get_self() { | -------- first mutable borrow occurs here diff --git a/src/test/ui/nll/issue-47022.rs b/src/test/ui/nll/issue-47022.rs index 1add2c334dae..3f8e0f5ad3d7 100644 --- a/src/test/ui/nll/issue-47022.rs +++ b/src/test/ui/nll/issue-47022.rs @@ -1,8 +1,5 @@ // compile-pass -#![allow(warnings)] -#![feature(nll)] - struct LoadedObject { bodies: Vec, color: Color, diff --git a/src/test/ui/nll/issue-47388.rs b/src/test/ui/nll/issue-47388.rs index df47baa3c17f..207af380e62d 100644 --- a/src/test/ui/nll/issue-47388.rs +++ b/src/test/ui/nll/issue-47388.rs @@ -1,4 +1,3 @@ -#![feature(nll)] struct FancyNum { num: u8, } diff --git a/src/test/ui/nll/issue-47388.stderr b/src/test/ui/nll/issue-47388.stderr index a5f5bf6ee2fd..d4064b3f50a3 100644 --- a/src/test/ui/nll/issue-47388.stderr +++ b/src/test/ui/nll/issue-47388.stderr @@ -1,5 +1,5 @@ error[E0594]: cannot assign to `fancy_ref.num` which is behind a `&` reference - --> $DIR/issue-47388.rs:9:5 + --> $DIR/issue-47388.rs:8:5 | LL | let fancy_ref = &(&mut fancy); | ------------- help: consider changing this to be a mutable reference: `&mut (&mut fancy)` diff --git a/src/test/ui/nll/issue-47470.rs b/src/test/ui/nll/issue-47470.rs index 67150b46c359..72ee7f88650e 100644 --- a/src/test/ui/nll/issue-47470.rs +++ b/src/test/ui/nll/issue-47470.rs @@ -2,8 +2,6 @@ // causing region relations not to be enforced at all the places where // they have to be enforced. -#![feature(nll)] - struct Foo<'a>(&'a ()); trait Bar { type Assoc; diff --git a/src/test/ui/nll/issue-47470.stderr b/src/test/ui/nll/issue-47470.stderr index d23cee3fc7c4..0b1247d60ec6 100644 --- a/src/test/ui/nll/issue-47470.stderr +++ b/src/test/ui/nll/issue-47470.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return reference to local variable `local` - --> $DIR/issue-47470.rs:17:9 + --> $DIR/issue-47470.rs:15:9 | LL | &local | ^^^^^^ returns a reference to data owned by the current function diff --git a/src/test/ui/nll/issue-48070.rs b/src/test/ui/nll/issue-48070.rs index c69bd3dbe90a..47426cdfa57e 100644 --- a/src/test/ui/nll/issue-48070.rs +++ b/src/test/ui/nll/issue-48070.rs @@ -1,8 +1,6 @@ // run-pass // revisions: lxl nll -#![cfg_attr(nll, feature(nll))] - struct Foo { x: u32 } diff --git a/src/test/ui/nll/issue-48697.rs b/src/test/ui/nll/issue-48697.rs index ececd6fccd84..16e29ab2a8ad 100644 --- a/src/test/ui/nll/issue-48697.rs +++ b/src/test/ui/nll/issue-48697.rs @@ -1,7 +1,5 @@ // Regression test for #48697 -#![feature(nll)] - fn foo(x: &i32) -> &i32 { let z = 4; let f = &|y| y; diff --git a/src/test/ui/nll/issue-48697.stderr b/src/test/ui/nll/issue-48697.stderr index 73832fd57879..f0c29b72b429 100644 --- a/src/test/ui/nll/issue-48697.stderr +++ b/src/test/ui/nll/issue-48697.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return value referencing local variable `z` - --> $DIR/issue-48697.rs:9:5 + --> $DIR/issue-48697.rs:7:5 | LL | let k = f(&z); | -- `z` is borrowed here diff --git a/src/test/ui/nll/issue-50716-1.rs b/src/test/ui/nll/issue-50716-1.rs index d963a620c9ac..ec992959a66c 100644 --- a/src/test/ui/nll/issue-50716-1.rs +++ b/src/test/ui/nll/issue-50716-1.rs @@ -3,12 +3,8 @@ // bounds derived from `Sized` requirements” that checks that the fixed compiler // accepts this code fragment with both AST and MIR borrow checkers. // -// revisions: migrate nll -// // compile-pass -#![cfg_attr(nll, feature(nll))] - struct Qey(Q); fn main() {} diff --git a/src/test/ui/nll/issue-50716.nll.stderr b/src/test/ui/nll/issue-50716.nll.stderr new file mode 100644 index 000000000000..38dd1b5f6fe7 --- /dev/null +++ b/src/test/ui/nll/issue-50716.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/issue-50716.rs:14:14 + | +LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) + | -- lifetime `'a` defined here +... +LL | let _x = *s; + | ^^ proving this value is `Sized` requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/nll/issue-50716.rs b/src/test/ui/nll/issue-50716.rs index ce4bee366567..c2fc345fa2ba 100644 --- a/src/test/ui/nll/issue-50716.rs +++ b/src/test/ui/nll/issue-50716.rs @@ -2,8 +2,6 @@ // Regression test for the issue #50716: NLL ignores lifetimes bounds // derived from `Sized` requirements -#![feature(nll)] - trait A { type X: ?Sized; } diff --git a/src/test/ui/nll/issue-50716.stderr b/src/test/ui/nll/issue-50716.stderr index 7e5ffb515011..b19e3a9dfb34 100644 --- a/src/test/ui/nll/issue-50716.stderr +++ b/src/test/ui/nll/issue-50716.stderr @@ -1,11 +1,18 @@ -error: lifetime may not live long enough - --> $DIR/issue-50716.rs:16:14 +error[E0308]: mismatched types + --> $DIR/issue-50716.rs:14:9 + | +LL | let _x = *s; + | ^^ lifetime mismatch + | + = note: expected type `std::marker::Sized` + found type `std::marker::Sized` +note: the lifetime 'a as defined on the function body at 9:8... + --> $DIR/issue-50716.rs:9:8 | LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) - | -- lifetime `'a` defined here -... -LL | let _x = *s; - | ^^ proving this value is `Sized` requires that `'a` must outlive `'static` + | ^^ + = note: ...does not necessarily outlive the static lifetime error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/nll/issue-51191.rs b/src/test/ui/nll/issue-51191.rs index 6704b6486991..747bfe3a8a57 100644 --- a/src/test/ui/nll/issue-51191.rs +++ b/src/test/ui/nll/issue-51191.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - struct Struct; impl Struct { diff --git a/src/test/ui/nll/issue-51191.stderr b/src/test/ui/nll/issue-51191.stderr index e80cd873d5ac..e226de15dc2f 100644 --- a/src/test/ui/nll/issue-51191.stderr +++ b/src/test/ui/nll/issue-51191.stderr @@ -1,5 +1,5 @@ warning: function cannot return without recursing - --> $DIR/issue-51191.rs:6:5 + --> $DIR/issue-51191.rs:4:5 | LL | fn bar(self: &mut Self) { | ^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing @@ -11,7 +11,7 @@ LL | (&mut self).bar(); = help: a `loop` may express intention better if this is on purpose error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable - --> $DIR/issue-51191.rs:8:9 + --> $DIR/issue-51191.rs:6:9 | LL | (&mut self).bar(); | ^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | (&mut self).bar(); | try removing `&mut` here error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable - --> $DIR/issue-51191.rs:13:9 + --> $DIR/issue-51191.rs:11:9 | LL | fn imm(self) { | ---- help: consider changing this to be mutable: `mut self` @@ -28,19 +28,19 @@ LL | (&mut self).bar(); | ^^^^^^^^^^^ cannot borrow as mutable error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable - --> $DIR/issue-51191.rs:22:9 + --> $DIR/issue-51191.rs:20:9 | LL | (&mut self).bar(); | ^^^^^^^^^^^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/issue-51191.rs:22:9 + --> $DIR/issue-51191.rs:20:9 | LL | (&mut self).bar(); | ^^^^^^^^^^^ cannot borrow as mutable error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable - --> $DIR/issue-51191.rs:28:9 + --> $DIR/issue-51191.rs:26:9 | LL | (&mut self).bar(); | ^^^^^^^^^^^ diff --git a/src/test/ui/nll/issue-51244.rs b/src/test/ui/nll/issue-51244.rs index aaf98ddfa277..743415d58afa 100644 --- a/src/test/ui/nll/issue-51244.rs +++ b/src/test/ui/nll/issue-51244.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - fn main() { let ref my_ref @ _ = 0; *my_ref = 0; diff --git a/src/test/ui/nll/issue-51244.stderr b/src/test/ui/nll/issue-51244.stderr index 6b543389af50..8a7e71e0326a 100644 --- a/src/test/ui/nll/issue-51244.stderr +++ b/src/test/ui/nll/issue-51244.stderr @@ -1,5 +1,5 @@ error[E0594]: cannot assign to `*my_ref` which is behind a `&` reference - --> $DIR/issue-51244.rs:5:5 + --> $DIR/issue-51244.rs:3:5 | LL | let ref my_ref @ _ = 0; | -------------- help: consider changing this to be a mutable reference: `ref mut my_ref @ _` diff --git a/src/test/ui/nll/issue-51268.rs b/src/test/ui/nll/issue-51268.rs index c14146a3de2a..12d0449abb19 100644 --- a/src/test/ui/nll/issue-51268.rs +++ b/src/test/ui/nll/issue-51268.rs @@ -1,7 +1,5 @@ // ignore-tidy-linelength -#![feature(nll)] - struct Bar; impl Bar { diff --git a/src/test/ui/nll/issue-51268.stderr b/src/test/ui/nll/issue-51268.stderr index 0be181745fde..420c94f8e1bd 100644 --- a/src/test/ui/nll/issue-51268.stderr +++ b/src/test/ui/nll/issue-51268.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `self.thing` as mutable because it is also borrowed as immutable - --> $DIR/issue-51268.rs:18:9 + --> $DIR/issue-51268.rs:16:9 | LL | self.thing.bar(|| { | ^ --- -- immutable borrow occurs here diff --git a/src/test/ui/nll/issue-51351.rs b/src/test/ui/nll/issue-51351.rs index 939993f154f8..b45477c7fb10 100644 --- a/src/test/ui/nll/issue-51351.rs +++ b/src/test/ui/nll/issue-51351.rs @@ -8,8 +8,6 @@ // // compile-pass -#![feature(nll)] - fn creash<'a>() { let x: &'a () = &(); } diff --git a/src/test/ui/nll/issue-51512.rs b/src/test/ui/nll/issue-51512.rs index 7e2e6e0a16cc..691760eb91e5 100644 --- a/src/test/ui/nll/issue-51512.rs +++ b/src/test/ui/nll/issue-51512.rs @@ -1,6 +1,3 @@ -#![allow(warnings)] -#![feature(nll)] - fn main() { let range = 0..1; let r = range; diff --git a/src/test/ui/nll/issue-51512.stderr b/src/test/ui/nll/issue-51512.stderr index a84a236ca777..e591ca08290e 100644 --- a/src/test/ui/nll/issue-51512.stderr +++ b/src/test/ui/nll/issue-51512.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `range` - --> $DIR/issue-51512.rs:7:13 + --> $DIR/issue-51512.rs:4:13 | LL | let range = 0..1; | ----- move occurs because `range` has type `std::ops::Range`, which does not implement the `Copy` trait diff --git a/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.rs b/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.rs index eaa809d2b370..58416c31edde 100644 --- a/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.rs +++ b/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.rs @@ -4,7 +4,6 @@ // of the fact that the type implements Drop. #![feature(nll)] -#![allow(dead_code)] pub struct S<'a> { url: &'a mut String } diff --git a/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.stderr b/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.stderr index e8741036e1d9..34259d06d383 100644 --- a/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.stderr +++ b/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.stderr @@ -1,5 +1,5 @@ error[E0713]: borrow may still be in use when destructor runs - --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:14:5 + --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:13:5 | LL | fn finish_1(s: S) -> &mut String { | - has type `S<'1>` @@ -9,7 +9,7 @@ LL | } | - here, drop of `s` needs exclusive access to `*s.url`, because the type `S<'_>` implements the `Drop` trait error[E0713]: borrow may still be in use when destructor runs - --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:19:13 + --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:18:13 | LL | fn finish_2(s: S) -> &mut String { | - has type `S<'1>` @@ -19,7 +19,7 @@ LL | } | - here, drop of `s` needs exclusive access to `*s.url`, because the type `S<'_>` implements the `Drop` trait error[E0713]: borrow may still be in use when destructor runs - --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:24:21 + --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:23:21 | LL | fn finish_3(s: S) -> &mut String { | - has type `S<'1>` @@ -29,7 +29,7 @@ LL | } | - here, drop of `s` needs exclusive access to `*s.url`, because the type `S<'_>` implements the `Drop` trait error[E0509]: cannot move out of type `S<'_>`, which implements the `Drop` trait - --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:29:13 + --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:28:13 | LL | let p = s.url; p | ^^^^^ diff --git a/src/test/ui/nll/issue-52078.rs b/src/test/ui/nll/issue-52078.rs index ebe442adbd94..4b8e6c680753 100644 --- a/src/test/ui/nll/issue-52078.rs +++ b/src/test/ui/nll/issue-52078.rs @@ -1,6 +1,3 @@ -#![feature(nll)] -#![allow(unused_variables)] - // Regression test for #52078: we were failing to infer a relationship // between `'a` and `'b` below due to inference variables introduced // during the normalization process. diff --git a/src/test/ui/nll/issue-52086.rs b/src/test/ui/nll/issue-52086.rs index 78765283ec29..0414428e4815 100644 --- a/src/test/ui/nll/issue-52086.rs +++ b/src/test/ui/nll/issue-52086.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - use std::rc::Rc; use std::sync::Arc; diff --git a/src/test/ui/nll/issue-52086.stderr b/src/test/ui/nll/issue-52086.stderr index ed4171ff1426..da453fb1f921 100644 --- a/src/test/ui/nll/issue-52086.stderr +++ b/src/test/ui/nll/issue-52086.stderr @@ -1,11 +1,11 @@ error[E0507]: cannot move out of an `Rc` - --> $DIR/issue-52086.rs:10:10 + --> $DIR/issue-52086.rs:8:10 | LL | drop(x.field); | ^^^^^^^ cannot move out of an `Rc` error[E0507]: cannot move out of an `Arc` - --> $DIR/issue-52086.rs:14:10 + --> $DIR/issue-52086.rs:12:10 | LL | drop(y.field); | ^^^^^^^ cannot move out of an `Arc` diff --git a/src/test/ui/nll/issue-52113.rs b/src/test/ui/nll/issue-52113.rs index 795f4f426fff..0d7ee0376924 100644 --- a/src/test/ui/nll/issue-52113.rs +++ b/src/test/ui/nll/issue-52113.rs @@ -1,6 +1,3 @@ -// - -#![allow(warnings)] #![feature(nll)] trait Bazinga {} diff --git a/src/test/ui/nll/issue-52113.stderr b/src/test/ui/nll/issue-52113.stderr index 8638fe257698..590963ded78b 100644 --- a/src/test/ui/nll/issue-52113.stderr +++ b/src/test/ui/nll/issue-52113.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/issue-52113.rs:37:5 + --> $DIR/issue-52113.rs:34:5 | LL | fn produce_err<'a, 'b: 'a>(data: &'b mut Vec<&'b u32>, value: &'a u32) -> impl Bazinga + 'b { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/nll/issue-52534-1.rs b/src/test/ui/nll/issue-52534-1.rs index 7ab3593c89f7..d9ea3ae42c49 100644 --- a/src/test/ui/nll/issue-52534-1.rs +++ b/src/test/ui/nll/issue-52534-1.rs @@ -1,6 +1,3 @@ -#![feature(nll)] -#![allow(warnings)] - struct Test; impl Test { diff --git a/src/test/ui/nll/issue-52534-1.stderr b/src/test/ui/nll/issue-52534-1.stderr index 7d82f5e710fb..743179f05c1a 100644 --- a/src/test/ui/nll/issue-52534-1.stderr +++ b/src/test/ui/nll/issue-52534-1.stderr @@ -1,17 +1,17 @@ error[E0515]: cannot return reference to local variable `x` - --> $DIR/issue-52534-1.rs:9:9 + --> $DIR/issue-52534-1.rs:6:9 | LL | &x | ^^ returns a reference to data owned by the current function error[E0515]: cannot return reference to local variable `x` - --> $DIR/issue-52534-1.rs:16:5 + --> $DIR/issue-52534-1.rs:13:5 | LL | &x | ^^ returns a reference to data owned by the current function error[E0515]: cannot return value referencing local variable `x` - --> $DIR/issue-52534-1.rs:22:5 + --> $DIR/issue-52534-1.rs:19:5 | LL | &&x | ^-- @@ -20,7 +20,7 @@ LL | &&x | returns a value referencing data owned by the current function error[E0515]: cannot return reference to temporary value - --> $DIR/issue-52534-1.rs:22:5 + --> $DIR/issue-52534-1.rs:19:5 | LL | &&x | ^-- @@ -29,25 +29,25 @@ LL | &&x | returns a reference to data owned by the current function error[E0515]: cannot return reference to local variable `x` - --> $DIR/issue-52534-1.rs:29:5 + --> $DIR/issue-52534-1.rs:26:5 | LL | &x | ^^ returns a reference to data owned by the current function error[E0515]: cannot return reference to local variable `x` - --> $DIR/issue-52534-1.rs:35:5 + --> $DIR/issue-52534-1.rs:32:5 | LL | &x | ^^ returns a reference to data owned by the current function error[E0515]: cannot return reference to local variable `x` - --> $DIR/issue-52534-1.rs:41:5 + --> $DIR/issue-52534-1.rs:38:5 | LL | &x | ^^ returns a reference to data owned by the current function error[E0515]: cannot return reference to local variable `x` - --> $DIR/issue-52534-1.rs:47:5 + --> $DIR/issue-52534-1.rs:44:5 | LL | &x | ^^ returns a reference to data owned by the current function diff --git a/src/test/ui/nll/issue-52534-2.rs b/src/test/ui/nll/issue-52534-2.rs index 6e84869dd6d3..e416264ed09f 100644 --- a/src/test/ui/nll/issue-52534-2.rs +++ b/src/test/ui/nll/issue-52534-2.rs @@ -1,6 +1,3 @@ -#![feature(nll)] -#![allow(warnings)] - fn foo(x: &u32) -> &u32 { let y; diff --git a/src/test/ui/nll/issue-52534-2.stderr b/src/test/ui/nll/issue-52534-2.stderr index f98deaea7183..dd8a87f7e29a 100644 --- a/src/test/ui/nll/issue-52534-2.stderr +++ b/src/test/ui/nll/issue-52534-2.stderr @@ -1,5 +1,5 @@ error[E0597]: `x` does not live long enough - --> $DIR/issue-52534-2.rs:9:9 + --> $DIR/issue-52534-2.rs:6:9 | LL | y = &x | ^^^^^^ borrowed value does not live long enough diff --git a/src/test/ui/nll/issue-52534.rs b/src/test/ui/nll/issue-52534.rs index 1394560df19b..559d4c8591b3 100644 --- a/src/test/ui/nll/issue-52534.rs +++ b/src/test/ui/nll/issue-52534.rs @@ -1,6 +1,3 @@ -#![feature(nll)] -#![allow(warnings)] - fn foo(_: impl FnOnce(&u32) -> &u32) { } diff --git a/src/test/ui/nll/issue-52534.stderr b/src/test/ui/nll/issue-52534.stderr index 9ac79eda1614..b2b727fd4389 100644 --- a/src/test/ui/nll/issue-52534.stderr +++ b/src/test/ui/nll/issue-52534.stderr @@ -1,5 +1,5 @@ error[E0597]: `x` does not live long enough - --> $DIR/issue-52534.rs:12:14 + --> $DIR/issue-52534.rs:9:14 | LL | foo(|a| &x) | - ^ `x` would have to be valid for `'0`... @@ -13,7 +13,7 @@ LL | } = note: to learn more, visit error[E0597]: `y` does not live long enough - --> $DIR/issue-52534.rs:18:26 + --> $DIR/issue-52534.rs:15:26 | LL | baz(|first, second| &y) | ----- ^ `y` would have to be valid for `'0`... diff --git a/src/test/ui/nll/issue-52663-span-decl-captured-variable.rs b/src/test/ui/nll/issue-52663-span-decl-captured-variable.rs index 3e57d26745a9..24a4267f653f 100644 --- a/src/test/ui/nll/issue-52663-span-decl-captured-variable.rs +++ b/src/test/ui/nll/issue-52663-span-decl-captured-variable.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - fn expect_fn(f: F) where F : Fn() { f(); } diff --git a/src/test/ui/nll/issue-52663-span-decl-captured-variable.stderr b/src/test/ui/nll/issue-52663-span-decl-captured-variable.stderr index 0162c6bcbd1e..8958bdf4c2a8 100644 --- a/src/test/ui/nll/issue-52663-span-decl-captured-variable.stderr +++ b/src/test/ui/nll/issue-52663-span-decl-captured-variable.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of captured variable in an `Fn` closure - --> $DIR/issue-52663-span-decl-captured-variable.rs:10:26 + --> $DIR/issue-52663-span-decl-captured-variable.rs:8:26 | LL | let x = (vec![22], vec![44]); | - captured outer variable diff --git a/src/test/ui/nll/issue-52663-trait-object.rs b/src/test/ui/nll/issue-52663-trait-object.rs index 121c3ef4e610..e8e571aadc36 100644 --- a/src/test/ui/nll/issue-52663-trait-object.rs +++ b/src/test/ui/nll/issue-52663-trait-object.rs @@ -1,5 +1,4 @@ #![feature(box_syntax)] -#![feature(nll)] trait Foo { fn get(&self); } diff --git a/src/test/ui/nll/issue-52663-trait-object.stderr b/src/test/ui/nll/issue-52663-trait-object.stderr index b9437d88ff67..9262117f3975 100644 --- a/src/test/ui/nll/issue-52663-trait-object.stderr +++ b/src/test/ui/nll/issue-52663-trait-object.stderr @@ -1,5 +1,5 @@ error[E0597]: `tmp0` does not live long enough - --> $DIR/issue-52663-trait-object.rs:13:20 + --> $DIR/issue-52663-trait-object.rs:12:20 | LL | let tmp1 = &tmp0; | ^^^^^ borrowed value does not live long enough diff --git a/src/test/ui/nll/issue-52669.rs b/src/test/ui/nll/issue-52669.rs index 6027e9881412..e33528ac59e6 100644 --- a/src/test/ui/nll/issue-52669.rs +++ b/src/test/ui/nll/issue-52669.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - struct A { b: B, } diff --git a/src/test/ui/nll/issue-52669.stderr b/src/test/ui/nll/issue-52669.stderr index f51768c3859e..db53e444b9e4 100644 --- a/src/test/ui/nll/issue-52669.stderr +++ b/src/test/ui/nll/issue-52669.stderr @@ -1,5 +1,5 @@ error[E0382]: borrow of moved value: `a.b` - --> $DIR/issue-52669.rs:15:5 + --> $DIR/issue-52669.rs:13:5 | LL | fn bar(mut a: A) -> B { | ----- move occurs because `a` has type `A`, which does not implement the `Copy` trait diff --git a/src/test/ui/nll/issue-52742.nll.stderr b/src/test/ui/nll/issue-52742.nll.stderr new file mode 100644 index 000000000000..e8b7b3333eb6 --- /dev/null +++ b/src/test/ui/nll/issue-52742.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/issue-52742.rs:14:9 + | +LL | fn take_bar(&mut self, b: Bar<'_>) { + | --------- -- let's call this `'1` + | | + | has type `&mut Foo<'_, '2>` +LL | self.y = b.z + | ^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` + +error: aborting due to previous error + diff --git a/src/test/ui/nll/issue-52742.rs b/src/test/ui/nll/issue-52742.rs index 150e67fe0948..db9ddfff285b 100644 --- a/src/test/ui/nll/issue-52742.rs +++ b/src/test/ui/nll/issue-52742.rs @@ -1,4 +1,3 @@ -#![feature(nll)] #![feature(in_band_lifetimes)] struct Foo<'a, 'b> { @@ -13,7 +12,7 @@ struct Bar<'b> { impl Foo<'_, '_> { fn take_bar(&mut self, b: Bar<'_>) { self.y = b.z - //~^ ERROR lifetime may not live long enough + //~^ ERROR } } diff --git a/src/test/ui/nll/issue-52742.stderr b/src/test/ui/nll/issue-52742.stderr index 6b25296c4bda..b98291580029 100644 --- a/src/test/ui/nll/issue-52742.stderr +++ b/src/test/ui/nll/issue-52742.stderr @@ -1,12 +1,22 @@ -error: lifetime may not live long enough - --> $DIR/issue-52742.rs:15:9 +error[E0312]: lifetime of reference outlives lifetime of borrowed content... + --> $DIR/issue-52742.rs:14:18 | -LL | fn take_bar(&mut self, b: Bar<'_>) { - | --------- -- let's call this `'1` - | | - | has type `&mut Foo<'_, '2>` LL | self.y = b.z - | ^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` + | ^^^ + | +note: ...the reference is valid for the lifetime '_ as defined on the impl at 12:10... + --> $DIR/issue-52742.rs:12:10 + | +LL | impl Foo<'_, '_> { + | ^^ +note: ...but the borrowed content is only valid for the anonymous lifetime #2 defined on the method body at 13:5 + --> $DIR/issue-52742.rs:13:5 + | +LL | / fn take_bar(&mut self, b: Bar<'_>) { +LL | | self.y = b.z +LL | | +LL | | } + | |_____^ error: aborting due to previous error diff --git a/src/test/ui/nll/issue-53119.rs b/src/test/ui/nll/issue-53119.rs index 97e05c8810d0..7a47a77f6bb4 100644 --- a/src/test/ui/nll/issue-53119.rs +++ b/src/test/ui/nll/issue-53119.rs @@ -1,7 +1,5 @@ // compile-pass -#![feature(nll)] - use std::ops::Deref; pub struct TypeFieldIterator<'a, T: 'a> { diff --git a/src/test/ui/nll/issue-53570.rs b/src/test/ui/nll/issue-53570.rs index d0baffa2702c..cea458dcb65b 100644 --- a/src/test/ui/nll/issue-53570.rs +++ b/src/test/ui/nll/issue-53570.rs @@ -8,10 +8,6 @@ // // compile-pass -#![feature(nll)] -#![feature(rustc_attrs)] -#![allow(dead_code)] - use std::cell::{RefCell, Ref}; trait AnyVec<'a> { diff --git a/src/test/ui/nll/issue-55288.rs b/src/test/ui/nll/issue-55288.rs index 9b3eb7f05ded..c7b6ac592483 100644 --- a/src/test/ui/nll/issue-55288.rs +++ b/src/test/ui/nll/issue-55288.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - // run-pass struct Slice(&'static [&'static [u8]]); diff --git a/src/test/ui/nll/issue-55344.rs b/src/test/ui/nll/issue-55344.rs index b900acfa1599..521d4d33d863 100644 --- a/src/test/ui/nll/issue-55344.rs +++ b/src/test/ui/nll/issue-55344.rs @@ -1,7 +1,5 @@ // compile-pass -#![feature(nll)] -#![allow(unreachable_code)] #![deny(unused_mut)] pub fn foo() { diff --git a/src/test/ui/nll/issue-55394.nll.stderr b/src/test/ui/nll/issue-55394.nll.stderr new file mode 100644 index 000000000000..d0723047ac08 --- /dev/null +++ b/src/test/ui/nll/issue-55394.nll.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/issue-55394.rs:9:9 + | +LL | fn new(bar: &mut Bar) -> Self { + | - ---- return type is Foo<'2> + | | + | let's call the lifetime of this reference `'1` +LL | Foo { bar } + | ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` + +error: aborting due to previous error + diff --git a/src/test/ui/nll/issue-55394.rs b/src/test/ui/nll/issue-55394.rs index deb1034525ed..f813d1c915cf 100644 --- a/src/test/ui/nll/issue-55394.rs +++ b/src/test/ui/nll/issue-55394.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - struct Bar; struct Foo<'s> { @@ -8,7 +6,7 @@ struct Foo<'s> { impl Foo<'_> { fn new(bar: &mut Bar) -> Self { - Foo { bar } //~ERROR lifetime may not live long enough + Foo { bar } //~ERROR } } diff --git a/src/test/ui/nll/issue-55394.stderr b/src/test/ui/nll/issue-55394.stderr index e9a70fd6b161..ffb94ed7dd7c 100644 --- a/src/test/ui/nll/issue-55394.stderr +++ b/src/test/ui/nll/issue-55394.stderr @@ -1,12 +1,29 @@ -error: lifetime may not live long enough - --> $DIR/issue-55394.rs:11:9 +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'s` due to conflicting requirements + --> $DIR/issue-55394.rs:9:9 | -LL | fn new(bar: &mut Bar) -> Self { - | - ---- return type is Foo<'2> - | | - | let's call the lifetime of this reference `'1` LL | Foo { bar } - | ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` + | ^^^ + | +note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 8:5... + --> $DIR/issue-55394.rs:8:5 + | +LL | / fn new(bar: &mut Bar) -> Self { +LL | | Foo { bar } +LL | | } + | |_____^ +note: ...so that reference does not outlive borrowed content + --> $DIR/issue-55394.rs:9:15 + | +LL | Foo { bar } + | ^^^ +note: but, the lifetime must be valid for the lifetime '_ as defined on the impl at 7:10... + --> $DIR/issue-55394.rs:7:10 + | +LL | impl Foo<'_> { + | ^^ + = note: ...so that the expression is assignable: + expected Foo<'_> + found Foo<'_> error: aborting due to previous error diff --git a/src/test/ui/nll/issue-55401.nll.stderr b/src/test/ui/nll/issue-55401.nll.stderr new file mode 100644 index 000000000000..4f797f26a1a7 --- /dev/null +++ b/src/test/ui/nll/issue-55401.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/issue-55401.rs:3:5 + | +LL | fn static_to_a_to_static_through_ref_in_tuple<'a>(x: &'a u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | let (ref y, _z): (&'a u32, u32) = (&22, 44); +LL | *y + | ^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/nll/issue-55401.rs b/src/test/ui/nll/issue-55401.rs index 2fa234491087..fc45824e903c 100644 --- a/src/test/ui/nll/issue-55401.rs +++ b/src/test/ui/nll/issue-55401.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - fn static_to_a_to_static_through_ref_in_tuple<'a>(x: &'a u32) -> &'static u32 { let (ref y, _z): (&'a u32, u32) = (&22, 44); *y //~ ERROR diff --git a/src/test/ui/nll/issue-55401.stderr b/src/test/ui/nll/issue-55401.stderr index 622bc5a3f341..50debc6386f6 100644 --- a/src/test/ui/nll/issue-55401.stderr +++ b/src/test/ui/nll/issue-55401.stderr @@ -1,11 +1,15 @@ -error: lifetime may not live long enough - --> $DIR/issue-55401.rs:5:5 +error[E0312]: lifetime of reference outlives lifetime of borrowed content... + --> $DIR/issue-55401.rs:3:5 + | +LL | *y + | ^^ + | + = note: ...the reference is valid for the static lifetime... +note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 1:47 + --> $DIR/issue-55401.rs:1:47 | LL | fn static_to_a_to_static_through_ref_in_tuple<'a>(x: &'a u32) -> &'static u32 { - | -- lifetime `'a` defined here -LL | let (ref y, _z): (&'a u32, u32) = (&22, 44); -LL | *y - | ^^ returning this value requires that `'a` must outlive `'static` + | ^^ error: aborting due to previous error diff --git a/src/test/ui/nll/issue-57265-return-type-wf-check.rs b/src/test/ui/nll/issue-57265-return-type-wf-check.rs index 24c61a4926f0..8fb8351cee26 100644 --- a/src/test/ui/nll/issue-57265-return-type-wf-check.rs +++ b/src/test/ui/nll/issue-57265-return-type-wf-check.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - use std::any::Any; #[derive(Debug, Clone)] diff --git a/src/test/ui/nll/issue-57265-return-type-wf-check.stderr b/src/test/ui/nll/issue-57265-return-type-wf-check.stderr index db01212597f5..20add62b91dd 100644 --- a/src/test/ui/nll/issue-57265-return-type-wf-check.stderr +++ b/src/test/ui/nll/issue-57265-return-type-wf-check.stderr @@ -1,5 +1,5 @@ error[E0716]: temporary value dropped while borrowed - --> $DIR/issue-57265-return-type-wf-check.rs:22:23 + --> $DIR/issue-57265-return-type-wf-check.rs:20:23 | LL | let (_, z) = foo(&"hello".to_string()); | -----^^^^^^^^^^^^^^^^^^^-- temporary value is freed at the end of this statement diff --git a/src/test/ui/nll/issue-57280-1.rs b/src/test/ui/nll/issue-57280-1.rs index 356c477f1ba3..e02d6a0cb5a3 100644 --- a/src/test/ui/nll/issue-57280-1.rs +++ b/src/test/ui/nll/issue-57280-1.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - // compile-pass trait Foo<'a> { diff --git a/src/test/ui/nll/issue-57280.rs b/src/test/ui/nll/issue-57280.rs index 4fe6a96f5dcc..776a0d359cda 100644 --- a/src/test/ui/nll/issue-57280.rs +++ b/src/test/ui/nll/issue-57280.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - // compile-pass trait Foo { diff --git a/src/test/ui/nll/issue-57989.rs b/src/test/ui/nll/issue-57989.rs index 4f21cca97cc0..c410f0b0bfb4 100644 --- a/src/test/ui/nll/issue-57989.rs +++ b/src/test/ui/nll/issue-57989.rs @@ -1,7 +1,5 @@ // Test for ICE from issue 57989 -#![feature(nll)] - fn f(x: &i32) { let g = &x; *x = 0; //~ ERROR cannot assign to `*x` which is behind a `&` reference diff --git a/src/test/ui/nll/issue-57989.stderr b/src/test/ui/nll/issue-57989.stderr index 7367dc095a31..00a9bab48685 100644 --- a/src/test/ui/nll/issue-57989.stderr +++ b/src/test/ui/nll/issue-57989.stderr @@ -1,5 +1,5 @@ error[E0594]: cannot assign to `*x` which is behind a `&` reference - --> $DIR/issue-57989.rs:7:5 + --> $DIR/issue-57989.rs:5:5 | LL | fn f(x: &i32) { | ---- help: consider changing this to be a mutable reference: `&mut i32` @@ -8,7 +8,7 @@ LL | *x = 0; | ^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written error[E0506]: cannot assign to `*x` because it is borrowed - --> $DIR/issue-57989.rs:7:5 + --> $DIR/issue-57989.rs:5:5 | LL | let g = &x; | -- borrow of `*x` occurs here diff --git a/src/test/ui/nll/issue-58053.rs b/src/test/ui/nll/issue-58053.rs index d4338905ed2d..0992e3a85ae9 100644 --- a/src/test/ui/nll/issue-58053.rs +++ b/src/test/ui/nll/issue-58053.rs @@ -1,4 +1,3 @@ -#![allow(warnings)] #![feature(nll)] fn main() { diff --git a/src/test/ui/nll/issue-58053.stderr b/src/test/ui/nll/issue-58053.stderr index 9048983318b3..297681ff4038 100644 --- a/src/test/ui/nll/issue-58053.stderr +++ b/src/test/ui/nll/issue-58053.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/issue-58053.rs:7:33 + --> $DIR/issue-58053.rs:6:33 | LL | let f = |x: &i32| -> &i32 { x }; | - ---- ^ returning this value requires that `'1` must outlive `'2` @@ -8,7 +8,7 @@ LL | let f = |x: &i32| -> &i32 { x }; | let's call the lifetime of this reference `'1` error: lifetime may not live long enough - --> $DIR/issue-58053.rs:11:25 + --> $DIR/issue-58053.rs:10:25 | LL | let g = |x: &i32| { x }; | - - ^ returning this value requires that `'1` must outlive `'2` diff --git a/src/test/ui/nll/issue-58299.rs b/src/test/ui/nll/issue-58299.rs index 9267cac5dd3d..3277a9db8ec4 100644 --- a/src/test/ui/nll/issue-58299.rs +++ b/src/test/ui/nll/issue-58299.rs @@ -1,4 +1,3 @@ -#![allow(dead_code)] #![feature(nll)] struct A<'a>(&'a ()); diff --git a/src/test/ui/nll/issue-58299.stderr b/src/test/ui/nll/issue-58299.stderr index 0c69b70a97c7..aba07542d026 100644 --- a/src/test/ui/nll/issue-58299.stderr +++ b/src/test/ui/nll/issue-58299.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/issue-58299.rs:17:9 + --> $DIR/issue-58299.rs:16:9 | LL | fn foo<'a>(x: i32) { | -- lifetime `'a` defined here @@ -8,7 +8,7 @@ LL | A::<'a>::X..=A::<'static>::X => (), | ^^^^^^^^^^ requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/issue-58299.rs:25:27 + --> $DIR/issue-58299.rs:24:27 | LL | fn bar<'a>(x: i32) { | -- lifetime `'a` defined here diff --git a/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs b/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs index 5b609820a237..1de32ddf531c 100644 --- a/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs +++ b/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs @@ -1,6 +1,3 @@ -#![allow(warnings)] -#![feature(nll)] - struct Wrap<'p> { p: &'p mut i32 } impl<'p> Drop for Wrap<'p> { diff --git a/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.stderr b/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.stderr index e7755bdb89cc..80e297807465 100644 --- a/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.stderr +++ b/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/maybe-initialized-drop-implicit-fragment-drop.rs:20:5 + --> $DIR/maybe-initialized-drop-implicit-fragment-drop.rs:17:5 | LL | let wrap = Wrap { p: &mut x }; | ------ borrow of `x` occurs here diff --git a/src/test/ui/nll/move-errors.rs b/src/test/ui/nll/move-errors.rs index a34163737096..e0fcd6250322 100644 --- a/src/test/ui/nll/move-errors.rs +++ b/src/test/ui/nll/move-errors.rs @@ -1,6 +1,3 @@ -#![allow(unused)] -#![feature(nll)] - struct A(String); struct C(D); diff --git a/src/test/ui/nll/move-errors.stderr b/src/test/ui/nll/move-errors.stderr index bb30da034af5..a4af11e3d40f 100644 --- a/src/test/ui/nll/move-errors.stderr +++ b/src/test/ui/nll/move-errors.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of borrowed content - --> $DIR/move-errors.rs:9:13 + --> $DIR/move-errors.rs:6:13 | LL | let b = *a; | ^^ @@ -8,7 +8,7 @@ LL | let b = *a; | help: consider removing the `*`: `a` error[E0508]: cannot move out of type `[A; 1]`, a non-copy array - --> $DIR/move-errors.rs:15:13 + --> $DIR/move-errors.rs:12:13 | LL | let b = a[0]; | ^^^^ @@ -17,7 +17,7 @@ LL | let b = a[0]; | help: consider borrowing here: `&a[0]` error[E0507]: cannot move out of borrowed content - --> $DIR/move-errors.rs:22:13 + --> $DIR/move-errors.rs:19:13 | LL | let s = **r; | ^^^ @@ -26,7 +26,7 @@ LL | let s = **r; | help: consider removing the `*`: `*r` error[E0507]: cannot move out of an `Rc` - --> $DIR/move-errors.rs:30:13 + --> $DIR/move-errors.rs:27:13 | LL | let s = *r; | ^^ @@ -35,7 +35,7 @@ LL | let s = *r; | help: consider removing the `*`: `r` error[E0508]: cannot move out of type `[A; 1]`, a non-copy array - --> $DIR/move-errors.rs:35:13 + --> $DIR/move-errors.rs:32:13 | LL | let a = [A("".to_string())][0]; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | let a = [A("".to_string())][0]; | help: consider borrowing here: `&[A("".to_string())][0]` error[E0507]: cannot move out of borrowed content - --> $DIR/move-errors.rs:41:16 + --> $DIR/move-errors.rs:38:16 | LL | let A(s) = *a; | - ^^ @@ -54,13 +54,13 @@ LL | let A(s) = *a; | data moved here | note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait - --> $DIR/move-errors.rs:41:11 + --> $DIR/move-errors.rs:38:11 | LL | let A(s) = *a; | ^ error[E0509]: cannot move out of type `D`, which implements the `Drop` trait - --> $DIR/move-errors.rs:47:19 + --> $DIR/move-errors.rs:44:19 | LL | let C(D(s)) = c; | - ^ cannot move out of here @@ -68,19 +68,19 @@ LL | let C(D(s)) = c; | data moved here | note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait - --> $DIR/move-errors.rs:47:13 + --> $DIR/move-errors.rs:44:13 | LL | let C(D(s)) = c; | ^ error[E0507]: cannot move out of borrowed content - --> $DIR/move-errors.rs:54:9 + --> $DIR/move-errors.rs:51:9 | LL | b = *a; | ^^ cannot move out of borrowed content error[E0508]: cannot move out of type `[B; 1]`, a non-copy array - --> $DIR/move-errors.rs:77:11 + --> $DIR/move-errors.rs:74:11 | LL | match x[0] { | ^^^^ @@ -94,7 +94,7 @@ LL | B::V(s) => (), | - ...and here | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/move-errors.rs:79:14 + --> $DIR/move-errors.rs:76:14 | LL | B::U(d) => (), | ^ @@ -102,7 +102,7 @@ LL | B::V(s) => (), | ^ error[E0509]: cannot move out of type `D`, which implements the `Drop` trait - --> $DIR/move-errors.rs:86:11 + --> $DIR/move-errors.rs:83:11 | LL | match x { | ^ cannot move out of here @@ -111,13 +111,13 @@ LL | B::U(D(s)) => (), | - data moved here | note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait - --> $DIR/move-errors.rs:89:16 + --> $DIR/move-errors.rs:86:16 | LL | B::U(D(s)) => (), | ^ error[E0509]: cannot move out of type `D`, which implements the `Drop` trait - --> $DIR/move-errors.rs:95:11 + --> $DIR/move-errors.rs:92:11 | LL | match x { | ^ cannot move out of here @@ -126,13 +126,13 @@ LL | (D(s), &t) => (), | - data moved here | note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait - --> $DIR/move-errors.rs:98:12 + --> $DIR/move-errors.rs:95:12 | LL | (D(s), &t) => (), | ^ error[E0507]: cannot move out of borrowed content - --> $DIR/move-errors.rs:95:11 + --> $DIR/move-errors.rs:92:11 | LL | match x { | ^ cannot move out of borrowed content @@ -141,13 +141,13 @@ LL | (D(s), &t) => (), | - data moved here | note: move occurs because `t` has type `std::string::String`, which does not implement the `Copy` trait - --> $DIR/move-errors.rs:98:17 + --> $DIR/move-errors.rs:95:17 | LL | (D(s), &t) => (), | ^ error[E0509]: cannot move out of type `F`, which implements the `Drop` trait - --> $DIR/move-errors.rs:105:11 + --> $DIR/move-errors.rs:102:11 | LL | match x { | ^ cannot move out of here @@ -158,13 +158,13 @@ LL | F(s, mut t) => (), | data moved here | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/move-errors.rs:107:11 + --> $DIR/move-errors.rs:104:11 | LL | F(s, mut t) => (), | ^ ^^^^^ error[E0507]: cannot move out of borrowed content - --> $DIR/move-errors.rs:113:11 + --> $DIR/move-errors.rs:110:11 | LL | match *x { | ^^ @@ -176,7 +176,7 @@ LL | Ok(s) | Err(s) => (), | - data moved here | note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait - --> $DIR/move-errors.rs:115:12 + --> $DIR/move-errors.rs:112:12 | LL | Ok(s) | Err(s) => (), | ^ diff --git a/src/test/ui/nll/move-subpaths-moves-root.rs b/src/test/ui/nll/move-subpaths-moves-root.rs index 72a36ef22dff..e7caf89e7839 100644 --- a/src/test/ui/nll/move-subpaths-moves-root.rs +++ b/src/test/ui/nll/move-subpaths-moves-root.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - fn main() { let x = (vec![1, 2, 3], ); drop(x.0); diff --git a/src/test/ui/nll/move-subpaths-moves-root.stderr b/src/test/ui/nll/move-subpaths-moves-root.stderr index bdbc25e9ee3d..7030d5b3305f 100644 --- a/src/test/ui/nll/move-subpaths-moves-root.stderr +++ b/src/test/ui/nll/move-subpaths-moves-root.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `x` - --> $DIR/move-subpaths-moves-root.rs:6:10 + --> $DIR/move-subpaths-moves-root.rs:4:10 | LL | drop(x.0); | --- value moved here diff --git a/src/test/ui/nll/normalization-bounds-error.rs b/src/test/ui/nll/normalization-bounds-error.rs index d6610e158236..b6cfcd98732b 100644 --- a/src/test/ui/nll/normalization-bounds-error.rs +++ b/src/test/ui/nll/normalization-bounds-error.rs @@ -1,7 +1,6 @@ // Check that we error when a bound from the impl is not satisfied when // normalizing an associated type. -#![feature(nll)] trait Visitor<'d> { type Value; } diff --git a/src/test/ui/nll/normalization-bounds-error.stderr b/src/test/ui/nll/normalization-bounds-error.stderr index 8ee00168661b..951e73e7fd76 100644 --- a/src/test/ui/nll/normalization-bounds-error.stderr +++ b/src/test/ui/nll/normalization-bounds-error.stderr @@ -1,16 +1,16 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` due to conflicting requirements - --> $DIR/normalization-bounds-error.rs:13:1 + --> $DIR/normalization-bounds-error.rs:12:1 | LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'd as defined on the function body at 13:14... - --> $DIR/normalization-bounds-error.rs:13:14 +note: first, the lifetime cannot outlive the lifetime 'd as defined on the function body at 12:14... + --> $DIR/normalization-bounds-error.rs:12:14 | LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} | ^^ -note: ...but the lifetime must also be valid for the lifetime 'a as defined on the function body at 13:18... - --> $DIR/normalization-bounds-error.rs:13:18 +note: ...but the lifetime must also be valid for the lifetime 'a as defined on the function body at 12:18... + --> $DIR/normalization-bounds-error.rs:12:18 | LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} | ^^ diff --git a/src/test/ui/nll/normalization-bounds.rs b/src/test/ui/nll/normalization-bounds.rs index ebc19d7cc835..5d2825ef2d67 100644 --- a/src/test/ui/nll/normalization-bounds.rs +++ b/src/test/ui/nll/normalization-bounds.rs @@ -2,7 +2,6 @@ //run-pass -#![feature(nll)] trait Visitor<'d> { type Value; } diff --git a/src/test/ui/nll/promotable-mutable-zst-doesnt-conflict.rs b/src/test/ui/nll/promotable-mutable-zst-doesnt-conflict.rs index 061d0d69d099..6d5bdfa4da2f 100644 --- a/src/test/ui/nll/promotable-mutable-zst-doesnt-conflict.rs +++ b/src/test/ui/nll/promotable-mutable-zst-doesnt-conflict.rs @@ -3,8 +3,6 @@ // run-pass -#![feature(nll)] - pub fn main() { let mut x: Vec<&[i32; 0]> = Vec::new(); for i in 0..10 { diff --git a/src/test/ui/nll/promoted-bounds.rs b/src/test/ui/nll/promoted-bounds.rs index 59b21cf9ac2a..5f95ae13c58a 100644 --- a/src/test/ui/nll/promoted-bounds.rs +++ b/src/test/ui/nll/promoted-bounds.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - fn shorten_lifetime<'a, 'b, 'min>(a: &'a i32, b: &'b i32) -> &'min i32 where 'a: 'min, diff --git a/src/test/ui/nll/promoted-bounds.stderr b/src/test/ui/nll/promoted-bounds.stderr index de185cc0d294..df347f4e7f0f 100644 --- a/src/test/ui/nll/promoted-bounds.stderr +++ b/src/test/ui/nll/promoted-bounds.stderr @@ -1,5 +1,5 @@ error[E0597]: `l` does not live long enough - --> $DIR/promoted-bounds.rs:21:17 + --> $DIR/promoted-bounds.rs:19:17 | LL | let ptr = { | --- borrow later stored here diff --git a/src/test/ui/nll/promoted-closure-pair.rs b/src/test/ui/nll/promoted-closure-pair.rs index 7b3bbad4c1e0..cc9f17fd4e6b 100644 --- a/src/test/ui/nll/promoted-closure-pair.rs +++ b/src/test/ui/nll/promoted-closure-pair.rs @@ -1,7 +1,5 @@ // Check that we handle multiple closures in the same promoted constant. -#![feature(nll)] - fn foo() -> &'static i32 { let z = 0; let p = &(|y| y, |y| y); diff --git a/src/test/ui/nll/promoted-closure-pair.stderr b/src/test/ui/nll/promoted-closure-pair.stderr index b04d1a9ccba7..000bdf85804d 100644 --- a/src/test/ui/nll/promoted-closure-pair.stderr +++ b/src/test/ui/nll/promoted-closure-pair.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return value referencing local variable `z` - --> $DIR/promoted-closure-pair.rs:9:5 + --> $DIR/promoted-closure-pair.rs:7:5 | LL | p.1(&z) | ^^^^--^ diff --git a/src/test/ui/nll/relate_tys/issue-48071.rs b/src/test/ui/nll/relate_tys/issue-48071.rs index 9b8ac167466f..72987629848c 100644 --- a/src/test/ui/nll/relate_tys/issue-48071.rs +++ b/src/test/ui/nll/relate_tys/issue-48071.rs @@ -6,10 +6,6 @@ // // compile-pass -#![allow(warnings)] -#![feature(dyn_trait)] -#![feature(nll)] - trait Foo { fn foo(&self) { } } diff --git a/src/test/ui/nll/relate_tys/var-appears-twice.rs b/src/test/ui/nll/relate_tys/var-appears-twice.rs index 2f227c872598..77129f4468f0 100644 --- a/src/test/ui/nll/relate_tys/var-appears-twice.rs +++ b/src/test/ui/nll/relate_tys/var-appears-twice.rs @@ -2,9 +2,6 @@ // function returning always its first argument can be upcast to one // that returns either first or second argument. -#![feature(nll)] -#![allow(warnings)] - use std::cell::Cell; type DoubleCell
= Cell<(A, A)>; diff --git a/src/test/ui/nll/relate_tys/var-appears-twice.stderr b/src/test/ui/nll/relate_tys/var-appears-twice.stderr index 7c078d226dc0..d032ce6f2132 100644 --- a/src/test/ui/nll/relate_tys/var-appears-twice.stderr +++ b/src/test/ui/nll/relate_tys/var-appears-twice.stderr @@ -1,5 +1,5 @@ error[E0597]: `b` does not live long enough - --> $DIR/var-appears-twice.rs:23:38 + --> $DIR/var-appears-twice.rs:20:38 | LL | let x: DoubleCell<_> = make_cell(&b); | ------------- ^^ borrowed value does not live long enough diff --git a/src/test/ui/nll/return-ref-mut-issue-46557.rs b/src/test/ui/nll/return-ref-mut-issue-46557.rs index b535ab1f5e13..dca61d39dfe8 100644 --- a/src/test/ui/nll/return-ref-mut-issue-46557.rs +++ b/src/test/ui/nll/return-ref-mut-issue-46557.rs @@ -1,8 +1,5 @@ // Regression test for issue #46557 -#![feature(nll)] -#![allow(dead_code)] - fn gimme_static_mut() -> &'static mut u32 { let ref mut x = 1234543; x //~ ERROR cannot return value referencing temporary value [E0515] diff --git a/src/test/ui/nll/return-ref-mut-issue-46557.stderr b/src/test/ui/nll/return-ref-mut-issue-46557.stderr index cc201136ff21..720440a0ae5f 100644 --- a/src/test/ui/nll/return-ref-mut-issue-46557.stderr +++ b/src/test/ui/nll/return-ref-mut-issue-46557.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return value referencing temporary value - --> $DIR/return-ref-mut-issue-46557.rs:8:5 + --> $DIR/return-ref-mut-issue-46557.rs:5:5 | LL | let ref mut x = 1234543; | ------- temporary value created here diff --git a/src/test/ui/nll/ty-outlives/issue-53789-1.rs b/src/test/ui/nll/ty-outlives/issue-53789-1.rs index 586f076c8cab..dc67c1a68aaf 100644 --- a/src/test/ui/nll/ty-outlives/issue-53789-1.rs +++ b/src/test/ui/nll/ty-outlives/issue-53789-1.rs @@ -2,9 +2,6 @@ // // compile-pass -#![feature(nll)] -#![allow(unused_variables)] - use std::collections::BTreeMap; trait ValueTree { diff --git a/src/test/ui/nll/ty-outlives/issue-53789-2.rs b/src/test/ui/nll/ty-outlives/issue-53789-2.rs index de8b05aeed75..1b80be2eaff9 100644 --- a/src/test/ui/nll/ty-outlives/issue-53789-2.rs +++ b/src/test/ui/nll/ty-outlives/issue-53789-2.rs @@ -2,9 +2,6 @@ // // compile-pass -#![feature(nll)] -#![allow(unused_variables)] - use std::collections::BTreeMap; use std::ops::Range; use std::cmp::Ord; diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.nll.stderr b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.nll.stderr new file mode 100644 index 000000000000..3a84cbfbedc0 --- /dev/null +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.nll.stderr @@ -0,0 +1,11 @@ +error[E0309]: the associated type `>::Output` may not live long enough + --> $DIR/projection-where-clause-env-wrong-bound.rs:15:5 + | +LL | bar::() + | ^^^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `>::Output: 'a`... + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.rs b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.rs index 9c2cbfd4a453..dce88b88c753 100644 --- a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.rs +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - // Test that we are able to establish that `>::Output` outlives `'b` here. We need to prove however // that `>::Output` outlives `'a`, so we also have to diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr index 1aed0a545b47..1a5a3719fd86 100644 --- a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr @@ -1,10 +1,15 @@ -error[E0309]: the associated type `>::Output` may not live long enough - --> $DIR/projection-where-clause-env-wrong-bound.rs:17:5 +error[E0309]: the associated type `>::Output` may not live long enough + --> $DIR/projection-where-clause-env-wrong-bound.rs:15:5 | LL | bar::() | ^^^^^^^^^^^^^^^^ | - = help: consider adding an explicit lifetime bound `>::Output: 'a`... + = help: consider adding an explicit lifetime bound `>::Output: 'a`... +note: ...so that the type `>::Output` will meet its required lifetime bounds + --> $DIR/projection-where-clause-env-wrong-bound.rs:15:5 + | +LL | bar::() + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs b/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs index c6935badf54b..731476661112 100644 --- a/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - // Test that when we have a `>::Output: 'a` // relationship in the environment we take advantage of it. In this // case, that means we **don't** have to prove that `T: 'a`. diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.rs b/src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.rs deleted file mode 100644 index ec5594375709..000000000000 --- a/src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Test that we assume that universal types like `T` outlive the -// function body. Same as ty-param-fn-body, but uses `feature(nll)`, -// which affects error reporting. - -#![feature(nll)] - -#![allow(warnings)] - -use std::cell::Cell; - -// No errors here, because `'a` is local to the body. -fn region_within_body(t: T) { - let some_int = 22; - let cell = Cell::new(&some_int); - outlives(cell, t) -} - -// Error here, because T: 'a is not satisfied. -fn region_static<'a, T>(cell: Cell<&'a usize>, t: T) { - outlives(cell, t) - //~^ ERROR the parameter type `T` may not live long enough -} - -fn outlives<'a, T>(x: Cell<&'a usize>, y: T) -where - T: 'a, -{ -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.stderr b/src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.stderr deleted file mode 100644 index b3c02f7f4291..000000000000 --- a/src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0309]: the parameter type `T` may not live long enough - --> $DIR/ty-param-fn-body-nll-feature.rs:20:5 - | -LL | outlives(cell, t) - | ^^^^^^^^^^^^^^^^^ - | - = help: consider adding an explicit lifetime bound `T: 'a`... - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/nll/type-alias-free-regions.nll.stderr b/src/test/ui/nll/type-alias-free-regions.nll.stderr new file mode 100644 index 000000000000..235bf4167d52 --- /dev/null +++ b/src/test/ui/nll/type-alias-free-regions.nll.stderr @@ -0,0 +1,22 @@ +error: lifetime may not live long enough + --> $DIR/type-alias-free-regions.rs:17:9 + | +LL | impl<'a> FromBox<'a> for C<'a> { + | -- lifetime `'a` defined here +LL | fn from_box(b: Box) -> Self { + | - has type `std::boxed::Box>` +LL | C { f: b } + | ^^^^^^^^^^ returning this value requires that `'1` must outlive `'a` + +error: lifetime may not live long enough + --> $DIR/type-alias-free-regions.rs:27:9 + | +LL | impl<'a> FromTuple<'a> for C<'a> { + | -- lifetime `'a` defined here +LL | fn from_tuple(b: (B,)) -> Self { + | - has type `(std::boxed::Box<&'1 isize>,)` +LL | C { f: Box::new(b.0) } + | ^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'a` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/nll/type-alias-free-regions.rs b/src/test/ui/nll/type-alias-free-regions.rs index ebe6b9d20739..fd5566f35d51 100644 --- a/src/test/ui/nll/type-alias-free-regions.rs +++ b/src/test/ui/nll/type-alias-free-regions.rs @@ -1,8 +1,6 @@ // Test that we don't assume that type aliases have the same type parameters // as the type they alias and then panic when we see this. -#![feature(nll)] - type A<'a> = &'a isize; type B<'a> = Box>; diff --git a/src/test/ui/nll/type-alias-free-regions.stderr b/src/test/ui/nll/type-alias-free-regions.stderr index 4facc2d0da0e..00d58d34362e 100644 --- a/src/test/ui/nll/type-alias-free-regions.stderr +++ b/src/test/ui/nll/type-alias-free-regions.stderr @@ -1,22 +1,52 @@ -error: lifetime may not live long enough - --> $DIR/type-alias-free-regions.rs:19:9 +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements + --> $DIR/type-alias-free-regions.rs:17:9 + | +LL | C { f: b } + | ^ + | +note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 16:5... + --> $DIR/type-alias-free-regions.rs:16:5 + | +LL | / fn from_box(b: Box) -> Self { +LL | | C { f: b } +LL | | } + | |_____^ + = note: ...so that the expression is assignable: + expected std::boxed::Box> + found std::boxed::Box> +note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 15:6... + --> $DIR/type-alias-free-regions.rs:15:6 | LL | impl<'a> FromBox<'a> for C<'a> { - | -- lifetime `'a` defined here -LL | fn from_box(b: Box) -> Self { - | - has type `std::boxed::Box>` -LL | C { f: b } - | ^^^^^^^^^^ returning this value requires that `'1` must outlive `'a` + | ^^ + = note: ...so that the expression is assignable: + expected C<'a> + found C<'_> -error: lifetime may not live long enough - --> $DIR/type-alias-free-regions.rs:29:9 +error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements + --> $DIR/type-alias-free-regions.rs:27:16 + | +LL | C { f: Box::new(b.0) } + | ^^^^^^^^^^^^^ + | +note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 26:5... + --> $DIR/type-alias-free-regions.rs:26:5 + | +LL | / fn from_tuple(b: (B,)) -> Self { +LL | | C { f: Box::new(b.0) } +LL | | } + | |_____^ + = note: ...so that the expression is assignable: + expected std::boxed::Box<&isize> + found std::boxed::Box<&isize> +note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 25:6... + --> $DIR/type-alias-free-regions.rs:25:6 | LL | impl<'a> FromTuple<'a> for C<'a> { - | -- lifetime `'a` defined here -LL | fn from_tuple(b: (B,)) -> Self { - | - has type `(std::boxed::Box<&'1 isize>,)` -LL | C { f: Box::new(b.0) } - | ^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'a` + | ^^ + = note: ...so that the expression is assignable: + expected C<'a> + found C<'_> error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/unused-mut-issue-50343.rs b/src/test/ui/nll/unused-mut-issue-50343.rs index 06dbc4735573..da0d9229c126 100644 --- a/src/test/ui/nll/unused-mut-issue-50343.rs +++ b/src/test/ui/nll/unused-mut-issue-50343.rs @@ -1,4 +1,3 @@ -#![feature(nll)] #![deny(unused_mut)] fn main() { diff --git a/src/test/ui/nll/unused-mut-issue-50343.stderr b/src/test/ui/nll/unused-mut-issue-50343.stderr index ef31dd7b29a4..261d678db675 100644 --- a/src/test/ui/nll/unused-mut-issue-50343.stderr +++ b/src/test/ui/nll/unused-mut-issue-50343.stderr @@ -1,5 +1,5 @@ error: variable does not need to be mutable - --> $DIR/unused-mut-issue-50343.rs:5:33 + --> $DIR/unused-mut-issue-50343.rs:4:33 | LL | vec![(42, 22)].iter().map(|(mut x, _y)| ()).count(); | ----^ @@ -7,7 +7,7 @@ LL | vec![(42, 22)].iter().map(|(mut x, _y)| ()).count(); | help: remove this `mut` | note: lint level defined here - --> $DIR/unused-mut-issue-50343.rs:2:9 + --> $DIR/unused-mut-issue-50343.rs:1:9 | LL | #![deny(unused_mut)] | ^^^^^^^^^^ diff --git a/src/test/ui/nll/user-annotations/adt-brace-enums.rs b/src/test/ui/nll/user-annotations/adt-brace-enums.rs index 842ebae26181..0d9828342d8c 100644 --- a/src/test/ui/nll/user-annotations/adt-brace-enums.rs +++ b/src/test/ui/nll/user-annotations/adt-brace-enums.rs @@ -1,8 +1,6 @@ // Unit test for the "user substitutions" that are annotated on each // node. -#![feature(nll)] - enum SomeEnum { SomeVariant { t: T } } diff --git a/src/test/ui/nll/user-annotations/adt-brace-enums.stderr b/src/test/ui/nll/user-annotations/adt-brace-enums.stderr index 38f068746a67..e38b77fdcea0 100644 --- a/src/test/ui/nll/user-annotations/adt-brace-enums.stderr +++ b/src/test/ui/nll/user-annotations/adt-brace-enums.stderr @@ -1,5 +1,5 @@ error[E0597]: `c` does not live long enough - --> $DIR/adt-brace-enums.rs:27:48 + --> $DIR/adt-brace-enums.rs:25:48 | LL | SomeEnum::SomeVariant::<&'static u32> { t: &c }; | ^^ @@ -10,7 +10,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-brace-enums.rs:32:43 + --> $DIR/adt-brace-enums.rs:30:43 | LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { | -- lifetime `'a` defined here @@ -24,7 +24,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-brace-enums.rs:42:47 + --> $DIR/adt-brace-enums.rs:40:47 | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here diff --git a/src/test/ui/nll/user-annotations/adt-brace-structs.rs b/src/test/ui/nll/user-annotations/adt-brace-structs.rs index d7ebbe8eb5fc..bdbfd87d584d 100644 --- a/src/test/ui/nll/user-annotations/adt-brace-structs.rs +++ b/src/test/ui/nll/user-annotations/adt-brace-structs.rs @@ -1,8 +1,6 @@ // Unit test for the "user substitutions" that are annotated on each // node. -#![feature(nll)] - struct SomeStruct { t: T } fn no_annot() { diff --git a/src/test/ui/nll/user-annotations/adt-brace-structs.stderr b/src/test/ui/nll/user-annotations/adt-brace-structs.stderr index 25a9de480b2c..3c3003477c2d 100644 --- a/src/test/ui/nll/user-annotations/adt-brace-structs.stderr +++ b/src/test/ui/nll/user-annotations/adt-brace-structs.stderr @@ -1,5 +1,5 @@ error[E0597]: `c` does not live long enough - --> $DIR/adt-brace-structs.rs:25:37 + --> $DIR/adt-brace-structs.rs:23:37 | LL | SomeStruct::<&'static u32> { t: &c }; | ^^ @@ -10,7 +10,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-brace-structs.rs:30:32 + --> $DIR/adt-brace-structs.rs:28:32 | LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { | -- lifetime `'a` defined here @@ -24,7 +24,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-brace-structs.rs:40:36 + --> $DIR/adt-brace-structs.rs:38:36 | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here diff --git a/src/test/ui/nll/user-annotations/adt-nullary-enums.rs b/src/test/ui/nll/user-annotations/adt-nullary-enums.rs index 7a8f55a800b9..53853668d197 100644 --- a/src/test/ui/nll/user-annotations/adt-nullary-enums.rs +++ b/src/test/ui/nll/user-annotations/adt-nullary-enums.rs @@ -1,7 +1,6 @@ // Unit test for the "user substitutions" that are annotated on each // node. -#![feature(nll)] #![allow(warnings)] use std::cell::Cell; diff --git a/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr b/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr index 1afbac7c4b2e..bb7034122288 100644 --- a/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr +++ b/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr @@ -1,5 +1,5 @@ error[E0597]: `c` does not live long enough - --> $DIR/adt-nullary-enums.rs:34:41 + --> $DIR/adt-nullary-enums.rs:33:41 | LL | SomeEnum::SomeVariant(Cell::new(&c)), | ----------^^- @@ -11,7 +11,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-nullary-enums.rs:42:41 + --> $DIR/adt-nullary-enums.rs:41:41 | LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { | -- lifetime `'a` defined here @@ -26,7 +26,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-nullary-enums.rs:55:45 + --> $DIR/adt-nullary-enums.rs:54:45 | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here diff --git a/src/test/ui/nll/user-annotations/adt-tuple-enums.rs b/src/test/ui/nll/user-annotations/adt-tuple-enums.rs index 085596ecc53e..efe8dfda1910 100644 --- a/src/test/ui/nll/user-annotations/adt-tuple-enums.rs +++ b/src/test/ui/nll/user-annotations/adt-tuple-enums.rs @@ -1,7 +1,6 @@ // Unit test for the "user substitutions" that are annotated on each // node. -#![feature(nll)] #![allow(warnings)] enum SomeEnum { diff --git a/src/test/ui/nll/user-annotations/adt-tuple-enums.stderr b/src/test/ui/nll/user-annotations/adt-tuple-enums.stderr index cd625653ace2..810912bf8861 100644 --- a/src/test/ui/nll/user-annotations/adt-tuple-enums.stderr +++ b/src/test/ui/nll/user-annotations/adt-tuple-enums.stderr @@ -1,5 +1,5 @@ error[E0597]: `c` does not live long enough - --> $DIR/adt-tuple-enums.rs:29:43 + --> $DIR/adt-tuple-enums.rs:28:43 | LL | SomeEnum::SomeVariant::<&'static u32>(&c); | ^^ @@ -10,7 +10,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-tuple-enums.rs:34:38 + --> $DIR/adt-tuple-enums.rs:33:38 | LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { | -- lifetime `'a` defined here @@ -24,7 +24,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-tuple-enums.rs:44:42 + --> $DIR/adt-tuple-enums.rs:43:42 | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here diff --git a/src/test/ui/nll/user-annotations/adt-tuple-struct.rs b/src/test/ui/nll/user-annotations/adt-tuple-struct.rs index ebbe3cd2c898..37284e1fda82 100644 --- a/src/test/ui/nll/user-annotations/adt-tuple-struct.rs +++ b/src/test/ui/nll/user-annotations/adt-tuple-struct.rs @@ -1,8 +1,6 @@ // Unit test for the "user substitutions" that are annotated on each // node. -#![feature(nll)] - struct SomeStruct(T); fn no_annot() { diff --git a/src/test/ui/nll/user-annotations/adt-tuple-struct.stderr b/src/test/ui/nll/user-annotations/adt-tuple-struct.stderr index 2bb58bb2590b..4d2140eca1b0 100644 --- a/src/test/ui/nll/user-annotations/adt-tuple-struct.stderr +++ b/src/test/ui/nll/user-annotations/adt-tuple-struct.stderr @@ -1,5 +1,5 @@ error[E0597]: `c` does not live long enough - --> $DIR/adt-tuple-struct.rs:25:32 + --> $DIR/adt-tuple-struct.rs:23:32 | LL | SomeStruct::<&'static u32>(&c); | ^^ @@ -10,7 +10,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-tuple-struct.rs:30:27 + --> $DIR/adt-tuple-struct.rs:28:27 | LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { | -- lifetime `'a` defined here @@ -24,7 +24,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/adt-tuple-struct.rs:40:31 + --> $DIR/adt-tuple-struct.rs:38:31 | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here diff --git a/src/test/ui/nll/user-annotations/cast_static_lifetime.rs b/src/test/ui/nll/user-annotations/cast_static_lifetime.rs index 4756c771f6ea..bb6129dacda8 100644 --- a/src/test/ui/nll/user-annotations/cast_static_lifetime.rs +++ b/src/test/ui/nll/user-annotations/cast_static_lifetime.rs @@ -1,5 +1,4 @@ #![allow(warnings)] -#![feature(nll)] fn main() { let x = 22_u32; diff --git a/src/test/ui/nll/user-annotations/cast_static_lifetime.stderr b/src/test/ui/nll/user-annotations/cast_static_lifetime.stderr index 0228b56d761f..4599d04e7e23 100644 --- a/src/test/ui/nll/user-annotations/cast_static_lifetime.stderr +++ b/src/test/ui/nll/user-annotations/cast_static_lifetime.stderr @@ -1,5 +1,5 @@ error[E0597]: `x` does not live long enough - --> $DIR/cast_static_lifetime.rs:6:19 + --> $DIR/cast_static_lifetime.rs:5:19 | LL | let y: &u32 = (&x) as &'static u32; | ^^^^---------------- diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.nll.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.nll.stderr new file mode 100644 index 000000000000..c39301588acf --- /dev/null +++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.nll.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/constant-in-expr-inherent-1.rs:8:5 + | +LL | fn foo<'a>(_: &'a u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | >::C + | ^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.rs b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.rs index 9f0c60967efb..e3a8a5f58dfd 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.rs +++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - struct Foo<'a> { x: &'a u32 } impl<'a> Foo<'a> { diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr index 9a28fbd11339..77e1339dc161 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr @@ -1,10 +1,23 @@ -error: lifetime may not live long enough - --> $DIR/constant-in-expr-inherent-1.rs:10:5 +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements + --> $DIR/constant-in-expr-inherent-1.rs:8:5 + | +LL | >::C + | ^^^^^^^^^^^^ + | +note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 7:8... + --> $DIR/constant-in-expr-inherent-1.rs:7:8 | LL | fn foo<'a>(_: &'a u32) -> &'static u32 { - | -- lifetime `'a` defined here + | ^^ + = note: ...so that the types are compatible: + expected Foo<'_> + found Foo<'a> + = note: but, the lifetime must be valid for the static lifetime... +note: ...so that reference does not outlive borrowed content + --> $DIR/constant-in-expr-inherent-1.rs:8:5 + | LL | >::C - | ^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + | ^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.rs b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.rs index 123be6b3e409..90696d4b17d8 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.rs +++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.rs @@ -1,8 +1,6 @@ // Test that we still check constants are well-formed, even when we there's no // type annotation to check. -#![feature(nll)] - const FUN: fn(&'static ()) = |_| {}; struct A; impl A { diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr index 07e2e1e85cb7..12065a85aa4a 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr @@ -1,5 +1,5 @@ error[E0597]: `x` does not live long enough - --> $DIR/constant-in-expr-inherent-2.rs:25:9 + --> $DIR/constant-in-expr-inherent-2.rs:23:9 | LL | FUN(&x); | ----^^- @@ -11,7 +11,7 @@ LL | } | - `x` dropped here while still borrowed error[E0597]: `x` does not live long enough - --> $DIR/constant-in-expr-inherent-2.rs:26:23 + --> $DIR/constant-in-expr-inherent-2.rs:24:23 | LL | A::ASSOCIATED_FUN(&x); | ------------------^^- @@ -23,7 +23,7 @@ LL | } | - `x` dropped here while still borrowed error[E0597]: `x` does not live long enough - --> $DIR/constant-in-expr-inherent-2.rs:27:28 + --> $DIR/constant-in-expr-inherent-2.rs:25:28 | LL | B::ALSO_ASSOCIATED_FUN(&x); | -----------------------^^- @@ -35,7 +35,7 @@ LL | } | - `x` dropped here while still borrowed error[E0597]: `x` does not live long enough - --> $DIR/constant-in-expr-inherent-2.rs:28:31 + --> $DIR/constant-in-expr-inherent-2.rs:26:31 | LL | <_>::TRAIT_ASSOCIATED_FUN(&x); | --------------------------^^- diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.nll.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.nll.stderr new file mode 100644 index 000000000000..541a2cfaf299 --- /dev/null +++ b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.nll.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/constant-in-expr-normalize.rs:18:5 + | +LL | fn foo<'a>(_: &'a u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | <() as Foo<'a>>::C + | ^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.rs b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.rs index 4292fc710e98..b7095430d8bd 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.rs +++ b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - trait Mirror { type Me; } diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr index 5e66a30d7c33..f49d68458bea 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr @@ -1,10 +1,15 @@ -error: lifetime may not live long enough - --> $DIR/constant-in-expr-normalize.rs:20:5 +error[E0312]: lifetime of reference outlives lifetime of borrowed content... + --> $DIR/constant-in-expr-normalize.rs:18:5 + | +LL | <() as Foo<'a>>::C + | ^^^^^^^^^^^^^^^^^^ + | + = note: ...the reference is valid for the static lifetime... +note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 17:8 + --> $DIR/constant-in-expr-normalize.rs:17:8 | LL | fn foo<'a>(_: &'a u32) -> &'static u32 { - | -- lifetime `'a` defined here -LL | <() as Foo<'a>>::C - | ^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + | ^^ error: aborting due to previous error diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.nll.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.nll.stderr new file mode 100644 index 000000000000..ea0fcb6d634c --- /dev/null +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.nll.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/constant-in-expr-trait-item-1.rs:10:5 + | +LL | fn foo<'a>(_: &'a u32) -> &'static u32 { + | -- lifetime `'a` defined here +LL | <() as Foo<'a>>::C + | ^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.rs b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.rs index daa0d7bc2414..e0400b2cc026 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.rs +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - trait Foo<'a> { const C: &'a u32; } diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr index c96838f259a8..451bcf41e42a 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr @@ -1,10 +1,15 @@ -error: lifetime may not live long enough - --> $DIR/constant-in-expr-trait-item-1.rs:12:5 +error[E0312]: lifetime of reference outlives lifetime of borrowed content... + --> $DIR/constant-in-expr-trait-item-1.rs:10:5 + | +LL | <() as Foo<'a>>::C + | ^^^^^^^^^^^^^^^^^^ + | + = note: ...the reference is valid for the static lifetime... +note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 9:8 + --> $DIR/constant-in-expr-trait-item-1.rs:9:8 | LL | fn foo<'a>(_: &'a u32) -> &'static u32 { - | -- lifetime `'a` defined here -LL | <() as Foo<'a>>::C - | ^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + | ^^ error: aborting due to previous error diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.nll.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.nll.stderr new file mode 100644 index 000000000000..ff549f1d88bd --- /dev/null +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.nll.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/constant-in-expr-trait-item-2.rs:10:5 + | +LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 { + | -- lifetime `'a` defined here +LL | >::C + | ^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.rs b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.rs index cd66e7a49cb8..73c4e577b05c 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.rs +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - trait Foo<'a> { const C: &'a u32; } diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr index fcc3c40e43f7..d129e55e1e6f 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr @@ -1,10 +1,15 @@ -error: lifetime may not live long enough - --> $DIR/constant-in-expr-trait-item-2.rs:12:5 +error[E0312]: lifetime of reference outlives lifetime of borrowed content... + --> $DIR/constant-in-expr-trait-item-2.rs:10:5 + | +LL | >::C + | ^^^^^^^^^^^^^^^^^ + | + = note: ...the reference is valid for the static lifetime... +note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 9:8 + --> $DIR/constant-in-expr-trait-item-2.rs:9:8 | LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 { - | -- lifetime `'a` defined here -LL | >::C - | ^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + | ^^ error: aborting due to previous error diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.nll.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.nll.stderr new file mode 100644 index 000000000000..7f160d8e398b --- /dev/null +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.nll.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/constant-in-expr-trait-item-3.rs:10:5 + | +LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 { + | -- lifetime `'a` defined here +LL | T::C + | ^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.rs b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.rs index f83ae2438e6d..567e31ef9363 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.rs +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - trait Foo<'a> { const C: &'a u32; } diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr index c91370c810c8..77655fe091b6 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr @@ -1,10 +1,23 @@ -error: lifetime may not live long enough - --> $DIR/constant-in-expr-trait-item-3.rs:12:5 +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements + --> $DIR/constant-in-expr-trait-item-3.rs:10:5 + | +LL | T::C + | ^^^^ + | +note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 9:8... + --> $DIR/constant-in-expr-trait-item-3.rs:9:8 | LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 { - | -- lifetime `'a` defined here + | ^^ + = note: ...so that the types are compatible: + expected Foo<'_> + found Foo<'a> + = note: but, the lifetime must be valid for the static lifetime... +note: ...so that reference does not outlive borrowed content + --> $DIR/constant-in-expr-trait-item-3.rs:10:5 + | LL | T::C - | ^^^^ returning this value requires that `'a` must outlive `'static` + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/nll/user-annotations/fns.rs b/src/test/ui/nll/user-annotations/fns.rs index 1e5e9340bef5..38db6d1c4c56 100644 --- a/src/test/ui/nll/user-annotations/fns.rs +++ b/src/test/ui/nll/user-annotations/fns.rs @@ -1,8 +1,6 @@ // Unit test for the "user substitutions" that are annotated on each // node. -#![feature(nll)] - fn some_fn(arg: T) { } fn no_annot() { diff --git a/src/test/ui/nll/user-annotations/fns.stderr b/src/test/ui/nll/user-annotations/fns.stderr index dadce24159e8..e0640da39e2b 100644 --- a/src/test/ui/nll/user-annotations/fns.stderr +++ b/src/test/ui/nll/user-annotations/fns.stderr @@ -1,5 +1,5 @@ error[E0597]: `c` does not live long enough - --> $DIR/fns.rs:25:29 + --> $DIR/fns.rs:23:29 | LL | some_fn::<&'static u32>(&c); | ------------------------^^- @@ -10,7 +10,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/fns.rs:30:24 + --> $DIR/fns.rs:28:24 | LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { | -- lifetime `'a` defined here @@ -24,7 +24,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/fns.rs:40:28 + --> $DIR/fns.rs:38:28 | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here diff --git a/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs b/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs index 0a8a6793dc78..6b9d30f5ab42 100644 --- a/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs +++ b/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs @@ -1,5 +1,4 @@ // compile-pass -#![feature(nll)] // This test is reduced from a scenario pnkfelix encountered while // bootstrapping the compiler. diff --git a/src/test/ui/nll/user-annotations/issue-55219.rs b/src/test/ui/nll/user-annotations/issue-55219.rs index 7daa5a59b997..4d18e96cc154 100644 --- a/src/test/ui/nll/user-annotations/issue-55219.rs +++ b/src/test/ui/nll/user-annotations/issue-55219.rs @@ -5,8 +5,6 @@ // // run-pass -#![feature(nll)] - pub struct Foo(T); impl Foo { diff --git a/src/test/ui/nll/user-annotations/issue-55241.rs b/src/test/ui/nll/user-annotations/issue-55241.rs index d7686b9dc941..29969c7b4c6c 100644 --- a/src/test/ui/nll/user-annotations/issue-55241.rs +++ b/src/test/ui/nll/user-annotations/issue-55241.rs @@ -7,8 +7,6 @@ // // run-pass -#![feature(nll)] - pub trait Hasher { type Out: Eq; } diff --git a/src/test/ui/nll/user-annotations/method-call.rs b/src/test/ui/nll/user-annotations/method-call.rs index 59d1513c4c38..beafc597ac11 100644 --- a/src/test/ui/nll/user-annotations/method-call.rs +++ b/src/test/ui/nll/user-annotations/method-call.rs @@ -1,8 +1,6 @@ // Unit test for the "user substitutions" that are annotated on each // node. -#![feature(nll)] - trait Bazoom { fn method(&self, arg: T, arg2: U) { } } diff --git a/src/test/ui/nll/user-annotations/method-call.stderr b/src/test/ui/nll/user-annotations/method-call.stderr index 7e5314614f34..10447e45a6d4 100644 --- a/src/test/ui/nll/user-annotations/method-call.stderr +++ b/src/test/ui/nll/user-annotations/method-call.stderr @@ -1,5 +1,5 @@ error[E0597]: `c` does not live long enough - --> $DIR/method-call.rs:38:34 + --> $DIR/method-call.rs:36:34 | LL | a.method::<&'static u32>(b, &c); | -----------------------------^^- @@ -10,7 +10,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/method-call.rs:45:29 + --> $DIR/method-call.rs:43:29 | LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { | -- lifetime `'a` defined here @@ -24,7 +24,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/method-call.rs:59:33 + --> $DIR/method-call.rs:57:33 | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here diff --git a/src/test/ui/nll/user-annotations/method-ufcs-1.rs b/src/test/ui/nll/user-annotations/method-ufcs-1.rs index 7968a9f6c4fd..950771f35e49 100644 --- a/src/test/ui/nll/user-annotations/method-ufcs-1.rs +++ b/src/test/ui/nll/user-annotations/method-ufcs-1.rs @@ -1,8 +1,6 @@ // Unit test for the "user substitutions" that are annotated on each // node. -#![feature(nll)] - trait Bazoom: Sized { fn method(self, arg: T, arg2: U) { } } diff --git a/src/test/ui/nll/user-annotations/method-ufcs-1.stderr b/src/test/ui/nll/user-annotations/method-ufcs-1.stderr index 12b02ba33f72..962ddfd2bd15 100644 --- a/src/test/ui/nll/user-annotations/method-ufcs-1.stderr +++ b/src/test/ui/nll/user-annotations/method-ufcs-1.stderr @@ -1,5 +1,5 @@ error[E0597]: `a` does not live long enough - --> $DIR/method-ufcs-1.rs:32:7 + --> $DIR/method-ufcs-1.rs:30:7 | LL | x(&a, b, c); | --^^------- @@ -10,7 +10,7 @@ LL | } | - `a` dropped here while still borrowed error[E0597]: `a` does not live long enough - --> $DIR/method-ufcs-1.rs:39:36 + --> $DIR/method-ufcs-1.rs:37:36 | LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { | -- lifetime `'a` defined here @@ -24,7 +24,7 @@ LL | } | - `a` dropped here while still borrowed error[E0597]: `a` does not live long enough - --> $DIR/method-ufcs-1.rs:53:41 + --> $DIR/method-ufcs-1.rs:51:41 | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here diff --git a/src/test/ui/nll/user-annotations/method-ufcs-2.rs b/src/test/ui/nll/user-annotations/method-ufcs-2.rs index a1d0e7b4c920..7dc0f0c12a43 100644 --- a/src/test/ui/nll/user-annotations/method-ufcs-2.rs +++ b/src/test/ui/nll/user-annotations/method-ufcs-2.rs @@ -1,8 +1,6 @@ // Unit test for the "user substitutions" that are annotated on each // node. -#![feature(nll)] - trait Bazoom: Sized { fn method(self, arg: T, arg2: U) { } } diff --git a/src/test/ui/nll/user-annotations/method-ufcs-2.stderr b/src/test/ui/nll/user-annotations/method-ufcs-2.stderr index a55ed1aa272a..63d59905e1c3 100644 --- a/src/test/ui/nll/user-annotations/method-ufcs-2.stderr +++ b/src/test/ui/nll/user-annotations/method-ufcs-2.stderr @@ -1,5 +1,5 @@ error[E0597]: `a` does not live long enough - --> $DIR/method-ufcs-2.rs:32:7 + --> $DIR/method-ufcs-2.rs:30:7 | LL | x(&a, b, c); | --^^------- @@ -10,7 +10,7 @@ LL | } | - `a` dropped here while still borrowed error[E0597]: `b` does not live long enough - --> $DIR/method-ufcs-2.rs:39:39 + --> $DIR/method-ufcs-2.rs:37:39 | LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { | -- lifetime `'a` defined here @@ -24,7 +24,7 @@ LL | } | - `b` dropped here while still borrowed error[E0597]: `b` does not live long enough - --> $DIR/method-ufcs-2.rs:53:44 + --> $DIR/method-ufcs-2.rs:51:44 | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here diff --git a/src/test/ui/nll/user-annotations/method-ufcs-3.rs b/src/test/ui/nll/user-annotations/method-ufcs-3.rs index ea480c03c350..59d2009d14bd 100644 --- a/src/test/ui/nll/user-annotations/method-ufcs-3.rs +++ b/src/test/ui/nll/user-annotations/method-ufcs-3.rs @@ -1,8 +1,6 @@ // Unit test for the "user substitutions" that are annotated on each // node. -#![feature(nll)] - trait Bazoom { fn method(&self, arg: T, arg2: U) { } } diff --git a/src/test/ui/nll/user-annotations/method-ufcs-3.stderr b/src/test/ui/nll/user-annotations/method-ufcs-3.stderr index 140bda2df414..e7851833e93b 100644 --- a/src/test/ui/nll/user-annotations/method-ufcs-3.stderr +++ b/src/test/ui/nll/user-annotations/method-ufcs-3.stderr @@ -1,5 +1,5 @@ error[E0597]: `c` does not live long enough - --> $DIR/method-ufcs-3.rs:38:53 + --> $DIR/method-ufcs-3.rs:36:53 | LL | <_ as Bazoom<_>>::method::<&'static u32>(&a, b, &c); | ------------------------------------------------^^- @@ -10,7 +10,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/method-ufcs-3.rs:45:48 + --> $DIR/method-ufcs-3.rs:43:48 | LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { | -- lifetime `'a` defined here @@ -24,7 +24,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/method-ufcs-3.rs:59:52 + --> $DIR/method-ufcs-3.rs:57:52 | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here diff --git a/src/test/ui/nll/user-annotations/method-ufcs-inherent-2.rs b/src/test/ui/nll/user-annotations/method-ufcs-inherent-2.rs index a77d6af5323c..cfbc0bcf6b0f 100644 --- a/src/test/ui/nll/user-annotations/method-ufcs-inherent-2.rs +++ b/src/test/ui/nll/user-annotations/method-ufcs-inherent-2.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - // Check that substitutions given on the self type (here, `A`) can be // used in combination with annotations given for method arguments. diff --git a/src/test/ui/nll/user-annotations/method-ufcs-inherent-2.stderr b/src/test/ui/nll/user-annotations/method-ufcs-inherent-2.stderr index 4dc534b2e77a..06f20d9b2355 100644 --- a/src/test/ui/nll/user-annotations/method-ufcs-inherent-2.stderr +++ b/src/test/ui/nll/user-annotations/method-ufcs-inherent-2.stderr @@ -1,5 +1,5 @@ error[E0597]: `v` does not live long enough - --> $DIR/method-ufcs-inherent-2.rs:16:37 + --> $DIR/method-ufcs-inherent-2.rs:14:37 | LL | fn foo<'a>() { | -- lifetime `'a` defined here @@ -14,7 +14,7 @@ LL | } | - `v` dropped here while still borrowed error[E0597]: `v` does not live long enough - --> $DIR/method-ufcs-inherent-2.rs:16:41 + --> $DIR/method-ufcs-inherent-2.rs:14:41 | LL | fn foo<'a>() { | -- lifetime `'a` defined here diff --git a/src/test/ui/nll/user-annotations/method-ufcs-inherent-4.rs b/src/test/ui/nll/user-annotations/method-ufcs-inherent-4.rs index 3f88c3df48e0..85e7597390d5 100644 --- a/src/test/ui/nll/user-annotations/method-ufcs-inherent-4.rs +++ b/src/test/ui/nll/user-annotations/method-ufcs-inherent-4.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - // Check that inherent methods invoked with `::new` style // carry their annotations through to NLL in connection with // method type parameters. diff --git a/src/test/ui/nll/user-annotations/method-ufcs-inherent-4.stderr b/src/test/ui/nll/user-annotations/method-ufcs-inherent-4.stderr index a41cf50465e8..0f83e99cdfb9 100644 --- a/src/test/ui/nll/user-annotations/method-ufcs-inherent-4.stderr +++ b/src/test/ui/nll/user-annotations/method-ufcs-inherent-4.stderr @@ -1,5 +1,5 @@ error[E0597]: `v` does not live long enough - --> $DIR/method-ufcs-inherent-4.rs:17:37 + --> $DIR/method-ufcs-inherent-4.rs:15:37 | LL | fn foo<'a>() { | -- lifetime `'a` defined here @@ -14,7 +14,7 @@ LL | } | - `v` dropped here while still borrowed error[E0597]: `v` does not live long enough - --> $DIR/method-ufcs-inherent-4.rs:17:41 + --> $DIR/method-ufcs-inherent-4.rs:15:41 | LL | fn foo<'a>() { | -- lifetime `'a` defined here diff --git a/src/test/ui/nll/user-annotations/normalization.rs b/src/test/ui/nll/user-annotations/normalization.rs index e0af2e67e183..870e3d8110cd 100644 --- a/src/test/ui/nll/user-annotations/normalization.rs +++ b/src/test/ui/nll/user-annotations/normalization.rs @@ -1,8 +1,6 @@ // Test that we enforce a `&'static` requirement that is only visible // after normalization. -#![feature(nll)] - trait Foo { type Out; } impl Foo for () { type Out = &'static u32; } diff --git a/src/test/ui/nll/user-annotations/normalization.stderr b/src/test/ui/nll/user-annotations/normalization.stderr index fe93c3edba87..4c7893789a53 100644 --- a/src/test/ui/nll/user-annotations/normalization.stderr +++ b/src/test/ui/nll/user-annotations/normalization.stderr @@ -1,5 +1,5 @@ error[E0597]: `a` does not live long enough - --> $DIR/normalization.rs:11:31 + --> $DIR/normalization.rs:9:31 | LL | let b: <() as Foo>::Out = &a; | ---------------- ^^ borrowed value does not live long enough diff --git a/src/test/ui/nll/user-annotations/normalize-self-ty.rs b/src/test/ui/nll/user-annotations/normalize-self-ty.rs index d97cc88dd9af..a06229a02032 100644 --- a/src/test/ui/nll/user-annotations/normalize-self-ty.rs +++ b/src/test/ui/nll/user-annotations/normalize-self-ty.rs @@ -4,8 +4,6 @@ // // run-pass -#![feature(nll)] - trait Mirror { type Me; } diff --git a/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs b/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs index 526134b6e4b3..59cd69c0ca55 100644 --- a/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs +++ b/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - enum Foo<'a> { Bar { field: &'a u32 } } diff --git a/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr b/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr index b483f219c900..a97e7a9fd46f 100644 --- a/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr +++ b/src/test/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr @@ -1,5 +1,5 @@ error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_brace_enum_variant.rs:9:33 + --> $DIR/pattern_substs_on_brace_enum_variant.rs:7:33 | LL | let foo = Foo::Bar { field: &y }; | ^^ borrowed value does not live long enough @@ -10,7 +10,7 @@ LL | } | - `y` dropped here while still borrowed error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_brace_enum_variant.rs:16:33 + --> $DIR/pattern_substs_on_brace_enum_variant.rs:14:33 | LL | let foo = Foo::Bar { field: &y }; | ^^ borrowed value does not live long enough diff --git a/src/test/ui/nll/user-annotations/pattern_substs_on_brace_struct.rs b/src/test/ui/nll/user-annotations/pattern_substs_on_brace_struct.rs index 1c92858eb3a0..1586c4ea30c6 100644 --- a/src/test/ui/nll/user-annotations/pattern_substs_on_brace_struct.rs +++ b/src/test/ui/nll/user-annotations/pattern_substs_on_brace_struct.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - struct Foo<'a> { field: &'a u32 } fn in_let() { diff --git a/src/test/ui/nll/user-annotations/pattern_substs_on_brace_struct.stderr b/src/test/ui/nll/user-annotations/pattern_substs_on_brace_struct.stderr index 9c888b0bffe5..408d7c2a5e2a 100644 --- a/src/test/ui/nll/user-annotations/pattern_substs_on_brace_struct.stderr +++ b/src/test/ui/nll/user-annotations/pattern_substs_on_brace_struct.stderr @@ -1,5 +1,5 @@ error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_brace_struct.rs:7:28 + --> $DIR/pattern_substs_on_brace_struct.rs:5:28 | LL | let foo = Foo { field: &y }; | ^^ borrowed value does not live long enough @@ -10,7 +10,7 @@ LL | } | - `y` dropped here while still borrowed error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_brace_struct.rs:14:28 + --> $DIR/pattern_substs_on_brace_struct.rs:12:28 | LL | let foo = Foo { field: &y }; | ^^ borrowed value does not live long enough diff --git a/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs b/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs index d6c364f8e3f0..6fa59fdd8d89 100644 --- a/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs +++ b/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - enum Foo<'a> { Bar(&'a u32) } diff --git a/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr b/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr index 698cff51126f..920c906f63a5 100644 --- a/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr +++ b/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr @@ -1,5 +1,5 @@ error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_tuple_enum_variant.rs:9:24 + --> $DIR/pattern_substs_on_tuple_enum_variant.rs:7:24 | LL | let foo = Foo::Bar(&y); | ^^ borrowed value does not live long enough @@ -10,7 +10,7 @@ LL | } | - `y` dropped here while still borrowed error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_tuple_enum_variant.rs:16:24 + --> $DIR/pattern_substs_on_tuple_enum_variant.rs:14:24 | LL | let foo = Foo::Bar(&y); | ^^ borrowed value does not live long enough diff --git a/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_struct.rs b/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_struct.rs index 626ca9087978..7486aab0e088 100644 --- a/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_struct.rs +++ b/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_struct.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - struct Foo<'a>(&'a u32); fn in_let() { diff --git a/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_struct.stderr b/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_struct.stderr index b5f2cb8e321a..3f01638d8475 100644 --- a/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_struct.stderr +++ b/src/test/ui/nll/user-annotations/pattern_substs_on_tuple_struct.stderr @@ -1,5 +1,5 @@ error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_tuple_struct.rs:7:19 + --> $DIR/pattern_substs_on_tuple_struct.rs:5:19 | LL | let foo = Foo(&y); | ^^ borrowed value does not live long enough @@ -10,7 +10,7 @@ LL | } | - `y` dropped here while still borrowed error[E0597]: `y` does not live long enough - --> $DIR/pattern_substs_on_tuple_struct.rs:14:19 + --> $DIR/pattern_substs_on_tuple_struct.rs:12:19 | LL | let foo = Foo(&y); | ^^ borrowed value does not live long enough diff --git a/src/test/ui/nll/user-annotations/promoted-annotation.rs b/src/test/ui/nll/user-annotations/promoted-annotation.rs index fa2d2fb81183..b92f8bfd23b2 100644 --- a/src/test/ui/nll/user-annotations/promoted-annotation.rs +++ b/src/test/ui/nll/user-annotations/promoted-annotation.rs @@ -1,7 +1,5 @@ // Test that type annotations are checked in promoted constants correctly. -#![feature(nll)] - fn foo<'a>() { let x = 0; let f = &drop::<&'a i32>; diff --git a/src/test/ui/nll/user-annotations/promoted-annotation.stderr b/src/test/ui/nll/user-annotations/promoted-annotation.stderr index d8b01f22145d..cb99a6a369d0 100644 --- a/src/test/ui/nll/user-annotations/promoted-annotation.stderr +++ b/src/test/ui/nll/user-annotations/promoted-annotation.stderr @@ -1,5 +1,5 @@ error[E0597]: `x` does not live long enough - --> $DIR/promoted-annotation.rs:8:7 + --> $DIR/promoted-annotation.rs:6:7 | LL | fn foo<'a>() { | -- lifetime `'a` defined here diff --git a/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.rs b/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.rs index 362fe51c3ea3..101b5cfabb3d 100644 --- a/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.rs +++ b/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.rs @@ -1,5 +1,4 @@ #![allow(warnings)] -#![feature(nll)] #![feature(type_ascription)] fn main() { diff --git a/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.stderr b/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.stderr index 93dbf7cb1b31..133bbef52311 100644 --- a/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.stderr +++ b/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.stderr @@ -1,5 +1,5 @@ error[E0597]: `x` does not live long enough - --> $DIR/type_ascription_static_lifetime.rs:7:19 + --> $DIR/type_ascription_static_lifetime.rs:6:19 | LL | let y: &u32 = &x: &'static u32; | ^^-------------- diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs index 2f3c094ff395..7b499af632ec 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs @@ -4,7 +4,6 @@ // compile-pass -#![feature(nll)] #![feature(bind_by_move_pattern_guards)] use std::sync::mpsc::channel; diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs index 9a9d11ce1b13..aca6aa5f0f86 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs @@ -1,4 +1,3 @@ -#![feature(nll)] #![feature(bind_by_move_pattern_guards)] // compile-pass diff --git a/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs b/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs index 4faede353059..1c1230346a56 100644 --- a/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs +++ b/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - #[derive(Clone)] enum Either { One(X), diff --git a/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.stderr b/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.stderr index b1aaab6a7544..f8e043fbfdfd 100644 --- a/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.stderr +++ b/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:41:27 + --> $DIR/duplicate-suggestions.rs:39:27 | LL | let &(X(_t), X(_u)) = &(x.clone(), x.clone()); | --------------- ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -9,13 +9,13 @@ LL | let &(X(_t), X(_u)) = &(x.clone(), x.clone()); | help: consider removing the `&`: `(X(_t), X(_u))` | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:41:13 + --> $DIR/duplicate-suggestions.rs:39:13 | LL | let &(X(_t), X(_u)) = &(x.clone(), x.clone()); | ^^ ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:45:50 + --> $DIR/duplicate-suggestions.rs:43:50 | LL | if let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { } | ----------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -25,13 +25,13 @@ LL | if let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { | help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))` | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:45:26 + --> $DIR/duplicate-suggestions.rs:43:26 | LL | if let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { } | ^^ ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:49:53 + --> $DIR/duplicate-suggestions.rs:47:53 | LL | while let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { } | ----------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -41,13 +41,13 @@ LL | while let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) | help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))` | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:49:29 + --> $DIR/duplicate-suggestions.rs:47:29 | LL | while let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { } | ^^ ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:53:11 + --> $DIR/duplicate-suggestions.rs:51:11 | LL | match &(e.clone(), e.clone()) { | ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -61,7 +61,7 @@ LL | &(Either::Two(_t), Either::One(_u)) => (), | -- ...and here -- ...and here | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:55:23 + --> $DIR/duplicate-suggestions.rs:53:23 | LL | &(Either::One(_t), Either::Two(_u)) => (), | ^^ ^^ @@ -78,7 +78,7 @@ LL | (Either::Two(_t), Either::One(_u)) => (), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:63:11 + --> $DIR/duplicate-suggestions.rs:61:11 | LL | match &(e.clone(), e.clone()) { | ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -91,13 +91,13 @@ LL | &(Either::One(_t), Either::Two(_u)) | help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))` | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:65:23 + --> $DIR/duplicate-suggestions.rs:63:23 | LL | &(Either::One(_t), Either::Two(_u)) | ^^ ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:72:11 + --> $DIR/duplicate-suggestions.rs:70:11 | LL | match &(e.clone(), e.clone()) { | ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -110,13 +110,13 @@ LL | &(Either::One(_t), Either::Two(_u)) => (), | help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))` | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:74:23 + --> $DIR/duplicate-suggestions.rs:72:23 | LL | &(Either::One(_t), Either::Two(_u)) => (), | ^^ ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:80:11 + --> $DIR/duplicate-suggestions.rs:78:11 | LL | match &(e.clone(), e.clone()) { | ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -129,13 +129,13 @@ LL | &(Either::One(_t), Either::Two(_u)) => (), | help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))` | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:82:23 + --> $DIR/duplicate-suggestions.rs:80:23 | LL | &(Either::One(_t), Either::Two(_u)) => (), | ^^ ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:93:31 + --> $DIR/duplicate-suggestions.rs:91:31 | LL | let &mut (X(_t), X(_u)) = &mut (xm.clone(), xm.clone()); | ------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -145,13 +145,13 @@ LL | let &mut (X(_t), X(_u)) = &mut (xm.clone(), xm.clone()); | help: consider removing the `&mut`: `(X(_t), X(_u))` | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:93:17 + --> $DIR/duplicate-suggestions.rs:91:17 | LL | let &mut (X(_t), X(_u)) = &mut (xm.clone(), xm.clone()); | ^^ ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:97:54 + --> $DIR/duplicate-suggestions.rs:95:54 | LL | if let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { } | --------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -161,13 +161,13 @@ LL | if let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.c | help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))` | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:97:30 + --> $DIR/duplicate-suggestions.rs:95:30 | LL | if let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { } | ^^ ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:101:57 + --> $DIR/duplicate-suggestions.rs:99:57 | LL | while let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { } | --------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -177,13 +177,13 @@ LL | while let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), e | help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))` | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:101:33 + --> $DIR/duplicate-suggestions.rs:99:33 | LL | while let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { } | ^^ ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:105:11 + --> $DIR/duplicate-suggestions.rs:103:11 | LL | match &mut (em.clone(), em.clone()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -197,7 +197,7 @@ LL | &mut (Either::Two(_t), Either::One(_u)) => (), | -- ...and here -- ...and here | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:107:27 + --> $DIR/duplicate-suggestions.rs:105:27 | LL | &mut (Either::One(_t), Either::Two(_u)) => (), | ^^ ^^ @@ -214,7 +214,7 @@ LL | (Either::Two(_t), Either::One(_u)) => (), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:115:11 + --> $DIR/duplicate-suggestions.rs:113:11 | LL | match &mut (em.clone(), em.clone()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -227,13 +227,13 @@ LL | &mut (Either::One(_t), Either::Two(_u)) | help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))` | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:117:27 + --> $DIR/duplicate-suggestions.rs:115:27 | LL | &mut (Either::One(_t), Either::Two(_u)) | ^^ ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:124:11 + --> $DIR/duplicate-suggestions.rs:122:11 | LL | match &mut (em.clone(), em.clone()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -246,13 +246,13 @@ LL | &mut (Either::One(_t), Either::Two(_u)) => (), | help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))` | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:126:27 + --> $DIR/duplicate-suggestions.rs:124:27 | LL | &mut (Either::One(_t), Either::Two(_u)) => (), | ^^ ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:132:11 + --> $DIR/duplicate-suggestions.rs:130:11 | LL | match &mut (em.clone(), em.clone()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -265,13 +265,13 @@ LL | &mut (Either::One(_t), Either::Two(_u)) => (), | help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))` | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:134:27 + --> $DIR/duplicate-suggestions.rs:132:27 | LL | &mut (Either::One(_t), Either::Two(_u)) => (), | ^^ ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:140:11 + --> $DIR/duplicate-suggestions.rs:138:11 | LL | match &mut (em.clone(), em.clone()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -284,13 +284,13 @@ LL | &mut (Either::One(_t), Either::Two(_u)) => (), | help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))` | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:142:27 + --> $DIR/duplicate-suggestions.rs:140:27 | LL | &mut (Either::One(_t), Either::Two(_u)) => (), | ^^ ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:88:11 + --> $DIR/duplicate-suggestions.rs:86:11 | LL | fn f5(&(X(_t), X(_u)): &(X, X)) { } | ^^^^--^^^^^--^^ @@ -301,13 +301,13 @@ LL | fn f5(&(X(_t), X(_u)): &(X, X)) { } | help: consider removing the `&`: `(X(_t), X(_u))` | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:88:15 + --> $DIR/duplicate-suggestions.rs:86:15 | LL | fn f5(&(X(_t), X(_u)): &(X, X)) { } | ^^ ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/duplicate-suggestions.rs:148:11 + --> $DIR/duplicate-suggestions.rs:146:11 | LL | fn f6(&mut (X(_t), X(_u)): &mut (X, X)) { } | ^^^^^^^^--^^^^^--^^ @@ -318,7 +318,7 @@ LL | fn f6(&mut (X(_t), X(_u)): &mut (X, X)) { } | help: consider removing the `&mut`: `(X(_t), X(_u))` | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/duplicate-suggestions.rs:148:19 + --> $DIR/duplicate-suggestions.rs:146:19 | LL | fn f6(&mut (X(_t), X(_u)): &mut (X, X)) { } | ^^ ^^ diff --git a/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.rs b/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.rs index 90a9fe4e7d06..6e3879a4155b 100644 --- a/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.rs +++ b/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - #[derive(Clone)] enum Either { One(X), diff --git a/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.stderr b/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.stderr index f1d515e932c6..74f3a63be57d 100644 --- a/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.stderr +++ b/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:30:21 + --> $DIR/move-into-closure.rs:28:21 | LL | let x = X(Y); | - captured outer variable @@ -12,13 +12,13 @@ LL | let X(_t) = x; | data moved here | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:30:15 + --> $DIR/move-into-closure.rs:28:15 | LL | let X(_t) = x; | ^^ error[E0507]: cannot move out of captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:34:34 + --> $DIR/move-into-closure.rs:32:34 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -31,13 +31,13 @@ LL | if let Either::One(_t) = e { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:34:28 + --> $DIR/move-into-closure.rs:32:28 | LL | if let Either::One(_t) = e { } | ^^ error[E0507]: cannot move out of captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:38:37 + --> $DIR/move-into-closure.rs:36:37 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -50,13 +50,13 @@ LL | while let Either::One(_t) = e { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:38:31 + --> $DIR/move-into-closure.rs:36:31 | LL | while let Either::One(_t) = e { } | ^^ error[E0507]: cannot move out of captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:42:15 + --> $DIR/move-into-closure.rs:40:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -71,13 +71,13 @@ LL | Either::One(_t) | -- data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:46:25 + --> $DIR/move-into-closure.rs:44:25 | LL | Either::One(_t) | ^^ error[E0507]: cannot move out of captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:49:15 + --> $DIR/move-into-closure.rs:47:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -92,13 +92,13 @@ LL | Either::One(_t) => (), | -- data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:53:25 + --> $DIR/move-into-closure.rs:51:25 | LL | Either::One(_t) => (), | ^^ error[E0507]: cannot move out of captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:58:25 + --> $DIR/move-into-closure.rs:56:25 | LL | let x = X(Y); | - captured outer variable @@ -111,13 +111,13 @@ LL | let X(mut _t) = x; | data moved here | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:58:15 + --> $DIR/move-into-closure.rs:56:15 | LL | let X(mut _t) = x; | ^^^^^^ error[E0507]: cannot move out of captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:62:38 + --> $DIR/move-into-closure.rs:60:38 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -130,13 +130,13 @@ LL | if let Either::One(mut _t) = em { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:62:28 + --> $DIR/move-into-closure.rs:60:28 | LL | if let Either::One(mut _t) = em { } | ^^^^^^ error[E0507]: cannot move out of captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:66:41 + --> $DIR/move-into-closure.rs:64:41 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -149,13 +149,13 @@ LL | while let Either::One(mut _t) = em { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:66:31 + --> $DIR/move-into-closure.rs:64:31 | LL | while let Either::One(mut _t) = em { } | ^^^^^^ error[E0507]: cannot move out of captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:70:15 + --> $DIR/move-into-closure.rs:68:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -170,13 +170,13 @@ LL | Either::One(mut _t) | ------ data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:74:25 + --> $DIR/move-into-closure.rs:72:25 | LL | Either::One(mut _t) | ^^^^^^ error[E0507]: cannot move out of captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:77:15 + --> $DIR/move-into-closure.rs:75:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -191,13 +191,13 @@ LL | Either::One(mut _t) => (), | ------ data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:81:25 + --> $DIR/move-into-closure.rs:79:25 | LL | Either::One(mut _t) => (), | ^^^^^^ error[E0507]: cannot move out of captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:97:21 + --> $DIR/move-into-closure.rs:95:21 | LL | let x = X(Y); | - captured outer variable @@ -210,13 +210,13 @@ LL | let X(_t) = x; | data moved here | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:97:15 + --> $DIR/move-into-closure.rs:95:15 | LL | let X(_t) = x; | ^^ error[E0507]: cannot move out of captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:101:34 + --> $DIR/move-into-closure.rs:99:34 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -229,13 +229,13 @@ LL | if let Either::One(_t) = e { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:101:28 + --> $DIR/move-into-closure.rs:99:28 | LL | if let Either::One(_t) = e { } | ^^ error[E0507]: cannot move out of captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:105:37 + --> $DIR/move-into-closure.rs:103:37 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -248,13 +248,13 @@ LL | while let Either::One(_t) = e { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:105:31 + --> $DIR/move-into-closure.rs:103:31 | LL | while let Either::One(_t) = e { } | ^^ error[E0507]: cannot move out of captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:109:15 + --> $DIR/move-into-closure.rs:107:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -269,13 +269,13 @@ LL | Either::One(_t) | -- data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:113:25 + --> $DIR/move-into-closure.rs:111:25 | LL | Either::One(_t) | ^^ error[E0507]: cannot move out of captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:116:15 + --> $DIR/move-into-closure.rs:114:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -290,13 +290,13 @@ LL | Either::One(_t) => (), | -- data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:120:25 + --> $DIR/move-into-closure.rs:118:25 | LL | Either::One(_t) => (), | ^^ error[E0507]: cannot move out of captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:125:25 + --> $DIR/move-into-closure.rs:123:25 | LL | let x = X(Y); | - captured outer variable @@ -309,13 +309,13 @@ LL | let X(mut _t) = x; | data moved here | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:125:15 + --> $DIR/move-into-closure.rs:123:15 | LL | let X(mut _t) = x; | ^^^^^^ error[E0507]: cannot move out of captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:129:38 + --> $DIR/move-into-closure.rs:127:38 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -328,13 +328,13 @@ LL | if let Either::One(mut _t) = em { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:129:28 + --> $DIR/move-into-closure.rs:127:28 | LL | if let Either::One(mut _t) = em { } | ^^^^^^ error[E0507]: cannot move out of captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:133:41 + --> $DIR/move-into-closure.rs:131:41 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -347,13 +347,13 @@ LL | while let Either::One(mut _t) = em { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:133:31 + --> $DIR/move-into-closure.rs:131:31 | LL | while let Either::One(mut _t) = em { } | ^^^^^^ error[E0507]: cannot move out of captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:137:15 + --> $DIR/move-into-closure.rs:135:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -368,13 +368,13 @@ LL | Either::One(mut _t) | ------ data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:141:25 + --> $DIR/move-into-closure.rs:139:25 | LL | Either::One(mut _t) | ^^^^^^ error[E0507]: cannot move out of captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:144:15 + --> $DIR/move-into-closure.rs:142:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -389,13 +389,13 @@ LL | Either::One(mut _t) => (), | ------ data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:148:25 + --> $DIR/move-into-closure.rs:146:25 | LL | Either::One(mut _t) => (), | ^^^^^^ error[E0507]: cannot move out of captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:152:15 + --> $DIR/move-into-closure.rs:150:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -410,7 +410,7 @@ LL | Either::One(mut _t) => (), | ------ data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/move-into-closure.rs:156:25 + --> $DIR/move-into-closure.rs:154:25 | LL | Either::One(mut _t) => (), | ^^^^^^ diff --git a/src/test/ui/suggestions/dont-suggest-ref/simple.rs b/src/test/ui/suggestions/dont-suggest-ref/simple.rs index 58aab85ac267..31ab1a6639ac 100644 --- a/src/test/ui/suggestions/dont-suggest-ref/simple.rs +++ b/src/test/ui/suggestions/dont-suggest-ref/simple.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - #[derive(Clone)] enum Either { One(X), diff --git a/src/test/ui/suggestions/dont-suggest-ref/simple.stderr b/src/test/ui/suggestions/dont-suggest-ref/simple.stderr index 6a8b17ca8704..7f2ba4da714d 100644 --- a/src/test/ui/suggestions/dont-suggest-ref/simple.stderr +++ b/src/test/ui/suggestions/dont-suggest-ref/simple.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:40:17 + --> $DIR/simple.rs:38:17 | LL | let X(_t) = *s; | -- ^^ @@ -9,13 +9,13 @@ LL | let X(_t) = *s; | data moved here | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/simple.rs:40:11 + --> $DIR/simple.rs:38:11 | LL | let X(_t) = *s; | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:44:30 + --> $DIR/simple.rs:42:30 | LL | if let Either::One(_t) = *r { } | -- ^^ @@ -25,13 +25,13 @@ LL | if let Either::One(_t) = *r { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:44:24 + --> $DIR/simple.rs:42:24 | LL | if let Either::One(_t) = *r { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:48:33 + --> $DIR/simple.rs:46:33 | LL | while let Either::One(_t) = *r { } | -- ^^ @@ -41,13 +41,13 @@ LL | while let Either::One(_t) = *r { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:48:27 + --> $DIR/simple.rs:46:27 | LL | while let Either::One(_t) = *r { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:52:11 + --> $DIR/simple.rs:50:11 | LL | match *r { | ^^ @@ -59,13 +59,13 @@ LL | Either::One(_t) | -- data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:56:21 + --> $DIR/simple.rs:54:21 | LL | Either::One(_t) | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:59:11 + --> $DIR/simple.rs:57:11 | LL | match *r { | ^^ @@ -77,13 +77,13 @@ LL | Either::One(_t) => (), | -- data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:63:21 + --> $DIR/simple.rs:61:21 | LL | Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:68:17 + --> $DIR/simple.rs:66:17 | LL | let X(_t) = *sm; | -- ^^^ @@ -93,13 +93,13 @@ LL | let X(_t) = *sm; | data moved here | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/simple.rs:68:11 + --> $DIR/simple.rs:66:11 | LL | let X(_t) = *sm; | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:72:30 + --> $DIR/simple.rs:70:30 | LL | if let Either::One(_t) = *rm { } | -- ^^^ @@ -109,13 +109,13 @@ LL | if let Either::One(_t) = *rm { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:72:24 + --> $DIR/simple.rs:70:24 | LL | if let Either::One(_t) = *rm { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:76:33 + --> $DIR/simple.rs:74:33 | LL | while let Either::One(_t) = *rm { } | -- ^^^ @@ -125,13 +125,13 @@ LL | while let Either::One(_t) = *rm { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:76:27 + --> $DIR/simple.rs:74:27 | LL | while let Either::One(_t) = *rm { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:80:11 + --> $DIR/simple.rs:78:11 | LL | match *rm { | ^^^ @@ -143,13 +143,13 @@ LL | Either::One(_t) | -- data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:84:21 + --> $DIR/simple.rs:82:21 | LL | Either::One(_t) | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:87:11 + --> $DIR/simple.rs:85:11 | LL | match *rm { | ^^^ @@ -161,13 +161,13 @@ LL | Either::One(_t) => (), | -- data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:91:21 + --> $DIR/simple.rs:89:21 | LL | Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:95:11 + --> $DIR/simple.rs:93:11 | LL | match *rm { | ^^^ @@ -179,13 +179,13 @@ LL | Either::One(_t) => (), | -- data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:99:21 + --> $DIR/simple.rs:97:21 | LL | Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:104:17 + --> $DIR/simple.rs:102:17 | LL | let X(_t) = vs[0]; | -- ^^^^^ @@ -195,13 +195,13 @@ LL | let X(_t) = vs[0]; | data moved here | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/simple.rs:104:11 + --> $DIR/simple.rs:102:11 | LL | let X(_t) = vs[0]; | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:108:30 + --> $DIR/simple.rs:106:30 | LL | if let Either::One(_t) = vr[0] { } | -- ^^^^^ @@ -211,13 +211,13 @@ LL | if let Either::One(_t) = vr[0] { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:108:24 + --> $DIR/simple.rs:106:24 | LL | if let Either::One(_t) = vr[0] { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:112:33 + --> $DIR/simple.rs:110:33 | LL | while let Either::One(_t) = vr[0] { } | -- ^^^^^ @@ -227,13 +227,13 @@ LL | while let Either::One(_t) = vr[0] { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:112:27 + --> $DIR/simple.rs:110:27 | LL | while let Either::One(_t) = vr[0] { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:116:11 + --> $DIR/simple.rs:114:11 | LL | match vr[0] { | ^^^^^ @@ -245,13 +245,13 @@ LL | Either::One(_t) | -- data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:120:21 + --> $DIR/simple.rs:118:21 | LL | Either::One(_t) | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:123:11 + --> $DIR/simple.rs:121:11 | LL | match vr[0] { | ^^^^^ @@ -263,13 +263,13 @@ LL | Either::One(_t) => (), | -- data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:127:21 + --> $DIR/simple.rs:125:21 | LL | Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:132:17 + --> $DIR/simple.rs:130:17 | LL | let X(_t) = vsm[0]; | -- ^^^^^^ @@ -279,13 +279,13 @@ LL | let X(_t) = vsm[0]; | data moved here | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/simple.rs:132:11 + --> $DIR/simple.rs:130:11 | LL | let X(_t) = vsm[0]; | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:136:30 + --> $DIR/simple.rs:134:30 | LL | if let Either::One(_t) = vrm[0] { } | -- ^^^^^^ @@ -295,13 +295,13 @@ LL | if let Either::One(_t) = vrm[0] { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:136:24 + --> $DIR/simple.rs:134:24 | LL | if let Either::One(_t) = vrm[0] { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:140:33 + --> $DIR/simple.rs:138:33 | LL | while let Either::One(_t) = vrm[0] { } | -- ^^^^^^ @@ -311,13 +311,13 @@ LL | while let Either::One(_t) = vrm[0] { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:140:27 + --> $DIR/simple.rs:138:27 | LL | while let Either::One(_t) = vrm[0] { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:144:11 + --> $DIR/simple.rs:142:11 | LL | match vrm[0] { | ^^^^^^ @@ -329,13 +329,13 @@ LL | Either::One(_t) | -- data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:148:21 + --> $DIR/simple.rs:146:21 | LL | Either::One(_t) | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:151:11 + --> $DIR/simple.rs:149:11 | LL | match vrm[0] { | ^^^^^^ @@ -347,13 +347,13 @@ LL | Either::One(_t) => (), | -- data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:155:21 + --> $DIR/simple.rs:153:21 | LL | Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:159:11 + --> $DIR/simple.rs:157:11 | LL | match vrm[0] { | ^^^^^^ @@ -365,13 +365,13 @@ LL | Either::One(_t) => (), | -- data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:163:21 + --> $DIR/simple.rs:161:21 | LL | Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:170:18 + --> $DIR/simple.rs:168:18 | LL | let &X(_t) = s; | ------ ^ cannot move out of borrowed content @@ -380,13 +380,13 @@ LL | let &X(_t) = s; | help: consider removing the `&`: `X(_t)` | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/simple.rs:170:12 + --> $DIR/simple.rs:168:12 | LL | let &X(_t) = s; | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:174:31 + --> $DIR/simple.rs:172:31 | LL | if let &Either::One(_t) = r { } | ---------------- ^ cannot move out of borrowed content @@ -395,13 +395,13 @@ LL | if let &Either::One(_t) = r { } | help: consider removing the `&`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:174:25 + --> $DIR/simple.rs:172:25 | LL | if let &Either::One(_t) = r { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:178:34 + --> $DIR/simple.rs:176:34 | LL | while let &Either::One(_t) = r { } | ---------------- ^ cannot move out of borrowed content @@ -410,13 +410,13 @@ LL | while let &Either::One(_t) = r { } | help: consider removing the `&`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:178:28 + --> $DIR/simple.rs:176:28 | LL | while let &Either::One(_t) = r { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:182:11 + --> $DIR/simple.rs:180:11 | LL | match r { | ^ cannot move out of borrowed content @@ -428,13 +428,13 @@ LL | &Either::One(_t) | help: consider removing the `&`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:184:22 + --> $DIR/simple.rs:182:22 | LL | &Either::One(_t) | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:190:11 + --> $DIR/simple.rs:188:11 | LL | match r { | ^ cannot move out of borrowed content @@ -446,13 +446,13 @@ LL | &Either::One(_t) => (), | help: consider removing the `&`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:192:22 + --> $DIR/simple.rs:190:22 | LL | &Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:197:11 + --> $DIR/simple.rs:195:11 | LL | match r { | ^ cannot move out of borrowed content @@ -464,13 +464,13 @@ LL | &Either::One(_t) => (), | help: consider removing the `&`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:199:22 + --> $DIR/simple.rs:197:22 | LL | &Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:209:22 + --> $DIR/simple.rs:207:22 | LL | let &mut X(_t) = sm; | ---------- ^^ cannot move out of borrowed content @@ -479,13 +479,13 @@ LL | let &mut X(_t) = sm; | help: consider removing the `&mut`: `X(_t)` | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/simple.rs:209:16 + --> $DIR/simple.rs:207:16 | LL | let &mut X(_t) = sm; | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:213:35 + --> $DIR/simple.rs:211:35 | LL | if let &mut Either::One(_t) = rm { } | -------------------- ^^ cannot move out of borrowed content @@ -494,13 +494,13 @@ LL | if let &mut Either::One(_t) = rm { } | help: consider removing the `&mut`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:213:29 + --> $DIR/simple.rs:211:29 | LL | if let &mut Either::One(_t) = rm { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:217:38 + --> $DIR/simple.rs:215:38 | LL | while let &mut Either::One(_t) = rm { } | -------------------- ^^ cannot move out of borrowed content @@ -509,13 +509,13 @@ LL | while let &mut Either::One(_t) = rm { } | help: consider removing the `&mut`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:217:32 + --> $DIR/simple.rs:215:32 | LL | while let &mut Either::One(_t) = rm { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:221:11 + --> $DIR/simple.rs:219:11 | LL | match rm { | ^^ cannot move out of borrowed content @@ -527,7 +527,7 @@ LL | &mut Either::Two(_t) => (), | -- ...and here | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/simple.rs:223:26 + --> $DIR/simple.rs:221:26 | LL | &mut Either::One(_t) => (), | ^^ @@ -544,7 +544,7 @@ LL | Either::Two(_t) => (), | ^^^^^^^^^^^^^^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:230:11 + --> $DIR/simple.rs:228:11 | LL | match rm { | ^^ cannot move out of borrowed content @@ -556,13 +556,13 @@ LL | &mut Either::One(_t) => (), | help: consider removing the `&mut`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:232:26 + --> $DIR/simple.rs:230:26 | LL | &mut Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:237:11 + --> $DIR/simple.rs:235:11 | LL | match rm { | ^^ cannot move out of borrowed content @@ -574,13 +574,13 @@ LL | &mut Either::One(_t) => (), | help: consider removing the `&mut`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:239:26 + --> $DIR/simple.rs:237:26 | LL | &mut Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:244:11 + --> $DIR/simple.rs:242:11 | LL | match rm { | ^^ cannot move out of borrowed content @@ -592,13 +592,13 @@ LL | &mut Either::One(_t) => (), | help: consider removing the `&mut`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:246:26 + --> $DIR/simple.rs:244:26 | LL | &mut Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:260:21 + --> $DIR/simple.rs:258:21 | LL | let (&X(_t),) = (&x.clone(),); | -- ^^^^^^^^^^^^^ cannot move out of borrowed content @@ -606,13 +606,13 @@ LL | let (&X(_t),) = (&x.clone(),); | data moved here | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/simple.rs:260:13 + --> $DIR/simple.rs:258:13 | LL | let (&X(_t),) = (&x.clone(),); | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:262:34 + --> $DIR/simple.rs:260:34 | LL | if let (&Either::One(_t),) = (&e.clone(),) { } | -- ^^^^^^^^^^^^^ cannot move out of borrowed content @@ -620,13 +620,13 @@ LL | if let (&Either::One(_t),) = (&e.clone(),) { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:262:26 + --> $DIR/simple.rs:260:26 | LL | if let (&Either::One(_t),) = (&e.clone(),) { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:264:37 + --> $DIR/simple.rs:262:37 | LL | while let (&Either::One(_t),) = (&e.clone(),) { } | -- ^^^^^^^^^^^^^ cannot move out of borrowed content @@ -634,13 +634,13 @@ LL | while let (&Either::One(_t),) = (&e.clone(),) { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:264:29 + --> $DIR/simple.rs:262:29 | LL | while let (&Either::One(_t),) = (&e.clone(),) { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:266:11 + --> $DIR/simple.rs:264:11 | LL | match (&e.clone(),) { | ^^^^^^^^^^^^^ cannot move out of borrowed content @@ -649,13 +649,13 @@ LL | (&Either::One(_t),) | -- data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:268:23 + --> $DIR/simple.rs:266:23 | LL | (&Either::One(_t),) | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:274:25 + --> $DIR/simple.rs:272:25 | LL | let (&mut X(_t),) = (&mut xm.clone(),); | -- ^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -663,13 +663,13 @@ LL | let (&mut X(_t),) = (&mut xm.clone(),); | data moved here | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/simple.rs:274:17 + --> $DIR/simple.rs:272:17 | LL | let (&mut X(_t),) = (&mut xm.clone(),); | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:276:38 + --> $DIR/simple.rs:274:38 | LL | if let (&mut Either::One(_t),) = (&mut em.clone(),) { } | -- ^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -677,13 +677,13 @@ LL | if let (&mut Either::One(_t),) = (&mut em.clone(),) { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:276:30 + --> $DIR/simple.rs:274:30 | LL | if let (&mut Either::One(_t),) = (&mut em.clone(),) { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:278:41 + --> $DIR/simple.rs:276:41 | LL | while let (&mut Either::One(_t),) = (&mut em.clone(),) { } | -- ^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -691,13 +691,13 @@ LL | while let (&mut Either::One(_t),) = (&mut em.clone(),) { } | data moved here | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:278:33 + --> $DIR/simple.rs:276:33 | LL | while let (&mut Either::One(_t),) = (&mut em.clone(),) { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:280:11 + --> $DIR/simple.rs:278:11 | LL | match (&mut em.clone(),) { | ^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content @@ -708,7 +708,7 @@ LL | (&mut Either::Two(_t),) => (), | -- ...and here | note: move occurs because these variables have types that don't implement the `Copy` trait - --> $DIR/simple.rs:282:27 + --> $DIR/simple.rs:280:27 | LL | (&mut Either::One(_t),) => (), | ^^ @@ -716,7 +716,7 @@ LL | (&mut Either::Two(_t),) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:290:18 + --> $DIR/simple.rs:288:18 | LL | let &X(_t) = &x; | ------ ^^ cannot move out of borrowed content @@ -725,13 +725,13 @@ LL | let &X(_t) = &x; | help: consider removing the `&`: `X(_t)` | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/simple.rs:290:12 + --> $DIR/simple.rs:288:12 | LL | let &X(_t) = &x; | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:294:31 + --> $DIR/simple.rs:292:31 | LL | if let &Either::One(_t) = &e { } | ---------------- ^^ cannot move out of borrowed content @@ -740,13 +740,13 @@ LL | if let &Either::One(_t) = &e { } | help: consider removing the `&`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:294:25 + --> $DIR/simple.rs:292:25 | LL | if let &Either::One(_t) = &e { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:298:34 + --> $DIR/simple.rs:296:34 | LL | while let &Either::One(_t) = &e { } | ---------------- ^^ cannot move out of borrowed content @@ -755,13 +755,13 @@ LL | while let &Either::One(_t) = &e { } | help: consider removing the `&`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:298:28 + --> $DIR/simple.rs:296:28 | LL | while let &Either::One(_t) = &e { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:302:11 + --> $DIR/simple.rs:300:11 | LL | match &e { | ^^ cannot move out of borrowed content @@ -773,13 +773,13 @@ LL | &Either::One(_t) | help: consider removing the `&`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:304:22 + --> $DIR/simple.rs:302:22 | LL | &Either::One(_t) | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:310:11 + --> $DIR/simple.rs:308:11 | LL | match &e { | ^^ cannot move out of borrowed content @@ -791,13 +791,13 @@ LL | &Either::One(_t) => (), | help: consider removing the `&`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:312:22 + --> $DIR/simple.rs:310:22 | LL | &Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:317:11 + --> $DIR/simple.rs:315:11 | LL | match &e { | ^^ cannot move out of borrowed content @@ -809,13 +809,13 @@ LL | &Either::One(_t) => (), | help: consider removing the `&`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:319:22 + --> $DIR/simple.rs:317:22 | LL | &Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:325:22 + --> $DIR/simple.rs:323:22 | LL | let &mut X(_t) = &mut xm; | ---------- ^^^^^^^ cannot move out of borrowed content @@ -824,13 +824,13 @@ LL | let &mut X(_t) = &mut xm; | help: consider removing the `&mut`: `X(_t)` | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/simple.rs:325:16 + --> $DIR/simple.rs:323:16 | LL | let &mut X(_t) = &mut xm; | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:329:35 + --> $DIR/simple.rs:327:35 | LL | if let &mut Either::One(_t) = &mut em { } | -------------------- ^^^^^^^ cannot move out of borrowed content @@ -839,13 +839,13 @@ LL | if let &mut Either::One(_t) = &mut em { } | help: consider removing the `&mut`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:329:29 + --> $DIR/simple.rs:327:29 | LL | if let &mut Either::One(_t) = &mut em { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:333:38 + --> $DIR/simple.rs:331:38 | LL | while let &mut Either::One(_t) = &mut em { } | -------------------- ^^^^^^^ cannot move out of borrowed content @@ -854,13 +854,13 @@ LL | while let &mut Either::One(_t) = &mut em { } | help: consider removing the `&mut`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:333:32 + --> $DIR/simple.rs:331:32 | LL | while let &mut Either::One(_t) = &mut em { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:337:11 + --> $DIR/simple.rs:335:11 | LL | match &mut em { | ^^^^^^^ cannot move out of borrowed content @@ -872,13 +872,13 @@ LL | &mut Either::One(_t) | help: consider removing the `&mut`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:339:26 + --> $DIR/simple.rs:337:26 | LL | &mut Either::One(_t) | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:345:11 + --> $DIR/simple.rs:343:11 | LL | match &mut em { | ^^^^^^^ cannot move out of borrowed content @@ -890,13 +890,13 @@ LL | &mut Either::One(_t) => (), | help: consider removing the `&mut`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:347:26 + --> $DIR/simple.rs:345:26 | LL | &mut Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:352:11 + --> $DIR/simple.rs:350:11 | LL | match &mut em { | ^^^^^^^ cannot move out of borrowed content @@ -908,13 +908,13 @@ LL | &mut Either::One(_t) => (), | help: consider removing the `&mut`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:354:26 + --> $DIR/simple.rs:352:26 | LL | &mut Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:359:11 + --> $DIR/simple.rs:357:11 | LL | match &mut em { | ^^^^^^^ cannot move out of borrowed content @@ -926,13 +926,13 @@ LL | &mut Either::One(_t) => (), | help: consider removing the `&mut`: `Either::One(_t)` | note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait - --> $DIR/simple.rs:361:26 + --> $DIR/simple.rs:359:26 | LL | &mut Either::One(_t) => (), | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:204:11 + --> $DIR/simple.rs:202:11 | LL | fn f1(&X(_t): &X) { } | ^^^--^ @@ -942,13 +942,13 @@ LL | fn f1(&X(_t): &X) { } | help: consider removing the `&`: `X(_t)` | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/simple.rs:204:14 + --> $DIR/simple.rs:202:14 | LL | fn f1(&X(_t): &X) { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:251:11 + --> $DIR/simple.rs:249:11 | LL | fn f2(&mut X(_t): &mut X) { } | ^^^^^^^--^ @@ -958,13 +958,13 @@ LL | fn f2(&mut X(_t): &mut X) { } | help: consider removing the `&mut`: `X(_t)` | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/simple.rs:251:18 + --> $DIR/simple.rs:249:18 | LL | fn f2(&mut X(_t): &mut X) { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:271:11 + --> $DIR/simple.rs:269:11 | LL | fn f3((&X(_t),): (&X,)) { } | ^^^^--^^^ @@ -973,13 +973,13 @@ LL | fn f3((&X(_t),): (&X,)) { } | cannot move out of borrowed content | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/simple.rs:271:15 + --> $DIR/simple.rs:269:15 | LL | fn f3((&X(_t),): (&X,)) { } | ^^ error[E0507]: cannot move out of borrowed content - --> $DIR/simple.rs:285:11 + --> $DIR/simple.rs:283:11 | LL | fn f4((&mut X(_t),): (&mut X,)) { } | ^^^^^^^^--^^^ @@ -988,7 +988,7 @@ LL | fn f4((&mut X(_t),): (&mut X,)) { } | cannot move out of borrowed content | note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait - --> $DIR/simple.rs:285:19 + --> $DIR/simple.rs:283:19 | LL | fn f4((&mut X(_t),): (&mut X,)) { } | ^^ diff --git a/src/test/ui/suggestions/suggest-ref-mut.rs b/src/test/ui/suggestions/suggest-ref-mut.rs index b4a6fa39f905..d04113ffccc3 100644 --- a/src/test/ui/suggestions/suggest-ref-mut.rs +++ b/src/test/ui/suggestions/suggest-ref-mut.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - struct X(usize); impl X { diff --git a/src/test/ui/suggestions/suggest-ref-mut.stderr b/src/test/ui/suggestions/suggest-ref-mut.stderr index 3dd9fbc6f148..241436787571 100644 --- a/src/test/ui/suggestions/suggest-ref-mut.stderr +++ b/src/test/ui/suggestions/suggest-ref-mut.stderr @@ -1,5 +1,5 @@ error[E0594]: cannot assign to `self.0` which is behind a `&` reference - --> $DIR/suggest-ref-mut.rs:9:9 + --> $DIR/suggest-ref-mut.rs:7:9 | LL | fn zap(&self) { | ----- help: consider changing this to be a mutable reference: `&mut self` @@ -8,7 +8,7 @@ LL | self.0 = 32; | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written error[E0594]: cannot assign to `*foo` which is behind a `&` reference - --> $DIR/suggest-ref-mut.rs:18:5 + --> $DIR/suggest-ref-mut.rs:16:5 | LL | let ref foo = 16; | ------- help: consider changing this to be a mutable reference: `ref mut foo` @@ -17,7 +17,7 @@ LL | *foo = 32; | ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written error[E0594]: cannot assign to `*bar` which is behind a `&` reference - --> $DIR/suggest-ref-mut.rs:23:9 + --> $DIR/suggest-ref-mut.rs:21:9 | LL | if let Some(ref bar) = Some(16) { | ------- help: consider changing this to be a mutable reference: `ref mut bar` @@ -26,7 +26,7 @@ LL | *bar = 32; | ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written error[E0594]: cannot assign to `*quo` which is behind a `&` reference - --> $DIR/suggest-ref-mut.rs:27:22 + --> $DIR/suggest-ref-mut.rs:25:22 | LL | ref quo => { *quo = 32; }, | ------- ^^^^^^^^^ `quo` is a `&` reference, so the data it refers to cannot be written From 9a4f0abd7a385416acf9d93b9d77ea1fdf755f93 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 12 May 2019 18:51:40 +0100 Subject: [PATCH 113/239] Don't allow any ReScope in impl trait types This shouldn't be possible any more, but if it does happen, emit an error rather than maybe panicking later when NLL finds a the ReScope. Impl trait in bindings is sufficiently broken that I don't think this breaks anything that works for it. --- src/librustc/infer/opaque_types/mod.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index a8dca9062bd2..4351f94df2f1 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -611,10 +611,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx> ty::ReLateBound(..) | // ignore `'static`, as that can appear anywhere - ty::ReStatic | - - // ignore `ReScope`, which may appear in impl Trait in bindings. - ty::ReScope(..) => return r, + ty::ReStatic => return r, _ => { } } From e392db6cd424983fc7542fa9b35d30de89db439a Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 12 May 2019 14:16:50 -0700 Subject: [PATCH 114/239] Update rustc book CLI docs. --- src/doc/rustc/src/command-line-arguments.md | 165 ++++++++++++++++++-- src/librustc/session/config.rs | 3 +- 2 files changed, 156 insertions(+), 12 deletions(-) diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index dfb40284ef6c..bd7f6630ea2a 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -17,28 +17,147 @@ to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively. ## `-L`: add a directory to the library search path -When looking for external crates, a directory passed to this flag will be searched. +When looking for external crates or libraries, a directory passed to this flag +will be searched. + +The kind of search path can optionally be specified with the form `-L +KIND=PATH` where `KIND` may be one of: + +- `dependency` — Only search for transitive dependencies in this directory. +- `crate` — Only search for this crate's direct dependencies in this + directory. +- `native` — Only search for native libraries in this directory. +- `framework` — Only search for macOS frameworks in this directory. +- `all` — Search for all library kinds in this directory. This is the default + if `KIND` is not specified. ## `-l`: link the generated crate to a native library This flag allows you to specify linking to a specific native library when building a crate. +The kind of library can optionally be specified with the form `-l KIND=lib` +where `KIND` may be one of: + +- `dylib` — A native dynamic library. +- `static` — A native static library (such as a `.a` archive). +- `framework` — A macOS framework. + +The kind of library can be specified in a [`#[link]` +attribute][link-attribute]. If the kind is not specified in the `link` +attribute or on the command-line, it will link a dynamic library if available, +otherwise it will use a static library. If the kind is specified on the +command-line, it will override the kind specified in a `link` attribute. + +The name used in a `link` attribute may be overridden using the form `-l +ATTR_NAME:LINK_NAME` where `ATTR_NAME` is the name in the `link` attribute, +and `LINK_NAME` is the name of the actual library that will be linked. + +[link-attribute]: ../reference/items/external-blocks.html#the-link-attribute + ## `--crate-type`: a list of types of crates for the compiler to emit -This instructs `rustc` on which crate type to build. +This instructs `rustc` on which crate type to build. This flag accepts a +comma-separated list of values, and may be specified multiple times. The valid +crate types are: + +- `lib` — Generates a library kind preferred by the compiler, currently + defaults to `rlib`. +- `rlib` — A Rust static library. +- `staticlib` — A native static library. +- `dylib` — A Rust dynamic library. +- `cdylib` — A native dynamic library. +- `bin` — A runnable executable program. +- `proc-macro` — Generates a format suitable for a procedural macro library + that may be loaded by the compiler. + +The crate type may be specified with the [`crate_type` attribute][crate_type]. +The `--crate-type` command-line value will override the `crate_type` +attribute. + +More details may be found in the [linkage chapter] of the reference. + +[linkage chapter]: ../reference/linkage.html +[crate_type]: ../reference/linkage.html ## `--crate-name`: specify the name of the crate being built This informs `rustc` of the name of your crate. -## `--emit`: emit output other than a crate +## `--edition`: specify the edition to use -Instead of producing a crate, this flag can print out things like the assembly or LLVM-IR. +This flag takes a value of `2015` or `2018`. The default is `2015`. More +information about editions may be found in the [edition guide]. + +[edition guide]: ../edition-guide/introduction.html + +## `--emit`: specifies the types of output files to generate + +This flag controls the types of output files generated by the compiler. It +accepts a comma-separated list of values, and may be specified multiple times. +The valid emit kinds are: + +- `asm` — Generates a file with the crate's assembly code. The default output + filename is `CRATE_NAME.s`. +- `dep-info` — Generates a file with Makefile syntax that indicates all the + source files that were loaded to generate the crate. The default output + filename is `CRATE_NAME.d`. +- `link` — Generates the crates specified by `--crate-type`. The default + output filenames depend on the crate type and platform. This is the default + if `--emit` is not specified. +- `llvm-bc` — Generates a binary file containing the [LLVM bitcode]. The + default output filename is `CRATE_NAME.bc`. +- `llvm-ir` — Generates a file containing [LLVM IR]. The default output + filename is `CRATE_NAME.ll`. +- `metadata` — Generates a file containing metadata about the crate. The + default output filename is `CRATE_NAME.rmeta`. +- `mir` — Generates a file containing rustc's mid-level intermediate + representation. The default output filename is `CRATE_NAME.mir`. +- `obj` — Generates a native object file. The default output filename is + `CRATE_NAME.o`. + +The output filename can be set with the `-o` flag. A suffix may be added to +the filename with the `-C extra-filename` flag. The files are written to the +current directory unless the `--out-dir` flag is used. Each emission type may +also specify the output filename with the form `KIND=PATH`, which takes +precedence over the `-o` flag. + +[LLVM bitcode]: https://llvm.org/docs/BitCodeFormat.html +[LLVM IR]: https://llvm.org/docs/LangRef.html ## `--print`: print compiler information -This flag prints out various information about the compiler. +This flag prints out various information about the compiler. This flag may be +specified multiple times, and the information is printed in the order the +flags are specified. Specifying a `--print` flag will usually disable the +`--emit` step and will only print the requested information. The valid types +of print values are: + +- `crate-name` — The name of the crate. +- `file-names` — The names of the files created by the `link` emit kind. +- `sysroot` — Path to the sysroot. +- `cfg` — List of cfg values. See [conditional compilation] for more + information about cfg values. +- `target-list` — List of known targets. The target may be selected with the + `--target` flag. +- `target-cpus` — List of available CPU values for the current target. The + target CPU may be selected with the `-C target-cpu=val` flag. +- `target-features` — List of available target features for the current + target. Target features may be enabled with the `-C target-feature=val` + flag. +- `relocation-models` — List of relocation models. Relocation models may be + selected with the `-C relocation-model=val` flag. +- `code-models` — List of code models. Code models may be selected with the + `-C code-model=val` flag. +- `tls-models` — List of Thread Local Storage models supported. The model may + be selected with the `-Z tls-model=val` flag. +- `native-static-libs` — This may be used when creating a `staticlib` crate + type. If this is the only flag, it will perform a full compilation and + include a diagnostic note that indicates the linker flags to use when + linking the resulting static library. The note starts with the text + `native-static-libs:` to make it easier to fetch the output. + +[conditional compilation]: ../reference/conditional-compilation.html ## `-g`: include debug information @@ -54,7 +173,8 @@ This flag controls the output filename. ## `--out-dir`: directory to write the output in -The outputted crate will be written to this directory. +The outputted crate will be written to this directory. This flag is ignored if +the `-o` flag is used. ## `--explain`: provide a detailed explanation of an error message @@ -111,8 +231,9 @@ This flag, when combined with other flags, makes them produce extra output. ## `--extern`: specify where an external library is located -This flag allows you to pass the name and location of an external crate that will -be linked into the crate you're buildling. +This flag allows you to pass the name and location of an external crate that +will be linked into the crate you are building. This flag may be specified +multiple times. The format of the value should be `CRATENAME=PATH`. ## `--sysroot`: Override the system root @@ -121,8 +242,32 @@ distribution; this flag allows that to be overridden. ## `--error-format`: control how errors are produced -This flag lets you control the format of errors. +This flag lets you control the format of messages. Messages are printed to +stderr. The valid options are: + +- `human` — Human-readable output. This is the default. +- `json` — Structured JSON output. +- `short` — Short, one-line messages. ## `--color`: configure coloring of output -This flag lets you control color settings of the output. +This flag lets you control color settings of the output. The valid options +are: + +- `auto` — Use colors if output goes to a tty. This is the default. +- `always` — Always use colors. +- `never` — Never colorize output. + +## `--remap-path-prefix`: remap source names in output + +Remap source path prefixes in all output, including compiler diagnostics, +debug information, macro expansions, etc. It takes a value of the form +`FROM=TO` where a path prefix equal to `FROM` is rewritten to the value `TO`. +The `FROM` may itself contain an `=` symbol, but the `TO` value may not. This +flag may be specified multiple times. + +This is useful for normalizing build products, for example by removing the +current directory out of pathnames emitted into the object files. The +replacement is purely textual, with no consideration of the current system's +pathname syntax. For example `--remap-path-prefix foo=bar` will match +`foo/lib.rs` but not `./foo/lib.rs`. diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 12427daa3838..b938ae504d84 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1744,8 +1744,7 @@ pub fn rustc_short_optgroups() -> Vec { opt::multi_s( "", "print", - "Comma separated list of compiler information to \ - print on stdout", + "Compiler information to print on stdout", "[crate-name|file-names|sysroot|cfg|target-list|\ target-cpus|target-features|relocation-models|\ code-models|tls-models|target-spec-json|native-static-libs]", From a8245f5a38d0aa9cc392a1893fcbefb29bf77c2b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 7 May 2019 09:55:12 +1000 Subject: [PATCH 115/239] Add lots of static `Symbols`. These will be used in the subsequent commits. Many of them are attributes. The commit also adds the ability to handle symbols that aren't identifiers (e.g. "proc-macro"). --- src/librustc_macros/src/symbols.rs | 43 +++- src/libsyntax_pos/symbol.rs | 388 ++++++++++++++++++++++++++++- 2 files changed, 415 insertions(+), 16 deletions(-) diff --git a/src/librustc_macros/src/symbols.rs b/src/librustc_macros/src/symbols.rs index 169c5e137183..a4c7daf088ff 100644 --- a/src/librustc_macros/src/symbols.rs +++ b/src/librustc_macros/src/symbols.rs @@ -11,7 +11,7 @@ use quote::quote; #[allow(non_camel_case_types)] mod kw { syn::custom_keyword!(Keywords); - syn::custom_keyword!(Other); + syn::custom_keyword!(Symbols); } struct Keyword { @@ -33,14 +33,24 @@ impl Parse for Keyword { } } -struct Symbol(Ident); +struct Symbol { + name: Ident, + value: Option, +} impl Parse for Symbol { fn parse(input: ParseStream<'_>) -> Result { - let ident: Ident = input.parse()?; + let name = input.parse()?; + let value = match input.parse::() { + Ok(_) => Some(input.parse()?), + Err(_) => None, + }; input.parse::()?; - Ok(Symbol(ident)) + Ok(Symbol { + name, + value, + }) } } @@ -69,7 +79,7 @@ impl Parse for Input { braced!(content in input); let keywords = content.parse()?; - input.parse::()?; + input.parse::()?; let content; braced!(content in input); let symbols = content.parse()?; @@ -116,19 +126,22 @@ pub fn symbols(input: TokenStream) -> TokenStream { } for symbol in &input.symbols.0 { - let value = &symbol.0; - let value_str = value.to_string(); - check_dup(&value_str); + let name = &symbol.name; + let value = match &symbol.value { + Some(value) => value.value(), + None => name.to_string(), + }; + check_dup(&value); prefill_stream.extend(quote! { - #value_str, + #value, }); symbols_stream.extend(quote! { - pub const #value: Symbol = Symbol::new(#counter); + pub const #name: Symbol = Symbol::new(#counter); }); counter += 1; } - TokenStream::from(quote! { + let tt = TokenStream::from(quote! { macro_rules! keywords { () => { #keyword_stream @@ -159,5 +172,11 @@ pub fn symbols(input: TokenStream) -> TokenStream { ]) } } - }) + }); + + // To see the generated code generated, uncomment this line, recompile, and + // run the resulting output through `rustfmt`. + //eprintln!("{}", tt); + + tt } diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index c0c9c2a10004..5459f3904fa7 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -99,88 +99,375 @@ symbols! { Union: "union", } - // Other symbols that can be referred to with syntax_pos::symbols::* - Other { + // Symbols that can be referred to with syntax_pos::symbols::*. The symbol + // is the stringified identifier unless otherwise specified (e.g. + // `proc_dash_macro` represents "proc-macro"). + Symbols { + aarch64_target_feature, + abi, + abi_amdgpu_kernel, + abi_msp430_interrupt, + abi_ptx, + abi_sysv64, + abi_thiscall, + abi_unadjusted, + abi_vectorcall, + abi_x86_interrupt, + aborts, + advanced_slice_patterns, + adx_target_feature, alias, align, + alignstack, + all, + allocator, + allocator_internals, alloc_error_handler, allow, + allowed, allow_fail, allow_internal_unsafe, allow_internal_unstable, + allow_internal_unstable_backcompat_hack, + always, + any, + arbitrary_self_types, + arm_target_feature, + asm, + associated_consts, + associated_type_defaults, + associated_types, + async_await, + attr, + attributes, + attr_literals, + augmented_assignments, automatically_derived, + avx512_target_feature, + await_macro, + bin, + bind_by_move_pattern_guards, + block, + borrowck_graphviz_postflow, + borrowck_graphviz_preflow, + box_patterns, + box_syntax, + braced_empty_structs, + C, + cdylib, cfg, cfg_attr, + cfg_attr_multi, + cfg_target_feature, + cfg_target_has_atomic, + cfg_target_thread_local, + cfg_target_vendor, + clone, + clone_closures, + clone_from, + closure_to_fn_coercion, + cmpxchg16b_target_feature, cold, + compile_error, compiler_builtins, + concat_idents, + conservative_impl_trait, + console, + const_compare_raw_pointers, + const_fn, + const_fn_union, + const_generics, + const_indexing, + const_let, + const_panic, + const_raw_ptr_deref, + const_raw_ptr_to_usize_cast, + const_transmute, + contents, + convert, + copy_closures, + core, + core_intrinsics, crate_id, + crate_in_paths, crate_name, crate_type, + crate_visibility_modifier, + custom_attribute, + custom_derive, + custom_inner_attributes, + custom_test_frameworks, + c_variadic, + decl_macro, default_lib_allocator, + default_type_parameter_fallback, + default_type_params, deny, deprecated, derive, doc, + doc_alias, + doc_cfg, + doc_keyword, + doc_masked, + doc_spotlight, + document_private_items, + dotdoteq_in_patterns, + dotdot_in_tuple_patterns, + dropck_eyepatch, + dropck_parametricity, + drop_types_in_const, + dylib, + dyn_trait, + eh_personality, + eh_unwind_resume, + enable, + Err, + except, + exclusive_range_pattern, + exhaustive_integer_patterns, + exhaustive_patterns, + existential_type, + expected, export_name, + extern_absolute_paths, + external_doc, + extern_crate_item_prelude, + extern_crate_self, + extern_in_paths, + extern_prelude, + extern_types, + f16c_target_feature, feature, ffi_returns_twice, + field_init_shorthand, + file, + fn_must_use, forbid, + format_args_nl, + from, + From, + from_error, + from_generator, + from_ok, fundamental, + future, + Future, + generators, + generic_associated_types, + generic_param_attrs, global_allocator, + global_asm, + globs, + hexagon_target_feature, + hidden, + homogeneous_aggregate, + html_favicon_url, + html_logo_url, + html_no_source, + html_playground_url, + html_root_url, + i128, + i128_type, + i16, + i32, + i64, + i8, + ident, + if_let, + if_while_or_patterns, ignore, + impl_header_lifetime_elision, + impl_trait_in_bindings, + import_shadowing, + in_band_lifetimes, include, + inclusive_range_syntax, + infer_outlives_requirements, + infer_static_outlives_requirements, inline, + intel, + into_iter, + IntoIterator, + into_result, + intrinsics, + irrefutable_let_patterns, + isize, + issue, + issue_5723_bootstrap, + issue_tracker_base_url, + item_like_imports, + iter, + Iterator, keyword, + kind, + label, + label_break_value, lang, + lang_items, + lib, link, + linkage, link_args, + link_cfg, + link_llvm_intrinsics, link_name, link_section, - linkage, + lint_reasons, + local_inner_macros, + log_syntax, + loop_break_value, + macro_at_most_once_rep, macro_escape, macro_export, + macro_lifetime_matcher, + macro_literal_matcher, + macro_reexport, + macro_rules, + macros_in_extern, macro_use, + macro_vis_matcher, main, + managed_boxes, marker, + marker_trait_attr, masked, + match_beginning_vert, + match_default_bindings, may_dangle, + message, + min_const_fn, + min_const_unsafe_fn, + mips_target_feature, + mmx_target_feature, + module, + more_struct_aliases, + movbe_target_feature, must_use, naked, + naked_functions, + name, needs_allocator, needs_panic_runtime, + negate_unsigned, + never, + never_type, + next, + nll, no_builtins, no_core, + no_crate_inject, no_debug, + no_default_passes, no_implicit_prelude, + no_inline, no_link, no_main, no_mangle, + non_ascii_idents, + None, + non_exhaustive, + non_modrs_mods, + no_stack_check, no_start, no_std, - non_exhaustive, + not, + note, + Ok, omit_gdb_pretty_printer_section, + on, + on_unimplemented, + oom, + ops, optimize, + optimize_attribute, + optin_builtin_traits, + option, + Option, + opt_out_copy, + overlapping_marker_traits, + packed, panic_handler, + panic_impl, + panic_implementation, panic_runtime, + passes, path, + pattern_parentheses, + Pending, + pin, + Pin, + platform_intrinsics, plugin, plugin_registrar, + plugins, + Poll, + poll_with_tls_context, + powerpc_target_feature, + precise_pointer_size_matching, + prelude, prelude_import, + primitive, + proc_dash_macro: "proc-macro", proc_macro, proc_macro_attribute, proc_macro_derive, + proc_macro_expr, + proc_macro_gen, + proc_macro_hygiene, + proc_macro_mod, + proc_macro_non_items, + proc_macro_path_invoc, profiler_runtime, + pub_restricted, + pushpop_unsafe, + quad_precision_float, + question_mark, + quote, + Range, + RangeFrom, + RangeFull, + RangeInclusive, + RangeTo, + RangeToInclusive, + raw_identifiers, + Ready, + reason, recursion_limit, reexport_test_harness_main, + reflect, + relaxed_adts, repr, + repr128, + repr_align, + repr_align_enum, + repr_packed, + repr_simd, + repr_transparent, + re_rebalance_coherence, + result, + Result, + Return, + rlib, + rtm_target_feature, + rust, + rust_2015_preview, + rust_2018_preview, + rust_begin_unwind, + rustc_allocator_nounwind, + rustc_allow_const_fn_ptr, rustc_args_required_const, + rustc_attrs, rustc_clean, rustc_const_unstable, rustc_conversion_suggestion, rustc_copy_clone_marker, rustc_def_path, rustc_deprecated, + rustc_diagnostic_macros, rustc_dirty, + rustc_doc_only_macro, + rustc_dump_env_program_clauses, rustc_dump_program_clauses, rustc_dump_user_substs, rustc_error, @@ -191,13 +478,21 @@ symbols! { rustc_layout_scalar_valid_range_end, rustc_layout_scalar_valid_range_start, rustc_mir, + rustc_object_lifetime_default, rustc_on_unimplemented, rustc_outlives, rustc_paren_sugar, rustc_partition_codegened, rustc_partition_reused, + rustc_peek, + rustc_peek_definite_init, + rustc_peek_maybe_init, + rustc_peek_maybe_uninit, + rustc_private, rustc_proc_macro_decls, + rustc_promotable, rustc_regions, + rustc_stable, rustc_std_internal_symbol, rustc_symbol_name, rustc_synthetic, @@ -205,23 +500,108 @@ symbols! { rustc_then_this_would_need, rustc_transparent_macro, rustc_variance, + rustdoc, + rust_eh_personality, + rust_eh_unwind_resume, + rust_oom, + __rust_unstable_column, + rvalue_static_promotion, sanitizer_runtime, + self_in_typedefs, + self_struct_ctor, + Send, should_panic, simd, + simd_ffi, + since, + size, + slice_patterns, + slicing_syntax, + Some, + specialization, + speed, spotlight, + sse4a_target_feature, stable, + staged_api, start, + static_in_const, + staticlib, + static_nobundle, + static_recursion, + std, + stmt_expr_attributes, + stop_after_dataflow, + struct_field_attributes, + struct_inherit, structural_match, + struct_variant, + suggestion, target_feature, + target_has_atomic, + target_thread_local, + task, + tbm_target_feature, + termination_trait, + termination_trait_test, + test, + test_2018_feature, + test_accepted_feature, + test_removed_feature, test_runner, thread_local, + tool_attributes, + tool_lints, + trace_macros, + trait_alias, + transmute, + transparent, + trivial_bounds, + Try, + try_blocks, + tuple_indexing, + ty, + type_alias_enum_variants, + type_ascription, type_length_limit, + type_macros, + u128, + u16, + u32, + u64, + u8, + unboxed_closures, + underscore_const_names, + underscore_imports, + underscore_lifetimes, + uniform_paths, + universal_impl_trait, + unmarked_api, + unrestricted_attribute_tokens, unsafe_destructor_blind_to_params, + unsafe_no_drop_flag, + unsized_locals, + unsized_tuple_coercion, unstable, + untagged_unions, unwind, + unwind_attributes, used, + use_extern_macros, + use_nested_groups, + usize, + v1, + vis, + visible_private_types, + volatile, warn, + warn_directory_ownership, + wasm_import_module, + wasm_target_feature, + while_let, + windows, windows_subsystem, + Yield, } } From 79602c87b561e26fa1a8fe58b9130cca37375f90 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 10 May 2019 09:57:08 +1000 Subject: [PATCH 116/239] Rename `syntax::symbol::symbols` as `syntax::symbol::sym`. Because it's going to be used a lot. --- src/librustc/middle/lib_features.rs | 4 +- src/libsyntax/feature_gate.rs | 262 ++++++++++++++-------------- src/libsyntax_pos/lib.rs | 2 +- src/libsyntax_pos/symbol.rs | 7 +- 4 files changed, 138 insertions(+), 137 deletions(-) diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs index e79ef8bfc6fb..5acd48c77d82 100644 --- a/src/librustc/middle/lib_features.rs +++ b/src/librustc/middle/lib_features.rs @@ -8,7 +8,7 @@ use crate::ty::TyCtxt; use crate::hir::intravisit::{self, NestedVisitorMap, Visitor}; use syntax::symbol::Symbol; use syntax::ast::{Attribute, MetaItem, MetaItemKind}; -use syntax_pos::{Span, symbols}; +use syntax_pos::{Span, sym}; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use rustc_macros::HashStable; use errors::DiagnosticId; @@ -51,7 +51,7 @@ impl<'a, 'tcx> LibFeatureCollector<'a, 'tcx> { } fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option, Span)> { - let stab_attrs = [symbols::stable, symbols::unstable, symbols::rustc_const_unstable]; + let stab_attrs = [sym::stable, sym::unstable, sym::rustc_const_unstable]; // Find a stability attribute (i.e., `#[stable (..)]`, `#[unstable (..)]`, // `#[rustc_const_unstable (..)]`). diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index c3bad3aba184..c4977f924023 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -28,7 +28,7 @@ use crate::tokenstream::TokenTree; use errors::{DiagnosticBuilder, Handler}; use rustc_data_structures::fx::FxHashMap; use rustc_target::spec::abi::Abi; -use syntax_pos::{Span, DUMMY_SP, symbols}; +use syntax_pos::{Span, DUMMY_SP, sym}; use log::debug; use lazy_static::lazy_static; @@ -962,108 +962,108 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Normal attributes ( - symbols::warn, + sym::warn, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), Ungated ), ( - symbols::allow, + sym::allow, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), Ungated ), ( - symbols::forbid, + sym::forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), Ungated ), ( - symbols::deny, + sym::deny, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), Ungated ), - (symbols::macro_use, Normal, template!(Word, List: "name1, name2, ..."), Ungated), - (symbols::macro_export, Normal, template!(Word, List: "local_inner_macros"), Ungated), - (symbols::plugin_registrar, Normal, template!(Word), Ungated), + (sym::macro_use, Normal, template!(Word, List: "name1, name2, ..."), Ungated), + (sym::macro_export, Normal, template!(Word, List: "local_inner_macros"), Ungated), + (sym::plugin_registrar, Normal, template!(Word), Ungated), - (symbols::cfg, Normal, template!(List: "predicate"), Ungated), - (symbols::cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), Ungated), - (symbols::main, Normal, template!(Word), Ungated), - (symbols::start, Normal, template!(Word), Ungated), - (symbols::repr, Normal, template!(List: "C, packed, ..."), Ungated), - (symbols::path, Normal, template!(NameValueStr: "file"), Ungated), - (symbols::automatically_derived, Normal, template!(Word), Ungated), - (symbols::no_mangle, Normal, template!(Word), Ungated), - (symbols::no_link, Normal, template!(Word), Ungated), - (symbols::derive, Normal, template!(List: "Trait1, Trait2, ..."), Ungated), + (sym::cfg, Normal, template!(List: "predicate"), Ungated), + (sym::cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), Ungated), + (sym::main, Normal, template!(Word), Ungated), + (sym::start, Normal, template!(Word), Ungated), + (sym::repr, Normal, template!(List: "C, packed, ..."), Ungated), + (sym::path, Normal, template!(NameValueStr: "file"), Ungated), + (sym::automatically_derived, Normal, template!(Word), Ungated), + (sym::no_mangle, Normal, template!(Word), Ungated), + (sym::no_link, Normal, template!(Word), Ungated), + (sym::derive, Normal, template!(List: "Trait1, Trait2, ..."), Ungated), ( - symbols::should_panic, + sym::should_panic, Normal, template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"), Ungated ), - (symbols::ignore, Normal, template!(Word, NameValueStr: "reason"), Ungated), - (symbols::no_implicit_prelude, Normal, template!(Word), Ungated), - (symbols::reexport_test_harness_main, Normal, template!(NameValueStr: "name"), Ungated), - (symbols::link_args, Normal, template!(NameValueStr: "args"), Gated(Stability::Unstable, + (sym::ignore, Normal, template!(Word, NameValueStr: "reason"), Ungated), + (sym::no_implicit_prelude, Normal, template!(Word), Ungated), + (sym::reexport_test_harness_main, Normal, template!(NameValueStr: "name"), Ungated), + (sym::link_args, Normal, template!(NameValueStr: "args"), Gated(Stability::Unstable, "link_args", "the `link_args` attribute is experimental and not \ portable across platforms, it is recommended to \ use `#[link(name = \"foo\")] instead", cfg_fn!(link_args))), - (symbols::macro_escape, Normal, template!(Word), Ungated), + (sym::macro_escape, Normal, template!(Word), Ungated), // RFC #1445. - (symbols::structural_match, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::structural_match, Whitelisted, template!(Word), Gated(Stability::Unstable, "structural_match", "the semantics of constant patterns is \ not yet settled", cfg_fn!(structural_match))), // RFC #2008 - (symbols::non_exhaustive, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::non_exhaustive, Whitelisted, template!(Word), Gated(Stability::Unstable, "non_exhaustive", "non exhaustive is an experimental feature", cfg_fn!(non_exhaustive))), // RFC #1268 - (symbols::marker, Normal, template!(Word), Gated(Stability::Unstable, + (sym::marker, Normal, template!(Word), Gated(Stability::Unstable, "marker_trait_attr", "marker traits is an experimental feature", cfg_fn!(marker_trait_attr))), - (symbols::plugin, CrateLevel, template!(List: "name|name(args)"), Gated(Stability::Unstable, + (sym::plugin, CrateLevel, template!(List: "name|name(args)"), Gated(Stability::Unstable, "plugin", "compiler plugins are experimental \ and possibly buggy", cfg_fn!(plugin))), - (symbols::no_std, CrateLevel, template!(Word), Ungated), - (symbols::no_core, CrateLevel, template!(Word), Gated(Stability::Unstable, + (sym::no_std, CrateLevel, template!(Word), Ungated), + (sym::no_core, CrateLevel, template!(Word), Gated(Stability::Unstable, "no_core", "no_core is experimental", cfg_fn!(no_core))), - (symbols::lang, Normal, template!(NameValueStr: "name"), Gated(Stability::Unstable, + (sym::lang, Normal, template!(NameValueStr: "name"), Gated(Stability::Unstable, "lang_items", "language items are subject to change", cfg_fn!(lang_items))), - (symbols::linkage, Whitelisted, template!(NameValueStr: "external|internal|..."), + (sym::linkage, Whitelisted, template!(NameValueStr: "external|internal|..."), Gated(Stability::Unstable, "linkage", "the `linkage` attribute is experimental \ and not portable across platforms", cfg_fn!(linkage))), - (symbols::thread_local, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::thread_local, Whitelisted, template!(Word), Gated(Stability::Unstable, "thread_local", "`#[thread_local]` is an experimental feature, and does \ not currently handle destructors", cfg_fn!(thread_local))), - (symbols::rustc_on_unimplemented, Whitelisted, template!(List: + (sym::rustc_on_unimplemented, Whitelisted, template!(List: r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#, NameValueStr: "message"), Gated(Stability::Unstable, @@ -1071,101 +1071,101 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ "the `#[rustc_on_unimplemented]` attribute \ is an experimental feature", cfg_fn!(on_unimplemented))), - (symbols::rustc_const_unstable, Normal, template!(List: r#"feature = "name""#), + (sym::rustc_const_unstable, Normal, template!(List: r#"feature = "name""#), Gated(Stability::Unstable, "rustc_const_unstable", "the `#[rustc_const_unstable]` attribute \ is an internal feature", cfg_fn!(rustc_const_unstable))), - (symbols::global_allocator, Normal, template!(Word), Ungated), - (symbols::default_lib_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::global_allocator, Normal, template!(Word), Ungated), + (sym::default_lib_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable, "allocator_internals", "the `#[default_lib_allocator]` \ attribute is an experimental feature", cfg_fn!(allocator_internals))), - (symbols::needs_allocator, Normal, template!(Word), Gated(Stability::Unstable, + (sym::needs_allocator, Normal, template!(Word), Gated(Stability::Unstable, "allocator_internals", "the `#[needs_allocator]` \ attribute is an experimental \ feature", cfg_fn!(allocator_internals))), - (symbols::panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, "panic_runtime", "the `#[panic_runtime]` attribute is \ an experimental feature", cfg_fn!(panic_runtime))), - (symbols::needs_panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::needs_panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, "needs_panic_runtime", "the `#[needs_panic_runtime]` \ attribute is an experimental \ feature", cfg_fn!(needs_panic_runtime))), - (symbols::rustc_outlives, Normal, template!(Word), Gated(Stability::Unstable, + (sym::rustc_outlives, Normal, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "the `#[rustc_outlives]` attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_variance, Normal, template!(Word), Gated(Stability::Unstable, + (sym::rustc_variance, Normal, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "the `#[rustc_variance]` attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_layout, Normal, template!(List: "field1, field2, ..."), + (sym::rustc_layout, Normal, template!(List: "field1, field2, ..."), Gated(Stability::Unstable, "rustc_attrs", "the `#[rustc_layout]` attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"), + (sym::rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"), Gated(Stability::Unstable, "rustc_attrs", "the `#[rustc_layout_scalar_valid_range_start]` attribute \ is just used to enable niche optimizations in libcore \ and will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"), + (sym::rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"), Gated(Stability::Unstable, "rustc_attrs", "the `#[rustc_layout_scalar_valid_range_end]` attribute \ is just used to enable niche optimizations in libcore \ and will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_regions, Normal, template!(Word), Gated(Stability::Unstable, + (sym::rustc_regions, Normal, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "the `#[rustc_regions]` attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_error, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::rustc_error, Whitelisted, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "the `#[rustc_error]` attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_dump_user_substs, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::rustc_dump_user_substs, Whitelisted, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "this attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode"), + (sym::rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode"), Gated(Stability::Unstable, "rustc_attrs", "the `#[rustc_if_this_changed]` attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_then_this_would_need, Whitelisted, template!(List: "DepNode"), + (sym::rustc_then_this_would_need, Whitelisted, template!(List: "DepNode"), Gated(Stability::Unstable, "rustc_attrs", "the `#[rustc_if_this_changed]` attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_dirty, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...", + (sym::rustc_dirty, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#), Gated(Stability::Unstable, "rustc_attrs", @@ -1173,7 +1173,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_clean, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...", + (sym::rustc_clean, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#), Gated(Stability::Unstable, "rustc_attrs", @@ -1182,7 +1182,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ and will never be stable", cfg_fn!(rustc_attrs))), ( - symbols::rustc_partition_reused, + sym::rustc_partition_reused, Whitelisted, template!(List: r#"cfg = "...", module = "...""#), Gated( @@ -1195,7 +1195,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ) ), ( - symbols::rustc_partition_codegened, + sym::rustc_partition_codegened, Whitelisted, template!(List: r#"cfg = "...", module = "...""#), Gated( @@ -1207,7 +1207,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ cfg_fn!(rustc_attrs), ) ), - (symbols::rustc_expected_cgu_reuse, Whitelisted, template!(List: r#"cfg = "...", module = "...", + (sym::rustc_expected_cgu_reuse, Whitelisted, template!(List: r#"cfg = "...", module = "...", kind = "...""#), Gated(Stability::Unstable, "rustc_attrs", @@ -1215,28 +1215,28 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_synthetic, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::rustc_synthetic, Whitelisted, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "this attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_symbol_name, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::rustc_symbol_name, Whitelisted, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "internal rustc attributes will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_def_path, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::rustc_def_path, Whitelisted, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "internal rustc attributes will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_mir, Whitelisted, template!(List: "arg1, arg2, ..."), Gated(Stability::Unstable, + (sym::rustc_mir, Whitelisted, template!(List: "arg1, arg2, ..."), Gated(Stability::Unstable, "rustc_attrs", "the `#[rustc_mir]` attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), ( - symbols::rustc_inherit_overflow_checks, + sym::rustc_inherit_overflow_checks, Whitelisted, template!(Word), Gated( @@ -1251,35 +1251,35 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ) ), - (symbols::rustc_dump_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::rustc_dump_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "the `#[rustc_dump_program_clauses]` \ attribute is just used for rustc unit \ tests and will never be stable", cfg_fn!(rustc_attrs))), - (symbols::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable, + (sym::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "the `#[rustc_test_marker]` attribute \ is used internally to track tests", cfg_fn!(rustc_attrs))), - (symbols::rustc_transparent_macro, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::rustc_transparent_macro, Whitelisted, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "used internally for testing macro hygiene", cfg_fn!(rustc_attrs))), - (symbols::compiler_builtins, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::compiler_builtins, Whitelisted, template!(Word), Gated(Stability::Unstable, "compiler_builtins", "the `#[compiler_builtins]` attribute is used to \ identify the `compiler_builtins` crate which \ contains compiler-rt intrinsics and will never be \ stable", cfg_fn!(compiler_builtins))), - (symbols::sanitizer_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::sanitizer_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, "sanitizer_runtime", "the `#[sanitizer_runtime]` attribute is used to \ identify crates that contain the runtime of a \ sanitizer and will never be stable", cfg_fn!(sanitizer_runtime))), - (symbols::profiler_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::profiler_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, "profiler_runtime", "the `#[profiler_runtime]` attribute is used to \ identify the `profiler_builtins` crate which \ @@ -1287,35 +1287,35 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ stable", cfg_fn!(profiler_runtime))), - (symbols::allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."), + (sym::allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."), Gated(Stability::Unstable, "allow_internal_unstable", EXPLAIN_ALLOW_INTERNAL_UNSTABLE, cfg_fn!(allow_internal_unstable))), - (symbols::allow_internal_unsafe, Normal, template!(Word), Gated(Stability::Unstable, + (sym::allow_internal_unsafe, Normal, template!(Word), Gated(Stability::Unstable, "allow_internal_unsafe", EXPLAIN_ALLOW_INTERNAL_UNSAFE, cfg_fn!(allow_internal_unsafe))), - (symbols::fundamental, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::fundamental, Whitelisted, template!(Word), Gated(Stability::Unstable, "fundamental", "the `#[fundamental]` attribute \ is an experimental feature", cfg_fn!(fundamental))), - (symbols::proc_macro_derive, Normal, template!(List: "TraitName, \ + (sym::proc_macro_derive, Normal, template!(List: "TraitName, \ /*opt*/ attributes(name1, name2, ...)"), Ungated), - (symbols::rustc_copy_clone_marker, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::rustc_copy_clone_marker, Whitelisted, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "internal implementation detail", cfg_fn!(rustc_attrs))), // FIXME: #14408 whitelist docs since rustdoc looks at them ( - symbols::doc, + sym::doc, Whitelisted, template!(List: "hidden|inline|...", NameValueStr: "string"), Ungated @@ -1323,33 +1323,33 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // FIXME: #14406 these are processed in codegen, which happens after the // lint pass - (symbols::cold, Whitelisted, template!(Word), Ungated), - (symbols::naked, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::cold, Whitelisted, template!(Word), Ungated), + (sym::naked, Whitelisted, template!(Word), Gated(Stability::Unstable, "naked_functions", "the `#[naked]` attribute \ is an experimental feature", cfg_fn!(naked_functions))), - (symbols::ffi_returns_twice, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::ffi_returns_twice, Whitelisted, template!(Word), Gated(Stability::Unstable, "ffi_returns_twice", "the `#[ffi_returns_twice]` attribute \ is an experimental feature", cfg_fn!(ffi_returns_twice))), - (symbols::target_feature, Whitelisted, template!(List: r#"enable = "name""#), Ungated), - (symbols::export_name, Whitelisted, template!(NameValueStr: "name"), Ungated), - (symbols::inline, Whitelisted, template!(Word, List: "always|never"), Ungated), - (symbols::link, Whitelisted, template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", + (sym::target_feature, Whitelisted, template!(List: r#"enable = "name""#), Ungated), + (sym::export_name, Whitelisted, template!(NameValueStr: "name"), Ungated), + (sym::inline, Whitelisted, template!(Word, List: "always|never"), Ungated), + (sym::link, Whitelisted, template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...""#), Ungated), - (symbols::link_name, Whitelisted, template!(NameValueStr: "name"), Ungated), - (symbols::link_section, Whitelisted, template!(NameValueStr: "name"), Ungated), - (symbols::no_builtins, Whitelisted, template!(Word), Ungated), - (symbols::no_debug, Whitelisted, template!(Word), Gated( + (sym::link_name, Whitelisted, template!(NameValueStr: "name"), Ungated), + (sym::link_section, Whitelisted, template!(NameValueStr: "name"), Ungated), + (sym::no_builtins, Whitelisted, template!(Word), Ungated), + (sym::no_debug, Whitelisted, template!(Word), Gated( Stability::Deprecated("https://github.com/rust-lang/rust/issues/29721", None), "no_debug", "the `#[no_debug]` attribute was an experimental feature that has been \ deprecated due to lack of demand", cfg_fn!(no_debug))), ( - symbols::omit_gdb_pretty_printer_section, + sym::omit_gdb_pretty_printer_section, Whitelisted, template!(Word), Gated( @@ -1361,7 +1361,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ cfg_fn!(omit_gdb_pretty_printer_section) ) ), - (symbols::unsafe_destructor_blind_to_params, + (sym::unsafe_destructor_blind_to_params, Normal, template!(Word), Gated(Stability::Deprecated("https://github.com/rust-lang/rust/issues/34761", @@ -1370,21 +1370,21 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ "unsafe_destructor_blind_to_params has been replaced by \ may_dangle and will be removed in the future", cfg_fn!(dropck_parametricity))), - (symbols::may_dangle, + (sym::may_dangle, Normal, template!(Word), Gated(Stability::Unstable, "dropck_eyepatch", "may_dangle has unstable semantics and may be removed in the future", cfg_fn!(dropck_eyepatch))), - (symbols::unwind, Whitelisted, template!(List: "allowed|aborts"), Gated(Stability::Unstable, + (sym::unwind, Whitelisted, template!(List: "allowed|aborts"), Gated(Stability::Unstable, "unwind_attributes", "#[unwind] is experimental", cfg_fn!(unwind_attributes))), - (symbols::used, Whitelisted, template!(Word), Ungated), + (sym::used, Whitelisted, template!(Word), Ungated), // used in resolve - (symbols::prelude_import, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::prelude_import, Whitelisted, template!(Word), Gated(Stability::Unstable, "prelude_import", "`#[prelude_import]` is for use by rustc only", cfg_fn!(prelude_import))), @@ -1392,25 +1392,25 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // FIXME: #14407 these are only looked at on-demand so we can't // guarantee they'll have already been checked ( - symbols::rustc_deprecated, + sym::rustc_deprecated, Whitelisted, template!(List: r#"since = "version", reason = "...""#), Ungated ), - (symbols::must_use, Whitelisted, template!(Word, NameValueStr: "reason"), Ungated), + (sym::must_use, Whitelisted, template!(Word, NameValueStr: "reason"), Ungated), ( - symbols::stable, + sym::stable, Whitelisted, template!(List: r#"feature = "name", since = "version""#), Ungated ), ( - symbols::unstable, + sym::unstable, Whitelisted, template!(List: r#"feature = "name", reason = "...", issue = "N""#), Ungated ), - (symbols::deprecated, + (sym::deprecated, Normal, template!( Word, @@ -1420,69 +1420,69 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ Ungated ), - (symbols::rustc_paren_sugar, Normal, template!(Word), Gated(Stability::Unstable, + (sym::rustc_paren_sugar, Normal, template!(Word), Gated(Stability::Unstable, "unboxed_closures", "unboxed_closures are still evolving", cfg_fn!(unboxed_closures))), - (symbols::windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console"), Ungated), + (sym::windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console"), Ungated), - (symbols::proc_macro_attribute, Normal, template!(Word), Ungated), - (symbols::proc_macro, Normal, template!(Word), Ungated), + (sym::proc_macro_attribute, Normal, template!(Word), Ungated), + (sym::proc_macro, Normal, template!(Word), Ungated), - (symbols::rustc_proc_macro_decls, Normal, template!(Word), Gated(Stability::Unstable, + (sym::rustc_proc_macro_decls, Normal, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "used internally by rustc", cfg_fn!(rustc_attrs))), - (symbols::allow_fail, Normal, template!(Word), Gated(Stability::Unstable, + (sym::allow_fail, Normal, template!(Word), Gated(Stability::Unstable, "allow_fail", "allow_fail attribute is currently unstable", cfg_fn!(allow_fail))), - (symbols::rustc_std_internal_symbol, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::rustc_std_internal_symbol, Whitelisted, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "this is an internal attribute that will \ never be stable", cfg_fn!(rustc_attrs))), // whitelists "identity-like" conversion methods to suggest on type mismatch - (symbols::rustc_conversion_suggestion, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::rustc_conversion_suggestion, Whitelisted, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "this is an internal attribute that will \ never be stable", cfg_fn!(rustc_attrs))), ( - symbols::rustc_args_required_const, + sym::rustc_args_required_const, Whitelisted, template!(List: "N"), Gated(Stability::Unstable, "rustc_attrs", "never will be stable", cfg_fn!(rustc_attrs)) ), // RFC 2070 - (symbols::panic_handler, Normal, template!(Word), Ungated), + (sym::panic_handler, Normal, template!(Word), Ungated), - (symbols::alloc_error_handler, Normal, template!(Word), Gated(Stability::Unstable, + (sym::alloc_error_handler, Normal, template!(Word), Gated(Stability::Unstable, "alloc_error_handler", "#[alloc_error_handler] is an unstable feature", cfg_fn!(alloc_error_handler))), // RFC 2412 - (symbols::optimize, Whitelisted, template!(List: "size|speed"), Gated(Stability::Unstable, + (sym::optimize, Whitelisted, template!(List: "size|speed"), Gated(Stability::Unstable, "optimize_attribute", "#[optimize] attribute is an unstable feature", cfg_fn!(optimize_attribute))), // Crate level attributes - (symbols::crate_name, CrateLevel, template!(NameValueStr: "name"), Ungated), - (symbols::crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), Ungated), - (symbols::crate_id, CrateLevel, template!(NameValueStr: "ignored"), Ungated), - (symbols::feature, CrateLevel, template!(List: "name1, name1, ..."), Ungated), - (symbols::no_start, CrateLevel, template!(Word), Ungated), - (symbols::no_main, CrateLevel, template!(Word), Ungated), - (symbols::recursion_limit, CrateLevel, template!(NameValueStr: "N"), Ungated), - (symbols::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated), - (symbols::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable, + (sym::crate_name, CrateLevel, template!(NameValueStr: "name"), Ungated), + (sym::crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), Ungated), + (sym::crate_id, CrateLevel, template!(NameValueStr: "ignored"), Ungated), + (sym::feature, CrateLevel, template!(List: "name1, name1, ..."), Ungated), + (sym::no_start, CrateLevel, template!(Word), Ungated), + (sym::no_main, CrateLevel, template!(Word), Ungated), + (sym::recursion_limit, CrateLevel, template!(NameValueStr: "N"), Ungated), + (sym::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated), + (sym::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable, "custom_test_frameworks", EXPLAIN_CUSTOM_TEST_FRAMEWORKS, cfg_fn!(custom_test_frameworks))), @@ -1582,9 +1582,9 @@ impl<'a> Context<'a> { self, has_feature, attr.span, name, desc, GateStrength::Hard ); } - } else if name == symbols::doc { + } else if name == sym::doc { if let Some(content) = attr.meta_item_list() { - if content.iter().any(|c| c.check_name(symbols::include)) { + if content.iter().any(|c| c.check_name(sym::include)) { gate_feature!(self, external_doc, attr.span, "#[doc(include = \"...\")] is experimental" ); @@ -1841,11 +1841,11 @@ impl<'a> PostExpansionVisitor<'a> { template: AttributeTemplate) { // Some special attributes like `cfg` must be checked // before the generic check, so we skip them here. - let should_skip = |name| name == symbols::cfg; + let should_skip = |name| name == sym::cfg; // Some of previously accepted forms were used in practice, // report them as warnings for now. - let should_warn = |name| name == symbols::doc || name == symbols::ignore || - name == symbols::inline || name == symbols::link; + let should_warn = |name| name == sym::doc || name == sym::ignore || + name == sym::inline || name == sym::link; match attr.parse_meta(self.context.parse_sess) { Ok(meta) => if !should_skip(name) && !template.compatible(&meta.node) { @@ -1893,25 +1893,25 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { // check for gated attributes self.context.check_attribute(attr, attr_info, false); - if attr.check_name(symbols::doc) { + if attr.check_name(sym::doc) { if let Some(content) = attr.meta_item_list() { - if content.len() == 1 && content[0].check_name(symbols::cfg) { + if content.len() == 1 && content[0].check_name(sym::cfg) { gate_feature_post!(&self, doc_cfg, attr.span, "#[doc(cfg(...))] is experimental" ); - } else if content.iter().any(|c| c.check_name(symbols::masked)) { + } else if content.iter().any(|c| c.check_name(sym::masked)) { gate_feature_post!(&self, doc_masked, attr.span, "#[doc(masked)] is experimental" ); - } else if content.iter().any(|c| c.check_name(symbols::spotlight)) { + } else if content.iter().any(|c| c.check_name(sym::spotlight)) { gate_feature_post!(&self, doc_spotlight, attr.span, "#[doc(spotlight)] is experimental" ); - } else if content.iter().any(|c| c.check_name(symbols::alias)) { + } else if content.iter().any(|c| c.check_name(sym::alias)) { gate_feature_post!(&self, doc_alias, attr.span, "#[doc(alias = \"...\")] is experimental" ); - } else if content.iter().any(|c| c.check_name(symbols::keyword)) { + } else if content.iter().any(|c| c.check_name(sym::keyword)) { gate_feature_post!(&self, doc_keyword, attr.span, "#[doc(keyword = \"...\")] is experimental" ); @@ -1978,7 +1978,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::ItemKind::Struct(..) => { for attr in attr::filter_by_name(&i.attrs[..], "repr") { for item in attr.meta_item_list().unwrap_or_else(Vec::new) { - if item.check_name(symbols::simd) { + if item.check_name(sym::simd) { gate_feature_post!(&self, repr_simd, attr.span, "SIMD types are experimental and possibly buggy"); } @@ -1989,7 +1989,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::ItemKind::Enum(..) => { for attr in attr::filter_by_name(&i.attrs[..], "repr") { for item in attr.meta_item_list().unwrap_or_else(Vec::new) { - if item.check_name(symbols::align) { + if item.check_name(sym::align) { gate_feature_post!(&self, repr_align_enum, attr.span, "`#[repr(align(x))]` on enums is experimental"); } @@ -2319,7 +2319,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], // Process the edition umbrella feature-gates first, to ensure // `edition_enabled_features` is completed before it's queried. for attr in krate_attrs { - if !attr.check_name(symbols::feature) { + if !attr.check_name(sym::feature) { continue } @@ -2364,7 +2364,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], } for attr in krate_attrs { - if !attr.check_name(symbols::feature) { + if !attr.check_name(sym::feature) { continue } @@ -2496,7 +2496,7 @@ fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate, }; if !allow_features { for attr in &krate.attrs { - if attr.check_name(symbols::feature) { + if attr.check_name(sym::feature) { let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)"); span_err!(span_handler, attr.span, E0554, "#![feature] may not be used on the {} release channel", diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 3f09405a5c8c..d690a3919962 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -33,7 +33,7 @@ mod span_encoding; pub use span_encoding::{Span, DUMMY_SP}; pub mod symbol; -pub use symbol::symbols; +pub use symbol::sym; mod analyze_source_file; diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 5459f3904fa7..ac3f999c5379 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -99,8 +99,8 @@ symbols! { Union: "union", } - // Symbols that can be referred to with syntax_pos::symbols::*. The symbol - // is the stringified identifier unless otherwise specified (e.g. + // Symbols that can be referred to with syntax_pos::sym::*. The symbol is + // the stringified identifier unless otherwise specified (e.g. // `proc_dash_macro` represents "proc-macro"). Symbols { aarch64_target_feature, @@ -937,7 +937,8 @@ pub mod keywords { keywords!(); } -pub mod symbols { +// This module has a very short name because it's used a lot. +pub mod sym { use super::Symbol; symbols!(); } From fb084a48e2ca663de41b316dc6ece2dceb93e24e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 May 2019 13:21:18 +1000 Subject: [PATCH 117/239] Pass a `Symbol` to `check_name`, `emit_feature_err`, and related functions. --- src/librustc/hir/check_attr.rs | 21 +- src/librustc/hir/lowering.rs | 10 +- src/librustc/ich/hcx.rs | 2 +- src/librustc/ich/mod.rs | 20 +- src/librustc/lint/levels.rs | 4 +- src/librustc/middle/dead.rs | 9 +- src/librustc/middle/entry.rs | 7 +- src/librustc/middle/lang_items.rs | 8 +- src/librustc/middle/liveness.rs | 4 +- src/librustc/middle/mem_categorization.rs | 3 +- src/librustc/middle/recursion_limit.rs | 7 +- src/librustc/middle/resolve_lifetime.rs | 4 +- src/librustc/middle/stability.rs | 10 +- src/librustc/query/mod.rs | 2 +- src/librustc/session/mod.rs | 3 +- src/librustc/traits/coherence.rs | 9 +- src/librustc/traits/error_reporting.rs | 3 +- src/librustc/traits/on_unimplemented.rs | 11 +- src/librustc/ty/context.rs | 9 +- src/librustc/ty/mod.rs | 12 +- src/librustc/ty/util.rs | 3 +- src/librustc_allocator/expand.rs | 4 +- src/librustc_codegen_llvm/attributes.rs | 4 +- src/librustc_codegen_llvm/consts.rs | 3 +- src/librustc_codegen_llvm/debuginfo/gdb.rs | 4 +- src/librustc_codegen_llvm/llvm_util.rs | 135 +++++++------ src/librustc_codegen_ssa/back/write.rs | 6 +- src/librustc_codegen_ssa/mir/rvalue.rs | 6 +- src/librustc_codegen_utils/lib.rs | 3 +- src/librustc_codegen_utils/link.rs | 3 +- .../symbol_names_test.rs | 6 +- .../assert_module_sources.rs | 9 +- .../persist/dirty_clean.rs | 15 +- src/librustc_interface/passes.rs | 2 +- src/librustc_interface/proc_macro_decls.rs | 3 +- src/librustc_interface/util.rs | 4 +- src/librustc_lint/builtin.rs | 22 +- src/librustc_lint/nonstandard_style.rs | 7 +- src/librustc_lint/unused.rs | 8 +- src/librustc_metadata/creader.rs | 12 +- src/librustc_metadata/decoder.rs | 4 +- src/librustc_metadata/encoder.rs | 18 +- src/librustc_metadata/link_args.rs | 3 +- src/librustc_metadata/native_libs.rs | 16 +- .../borrow_check/error_reporting.rs | 3 +- src/librustc_mir/borrow_check/nll/mod.rs | 3 +- src/librustc_mir/dataflow/mod.rs | 11 +- src/librustc_mir/hair/cx/mod.rs | 4 +- src/librustc_mir/hair/pattern/mod.rs | 5 +- src/librustc_mir/interpret/cast.rs | 6 +- src/librustc_mir/transform/check_unsafety.rs | 4 +- src/librustc_mir/transform/qualify_consts.rs | 25 +-- src/librustc_mir/transform/rustc_peek.rs | 11 +- src/librustc_passes/ast_validation.rs | 8 +- src/librustc_passes/layout_test.rs | 3 +- src/librustc_passes/rvalue_promotion.rs | 3 +- src/librustc_plugin/build.rs | 4 +- src/librustc_plugin/load.rs | 3 +- src/librustc_plugin/registry.rs | 4 +- src/librustc_privacy/lib.rs | 7 +- src/librustc_resolve/build_reduced_graph.rs | 22 +- src/librustc_resolve/lib.rs | 8 +- src/librustc_resolve/macros.rs | 15 +- src/librustc_save_analysis/lib.rs | 6 +- src/librustc_traits/lowering/mod.rs | 5 +- src/librustc_typeck/astconv.rs | 3 +- src/librustc_typeck/check/coercion.rs | 3 +- src/librustc_typeck/check/demand.rs | 3 +- src/librustc_typeck/check/mod.rs | 8 +- src/librustc_typeck/check/wfcheck.rs | 3 +- src/librustc_typeck/check/writeback.rs | 5 +- src/librustc_typeck/collect.rs | 84 ++++---- src/librustc_typeck/outlives/mod.rs | 3 +- src/librustc_typeck/outlives/test.rs | 3 +- src/librustc_typeck/variance/test.rs | 3 +- src/librustdoc/clean/inline.rs | 3 +- src/librustdoc/clean/mod.rs | 59 +++--- src/librustdoc/core.rs | 3 +- src/librustdoc/html/render.rs | 11 +- .../passes/calculate_doc_coverage.rs | 3 +- src/librustdoc/passes/collect_trait_impls.rs | 5 +- src/librustdoc/passes/strip_hidden.rs | 3 +- src/librustdoc/test.rs | 16 +- src/librustdoc/visit_ast.rs | 26 +-- src/librustdoc/visit_lib.rs | 3 +- src/libsyntax/attr/builtin.rs | 18 +- src/libsyntax/attr/mod.rs | 25 +-- src/libsyntax/config.rs | 11 +- src/libsyntax/entry.rs | 5 +- src/libsyntax/ext/expand.rs | 30 +-- src/libsyntax/ext/source_util.rs | 4 +- src/libsyntax/ext/tt/macro_rules.rs | 12 +- src/libsyntax/feature_gate.rs | 191 +++++++++--------- src/libsyntax/parse/mod.rs | 6 +- src/libsyntax/parse/parser.rs | 6 +- src/libsyntax/std_inject.rs | 8 +- src/libsyntax/test.rs | 11 +- src/libsyntax_ext/asm.rs | 4 +- src/libsyntax_ext/concat_idents.rs | 4 +- src/libsyntax_ext/deriving/clone.rs | 4 +- src/libsyntax_ext/deriving/generic/mod.rs | 4 +- src/libsyntax_ext/format.rs | 6 +- src/libsyntax_ext/global_asm.rs | 4 +- src/libsyntax_ext/log_syntax.rs | 3 +- src/libsyntax_ext/proc_macro_decls.rs | 18 +- src/libsyntax_ext/test.rs | 12 +- src/libsyntax_ext/test_case.rs | 4 +- src/libsyntax_ext/trace_macros.rs | 4 +- src/libsyntax_pos/lib.rs | 4 +- .../auxiliary/custom-derive-plugin-attr.rs | 4 +- .../auxiliary/issue-40001-plugin.rs | 4 +- .../auxiliary/lint-for-crate.rs | 7 +- .../ui-fulldeps/auxiliary/attr-plugin-test.rs | 8 +- .../ui-fulldeps/auxiliary/lint-for-crate.rs | 3 +- 114 files changed, 671 insertions(+), 621 deletions(-) diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 4c527f80d0f5..23c8a671ec5b 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -12,6 +12,7 @@ use crate::hir; use crate::hir::def_id::DefId; use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; use std::fmt::{self, Display}; +use syntax::symbol::sym; use syntax_pos::Span; #[derive(Copy, Clone, PartialEq)] @@ -95,18 +96,18 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { fn check_attributes(&self, item: &hir::Item, target: Target) { if target == Target::Fn || target == Target::Const { self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id_from_hir_id(item.hir_id)); - } else if let Some(a) = item.attrs.iter().find(|a| a.check_name("target_feature")) { + } else if let Some(a) = item.attrs.iter().find(|a| a.check_name(sym::target_feature)) { self.tcx.sess.struct_span_err(a.span, "attribute should be applied to a function") .span_label(item.span, "not a function") .emit(); } for attr in &item.attrs { - if attr.check_name("inline") { + if attr.check_name(sym::inline) { self.check_inline(attr, &item.span, target) - } else if attr.check_name("non_exhaustive") { + } else if attr.check_name(sym::non_exhaustive) { self.check_non_exhaustive(attr, item, target) - } else if attr.check_name("marker") { + } else if attr.check_name(sym::marker) { self.check_marker(attr, item, target) } } @@ -166,7 +167,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { // ``` let hints: Vec<_> = item.attrs .iter() - .filter(|attr| attr.check_name("repr")) + .filter(|attr| attr.check_name(sym::repr)) .filter_map(|attr| attr.meta_item_list()) .flatten() .collect(); @@ -268,10 +269,10 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { // When checking statements ignore expressions, they will be checked later if let hir::StmtKind::Local(ref l) = stmt.node { for attr in l.attrs.iter() { - if attr.check_name("inline") { + if attr.check_name(sym::inline) { self.check_inline(attr, &stmt.span, Target::Statement); } - if attr.check_name("repr") { + if attr.check_name(sym::repr) { self.emit_repr_error( attr.span, stmt.span, @@ -289,10 +290,10 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { _ => Target::Expression, }; for attr in expr.attrs.iter() { - if attr.check_name("inline") { + if attr.check_name(sym::inline) { self.check_inline(attr, &expr.span, target); } - if attr.check_name("repr") { + if attr.check_name(sym::repr) { self.emit_repr_error( attr.span, expr.span, @@ -305,7 +306,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { fn check_used(&self, item: &hir::Item, target: Target) { for attr in &item.attrs { - if attr.check_name("used") && target != Target::Static { + if attr.check_name(sym::used) && target != Target::Static { self.tcx.sess .span_err(attr.span, "attribute must be applied to a `static` variable"); } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 5b334b24e2f4..0d80a0874e63 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -64,7 +64,7 @@ use syntax::ptr::P; use syntax::source_map::{respan, CompilerDesugaringKind, Spanned}; use syntax::source_map::CompilerDesugaringKind::IfTemporary; use syntax::std_inject; -use syntax::symbol::{keywords, Symbol}; +use syntax::symbol::{keywords, Symbol, sym}; use syntax::tokenstream::{TokenStream, TokenTree}; use syntax::parse::token::Token; use syntax::visit::{self, Visitor}; @@ -2727,7 +2727,7 @@ impl<'a> LoweringContext<'a> { self.lower_ty(x, ImplTraitContext::disallowed()) }), synthetic: param.attrs.iter() - .filter(|attr| attr.check_name("rustc_synthetic")) + .filter(|attr| attr.check_name(sym::rustc_synthetic)) .map(|_| hir::SyntheticTyParamKind::ImplTrait) .next(), }; @@ -2745,7 +2745,7 @@ impl<'a> LoweringContext<'a> { hir_id: self.lower_node_id(param.id), name, span: param.ident.span, - pure_wrt_drop: attr::contains_name(¶m.attrs, "may_dangle"), + pure_wrt_drop: attr::contains_name(¶m.attrs, sym::may_dangle), attrs: self.lower_attrs(¶m.attrs), bounds, kind, @@ -3773,8 +3773,8 @@ impl<'a> LoweringContext<'a> { let mut vis = self.lower_visibility(&i.vis, None); let attrs = self.lower_attrs(&i.attrs); if let ItemKind::MacroDef(ref def) = i.node { - if !def.legacy || attr::contains_name(&i.attrs, "macro_export") || - attr::contains_name(&i.attrs, "rustc_doc_only_macro") { + if !def.legacy || attr::contains_name(&i.attrs, sym::macro_export) || + attr::contains_name(&i.attrs, sym::rustc_doc_only_macro) { let body = self.lower_token_stream(def.stream()); let hir_id = self.lower_node_id(i.id); self.exported_macros.push(hir::MacroDef { diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 6da2cb9ab57e..8be610e8bf7a 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -28,7 +28,7 @@ use smallvec::SmallVec; fn compute_ignored_attr_names() -> FxHashSet { debug_assert!(ich::IGNORED_ATTRIBUTES.len() > 0); - ich::IGNORED_ATTRIBUTES.iter().map(|&s| Symbol::intern(s)).collect() + ich::IGNORED_ATTRIBUTES.iter().map(|&s| s).collect() } /// This is the context state available during incr. comp. hashing. It contains diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs index b407b75e68c9..f3fc7ec8fda1 100644 --- a/src/librustc/ich/mod.rs +++ b/src/librustc/ich/mod.rs @@ -4,6 +4,8 @@ crate use rustc_data_structures::fingerprint::Fingerprint; pub use self::caching_source_map_view::CachingSourceMapView; pub use self::hcx::{StableHashingContextProvider, StableHashingContext, NodeIdHashingMode, hash_stable_trait_impls}; +use syntax::symbol::{Symbol, sym}; + mod caching_source_map_view; mod hcx; @@ -12,16 +14,16 @@ mod impls_misc; mod impls_ty; mod impls_syntax; -pub const ATTR_DIRTY: &str = "rustc_dirty"; -pub const ATTR_CLEAN: &str = "rustc_clean"; -pub const ATTR_IF_THIS_CHANGED: &str = "rustc_if_this_changed"; -pub const ATTR_THEN_THIS_WOULD_NEED: &str = "rustc_then_this_would_need"; -pub const ATTR_PARTITION_REUSED: &str = "rustc_partition_reused"; -pub const ATTR_PARTITION_CODEGENED: &str = "rustc_partition_codegened"; -pub const ATTR_EXPECTED_CGU_REUSE: &str = "rustc_expected_cgu_reuse"; +pub const ATTR_DIRTY: Symbol = sym::rustc_dirty; +pub const ATTR_CLEAN: Symbol = sym::rustc_clean; +pub const ATTR_IF_THIS_CHANGED: Symbol = sym::rustc_if_this_changed; +pub const ATTR_THEN_THIS_WOULD_NEED: Symbol = sym::rustc_then_this_would_need; +pub const ATTR_PARTITION_REUSED: Symbol = sym::rustc_partition_reused; +pub const ATTR_PARTITION_CODEGENED: Symbol = sym::rustc_partition_codegened; +pub const ATTR_EXPECTED_CGU_REUSE: Symbol = sym::rustc_expected_cgu_reuse; -pub const IGNORED_ATTRIBUTES: &[&str] = &[ - "cfg", +pub const IGNORED_ATTRIBUTES: &[Symbol] = &[ + sym::cfg, ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED, ATTR_DIRTY, diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index 2e5bd8add0cd..a69758e33bab 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -14,7 +14,7 @@ use syntax::ast; use syntax::attr; use syntax::feature_gate; use syntax::source_map::MultiSpan; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; pub struct LintLevelSets { list: Vec, @@ -230,7 +230,7 @@ impl<'a> LintLevelsBuilder<'a> { if !self.sess.features_untracked().lint_reasons { feature_gate::emit_feature_err( &self.sess.parse_sess, - "lint_reasons", + sym::lint_reasons, item.span, feature_gate::GateIssue::Language, "lint reasons are experimental" diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index a0107ed0546d..2a9928567f4d 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -19,6 +19,7 @@ use rustc_data_structures::fx::FxHashMap; use syntax::{ast, source_map}; use syntax::attr; +use syntax::symbol::sym; use syntax_pos; // Any local node that may call something in its body block should be @@ -304,22 +305,22 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_, '_, '_>, id: hir::HirId, attrs: &[ast::Attribute]) -> bool { - if attr::contains_name(attrs, "lang") { + if attr::contains_name(attrs, sym::lang) { return true; } // Stable attribute for #[lang = "panic_impl"] - if attr::contains_name(attrs, "panic_handler") { + if attr::contains_name(attrs, sym::panic_handler) { return true; } // (To be) stable attribute for #[lang = "oom"] - if attr::contains_name(attrs, "alloc_error_handler") { + if attr::contains_name(attrs, sym::alloc_error_handler) { return true; } // Don't lint about global allocators - if attr::contains_name(attrs, "global_allocator") { + if attr::contains_name(attrs, sym::global_allocator) { return true; } diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index df77033ebef3..e2e76e69dc4e 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -4,6 +4,7 @@ use crate::session::{config, Session}; use crate::session::config::EntryFnType; use syntax::attr; use syntax::entry::EntryPointType; +use syntax::symbol::sym; use syntax_pos::Span; use crate::hir::{HirId, Item, ItemKind, ImplItem, TraitItem}; use crate::hir::itemlikevisit::ItemLikeVisitor; @@ -58,7 +59,7 @@ fn entry_fn(tcx: TyCtxt<'_, '_, '_>, cnum: CrateNum) -> Option<(DefId, EntryFnTy } // If the user wants no main function at all, then stop here. - if attr::contains_name(&tcx.hir().krate().attrs, "no_main") { + if attr::contains_name(&tcx.hir().krate().attrs, sym::no_main) { return None; } @@ -81,9 +82,9 @@ fn entry_fn(tcx: TyCtxt<'_, '_, '_>, cnum: CrateNum) -> Option<(DefId, EntryFnTy fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType { match item.node { ItemKind::Fn(..) => { - if attr::contains_name(&item.attrs, "start") { + if attr::contains_name(&item.attrs, sym::start) { EntryPointType::Start - } else if attr::contains_name(&item.attrs, "main") { + } else if attr::contains_name(&item.attrs, sym::main) { EntryPointType::MainAttr } else if item.ident.name == "main" { if at_root { diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 0e283ca6b1cf..103580a598fc 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -18,7 +18,7 @@ use crate::middle::weak_lang_items; use crate::util::nodemap::FxHashMap; use syntax::ast; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax_pos::Span; use rustc_macros::HashStable; use crate::hir::itemlikevisit::ItemLikeVisitor; @@ -209,9 +209,9 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { /// are also extracted out when found. pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> { attrs.iter().find_map(|attr| Some(match attr { - _ if attr.check_name("lang") => (attr.value_str()?, attr.span), - _ if attr.check_name("panic_handler") => (Symbol::intern("panic_impl"), attr.span), - _ if attr.check_name("alloc_error_handler") => (Symbol::intern("oom"), attr.span), + _ if attr.check_name(sym::lang) => (attr.value_str()?, attr.span), + _ if attr.check_name(sym::panic_handler) => (Symbol::intern("panic_impl"), attr.span), + _ if attr.check_name(sym::alloc_error_handler) => (Symbol::intern("oom"), attr.span), _ => return None, })) } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index a142b220f31a..cb333b5b0cba 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -112,7 +112,7 @@ use std::io; use std::rc::Rc; use syntax::ast::{self, NodeId}; use syntax::ptr::P; -use syntax::symbol::keywords; +use syntax::symbol::{keywords, sym}; use syntax_pos::Span; use crate::hir; @@ -362,7 +362,7 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>, if let FnKind::Method(..) = fk { let parent = ir.tcx.hir().get_parent_item(id); if let Some(Node::Item(i)) = ir.tcx.hir().find_by_hir_id(parent) { - if i.attrs.iter().any(|a| a.check_name("automatically_derived")) { + if i.attrs.iter().any(|a| a.check_name(sym::automatically_derived)) { return; } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 85c7f4379033..c7f8cf684e6b 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -72,6 +72,7 @@ use crate::hir::{MutImmutable, MutMutable, PatKind}; use crate::hir::pat_util::EnumerateAndAdjustIterator; use crate::hir; use syntax::ast::{self, Name}; +use syntax::symbol::sym; use syntax_pos::Span; use std::borrow::Cow; @@ -714,7 +715,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // they also cannot be moved out of. let is_thread_local = self.tcx.get_attrs(def_id)[..] .iter() - .any(|attr| attr.check_name("thread_local")); + .any(|attr| attr.check_name(sym::thread_local)); let cat = if is_thread_local { let re = self.temporary_scope(hir_id.local_id); diff --git a/src/librustc/middle/recursion_limit.rs b/src/librustc/middle/recursion_limit.rs index ea077220e0be..5f355d17072b 100644 --- a/src/librustc/middle/recursion_limit.rs +++ b/src/librustc/middle/recursion_limit.rs @@ -7,15 +7,16 @@ use crate::session::Session; use syntax::ast; +use syntax::symbol::{Symbol, sym}; use rustc_data_structures::sync::Once; pub fn update_limits(sess: &Session, krate: &ast::Crate) { - update_limit(krate, &sess.recursion_limit, "recursion_limit", 64); - update_limit(krate, &sess.type_length_limit, "type_length_limit", 1048576); + update_limit(krate, &sess.recursion_limit, sym::recursion_limit, 64); + update_limit(krate, &sess.type_length_limit, sym::type_length_limit, 1048576); } -fn update_limit(krate: &ast::Crate, limit: &Once, name: &str, default: usize) { +fn update_limit(krate: &ast::Crate, limit: &Once, name: Symbol, default: usize) { for attr in &krate.attrs { if !attr.check_name(name) { continue; diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index d835d872d76d..2402d0eefde4 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -23,7 +23,7 @@ use std::mem::replace; use syntax::ast; use syntax::attr; use syntax::ptr::P; -use syntax::symbol::keywords; +use syntax::symbol::{keywords, sym}; use syntax_pos::Span; use crate::hir::intravisit::{self, NestedVisitorMap, Visitor}; @@ -1285,7 +1285,7 @@ fn compute_object_lifetime_defaults( let result = object_lifetime_defaults_for_item(tcx, generics); // Debugging aid. - if attr::contains_name(&item.attrs, "rustc_object_lifetime_default") { + if attr::contains_name(&item.attrs, sym::rustc_object_lifetime_default) { let object_lifetime_default_reprs: String = result .iter() .map(|set| match *set { diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 5078bd7c5942..c608c72430cb 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -11,7 +11,7 @@ use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; use crate::ty::query::Providers; use crate::middle::privacy::AccessLevels; use crate::session::{DiagnosticMessageId, Session}; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax_pos::{Span, MultiSpan}; use syntax::ast::Attribute; use syntax::errors::Applicability; @@ -669,7 +669,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { match stability { Some(&Stability { level: attr::Unstable { reason, issue }, feature, .. }) => { - if span.allows_unstable(&feature.as_str()) { + if span.allows_unstable(feature) { debug!("stability: skipping span={:?} since it is internal", span); return EvalResult::Allow; } @@ -739,7 +739,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone()); let fresh = self.sess.one_time_diagnostics.borrow_mut().insert(error_id); if fresh { - emit_feature_err(&self.sess.parse_sess, &feature.as_str(), span, + emit_feature_err(&self.sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg); } } @@ -802,13 +802,13 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { if adt_def.has_dtor(self.tcx) { emit_feature_err(&self.tcx.sess.parse_sess, - "untagged_unions", item.span, GateIssue::Language, + sym::untagged_unions, item.span, GateIssue::Language, "unions with `Drop` implementations are unstable"); } else { let param_env = self.tcx.param_env(def_id); if !param_env.can_type_implement_copy(self.tcx, ty).is_ok() { emit_feature_err(&self.tcx.sess.parse_sess, - "untagged_unions", item.span, GateIssue::Language, + sym::untagged_unions, item.span, GateIssue::Language, "unions with non-`Copy` fields are unstable"); } } diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 0e7b66b74449..2fff4c3f109b 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -1052,7 +1052,7 @@ rustc_queries! { } Other { - query target_features_whitelist(_: CrateNum) -> Lrc>> { + query target_features_whitelist(_: CrateNum) -> Lrc>> { eval_always desc { "looking up the whitelist of target features" } } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index e8c7965ab4f4..4d47491661e8 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -29,6 +29,7 @@ use syntax::feature_gate::{self, AttributeType}; use syntax::json::JsonEmitter; use syntax::source_map; use syntax::parse::{self, ParseSess}; +use syntax::symbol::Symbol; use syntax_pos::{MultiSpan, Span}; use crate::util::profiling::SelfProfiler; @@ -86,7 +87,7 @@ pub struct Session { /// in order to avoid redundantly verbose output (Issue #24690, #44953). pub one_time_diagnostics: Lock, String)>>, pub plugin_llvm_passes: OneThread>>, - pub plugin_attributes: Lock>, + pub plugin_attributes: Lock>, pub crate_types: Once>, pub dependency_formats: Once, /// The crate_disambiguator is constructed out of all the `-C metadata` diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 35d8e2beef55..afbce5a4f0a4 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -4,17 +4,16 @@ //! [trait-resolution]: https://rust-lang.github.io/rustc-guide/traits/resolution.html //! [trait-specialization]: https://rust-lang.github.io/rustc-guide/traits/specialization.html -use crate::infer::CombinedSnapshot; +use crate::infer::{CombinedSnapshot, InferOk}; use crate::hir::def_id::{DefId, LOCAL_CRATE}; -use syntax_pos::DUMMY_SP; use crate::traits::{self, Normalized, SelectionContext, Obligation, ObligationCause}; use crate::traits::IntercrateMode; use crate::traits::select::IntercrateAmbiguityCause; use crate::ty::{self, Ty, TyCtxt}; use crate::ty::fold::TypeFoldable; use crate::ty::subst::Subst; - -use crate::infer::{InferOk}; +use syntax::symbol::sym; +use syntax_pos::DUMMY_SP; /// Whether we do the orphan check relative to this crate or /// to some remote crate. @@ -233,7 +232,7 @@ pub fn trait_ref_is_knowable<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, pub fn trait_ref_is_local_or_fundamental<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, trait_ref: ty::TraitRef<'tcx>) -> bool { - trait_ref.def_id.krate == LOCAL_CRATE || tcx.has_attr(trait_ref.def_id, "fundamental") + trait_ref.def_id.krate == LOCAL_CRATE || tcx.has_attr(trait_ref.def_id, sym::fundamental) } pub enum OrphanCheckErr<'tcx> { diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index d9ccbba69d5c..df2688397102 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -35,6 +35,7 @@ use crate::util::nodemap::{FxHashMap, FxHashSet}; use errors::{Applicability, DiagnosticBuilder}; use std::fmt; use syntax::ast; +use syntax::symbol::sym; use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnFormat}; impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { @@ -329,7 +330,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { return None }; - if tcx.has_attr(impl_def_id, "rustc_on_unimplemented") { + if tcx.has_attr(impl_def_id, sym::rustc_on_unimplemented) { Some(impl_def_id) } else { None diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index 2b286ee1b97f..7ba7429f465a 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -7,6 +7,7 @@ use crate::util::nodemap::FxHashMap; use syntax::ast::{MetaItem, NestedMetaItem}; use syntax::attr; +use syntax::symbol::sym; use syntax_pos::Span; use syntax_pos::symbol::LocalInternedString; @@ -84,25 +85,25 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { let mut note = None; let mut subcommands = vec![]; for item in item_iter { - if item.check_name("message") && message.is_none() { + if item.check_name(sym::message) && message.is_none() { if let Some(message_) = item.value_str() { message = Some(OnUnimplementedFormatString::try_parse( tcx, trait_def_id, message_.as_str(), span)?); continue; } - } else if item.check_name("label") && label.is_none() { + } else if item.check_name(sym::label) && label.is_none() { if let Some(label_) = item.value_str() { label = Some(OnUnimplementedFormatString::try_parse( tcx, trait_def_id, label_.as_str(), span)?); continue; } - } else if item.check_name("note") && note.is_none() { + } else if item.check_name(sym::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 && + } else if item.check_name(sym::on) && is_root && message.is_none() && label.is_none() && note.is_none() { if let Some(items) = item.meta_item_list() { @@ -139,7 +140,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { { let attrs = tcx.get_attrs(impl_def_id); - let attr = if let Some(item) = attr::find_by_name(&attrs, "rustc_on_unimplemented") { + let attr = if let Some(item) = attr::find_by_name(&attrs, sym::rustc_on_unimplemented) { item } else { return Ok(None); diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 15524ca6e930..c9fee02f66bb 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -74,7 +74,7 @@ use syntax::ast; use syntax::attr; use syntax::source_map::MultiSpan; use syntax::feature_gate; -use syntax::symbol::{Symbol, keywords, InternedString}; +use syntax::symbol::{Symbol, keywords, InternedString, sym}; use syntax_pos::Span; use crate::hir; @@ -1213,7 +1213,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } span_bug!(attr.span, "no arguments to `rustc_layout_scalar_valid_range` attribute"); }; - (get("rustc_layout_scalar_valid_range_start"), get("rustc_layout_scalar_valid_range_end")) + (get(sym::rustc_layout_scalar_valid_range_start), + get(sym::rustc_layout_scalar_valid_range_end)) } pub fn lift>(self, value: &T) -> Option { @@ -3102,10 +3103,10 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { }; providers.is_panic_runtime = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - attr::contains_name(tcx.hir().krate_attrs(), "panic_runtime") + attr::contains_name(tcx.hir().krate_attrs(), sym::panic_runtime) }; providers.is_compiler_builtins = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - attr::contains_name(tcx.hir().krate_attrs(), "compiler_builtins") + attr::contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins) }; } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 7b749957c3ff..2f71861d4dc0 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -47,7 +47,7 @@ use std::ops::Range; use syntax::ast::{self, Name, Ident, NodeId}; use syntax::attr; use syntax::ext::hygiene::Mark; -use syntax::symbol::{keywords, Symbol, LocalInternedString, InternedString}; +use syntax::symbol::{keywords, sym, Symbol, LocalInternedString, InternedString}; use syntax_pos::Span; use smallvec; @@ -1875,11 +1875,11 @@ impl<'a, 'gcx, 'tcx> VariantDef { ); let mut flags = VariantFlags::NO_VARIANT_FLAGS; - if adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, "non_exhaustive") { + if adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive) { debug!("found non-exhaustive field list for {:?}", parent_did); flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE; } else if let Some(variant_did) = variant_did { - if tcx.has_attr(variant_did, "non_exhaustive") { + if tcx.has_attr(variant_did, sym::non_exhaustive) { debug!("found non-exhaustive field list for {:?}", variant_did); flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE; } @@ -2156,7 +2156,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr); let mut flags = AdtFlags::NO_ADT_FLAGS; - if kind == AdtKind::Enum && tcx.has_attr(did, "non_exhaustive") { + if kind == AdtKind::Enum && tcx.has_attr(did, sym::non_exhaustive) { debug!("found non-exhaustive variant list for {:?}", did); flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE; } @@ -2172,7 +2172,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { } let attrs = tcx.get_attrs(did); - if attr::contains_name(&attrs, "fundamental") { + if attr::contains_name(&attrs, sym::fundamental) { flags |= AdtFlags::IS_FUNDAMENTAL; } if Some(did) == tcx.lang_items().phantom_data() { @@ -3030,7 +3030,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } /// Determines whether an item is annotated with an attribute. - pub fn has_attr(self, did: DefId, attr: &str) -> bool { + pub fn has_attr(self, did: DefId, attr: Symbol) -> bool { attr::contains_name(&self.get_attrs(did), attr) } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 4c8ed71a57ca..926c0f8b9491 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -22,6 +22,7 @@ use rustc_macros::HashStable; use std::{cmp, fmt}; use syntax::ast; use syntax::attr::{self, SignedInt, UnsignedInt}; +use syntax::symbol::sym; use syntax_pos::{Span, DUMMY_SP}; #[derive(Copy, Clone, Debug)] @@ -447,7 +448,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Such access can be in plain sight (e.g., dereferencing // `*foo.0` of `Foo<'a>(&'a u32)`) or indirectly hidden // (e.g., calling `foo.0.clone()` of `Foo`). - if self.has_attr(dtor, "unsafe_destructor_blind_to_params") { + if self.has_attr(dtor, sym::unsafe_destructor_blind_to_params) { debug!("destructor_constraint({:?}) - blind", def.did); return vec![]; } diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index 758a0d63886b..0200e6c53b69 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -19,7 +19,7 @@ use syntax::{ mut_visit::{self, MutVisitor}, parse::ParseSess, ptr::P, - symbol::Symbol + symbol::{Symbol, sym} }; use syntax_pos::Span; @@ -58,7 +58,7 @@ impl MutVisitor for ExpandAllocatorDirectives<'_> { fn flat_map_item(&mut self, item: P) -> SmallVec<[P; 1]> { debug!("in submodule {}", self.in_submod); - let name = if attr::contains_name(&item.attrs, "global_allocator") { + let name = if attr::contains_name(&item.attrs, sym::global_allocator) { "global_allocator" } else { return mut_visit::noop_flat_map_item(item, self); diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index b15a64c966b1..f26684d9ef04 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -321,12 +321,12 @@ pub fn provide(providers: &mut Providers<'_>) { // rustdoc needs to be able to document functions that use all the features, so // whitelist them all Lrc::new(llvm_util::all_known_features() - .map(|(a, b)| (a.to_string(), b.map(|s| s.to_string()))) + .map(|(a, b)| (a.to_string(), b)) .collect()) } else { Lrc::new(llvm_util::target_feature_whitelist(tcx.sess) .iter() - .map(|&(a, b)| (a.to_string(), b.map(|s| s.to_string()))) + .map(|&(a, b)| (a.to_string(), b)) .collect()) } }; diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 8c83e9ef538e..5f47108309fb 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -14,6 +14,7 @@ use rustc::mir::interpret::{ConstValue, Allocation, read_target_uint, use rustc::hir::Node; use syntax_pos::Span; use rustc_target::abi::HasDataLayout; +use syntax::symbol::sym; use syntax_pos::symbol::LocalInternedString; use rustc::ty::{self, Ty}; use rustc_codegen_ssa::traits::*; @@ -248,7 +249,7 @@ impl CodegenCx<'ll, 'tcx> { debug!("get_static: sym={} attrs={:?}", sym, attrs); for attr in attrs { - if attr.check_name("thread_local") { + if attr.check_name(sym::thread_local) { llvm::set_thread_local_mode(g, self.tls_model); } } diff --git a/src/librustc_codegen_llvm/debuginfo/gdb.rs b/src/librustc_codegen_llvm/debuginfo/gdb.rs index 91496ffbe557..04c9e93c7a52 100644 --- a/src/librustc_codegen_llvm/debuginfo/gdb.rs +++ b/src/librustc_codegen_llvm/debuginfo/gdb.rs @@ -9,6 +9,7 @@ use rustc::session::config::DebugInfo; use rustc_codegen_ssa::traits::*; use syntax::attr; +use syntax::symbol::sym; /// Inserts a side-effect free instruction sequence that makes sure that the @@ -66,8 +67,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx<'ll, '_>) pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool { let omit_gdb_pretty_printer_section = - attr::contains_name(&cx.tcx.hir().krate_attrs(), - "omit_gdb_pretty_printer_section"); + attr::contains_name(&cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section); !omit_gdb_pretty_printer_section && cx.sess().opts.debuginfo != DebugInfo::None && diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index f1b8d532eeb7..274c89659628 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -7,6 +7,7 @@ use rustc_target::spec::MergeFunctions; use libc::c_int; use std::ffi::CString; use syntax::feature_gate::UnstableFeatures; +use syntax::symbol::sym; use std::str; use std::slice; @@ -93,106 +94,106 @@ unsafe fn configure_llvm(sess: &Session) { // to LLVM or the feature detection code will walk past the end of the feature // array, leading to crashes. -const ARM_WHITELIST: &[(&str, Option<&str>)] = &[ - ("aclass", Some("arm_target_feature")), - ("mclass", Some("arm_target_feature")), - ("rclass", Some("arm_target_feature")), - ("dsp", Some("arm_target_feature")), - ("neon", Some("arm_target_feature")), - ("v5te", Some("arm_target_feature")), - ("v6", Some("arm_target_feature")), - ("v6k", Some("arm_target_feature")), - ("v6t2", Some("arm_target_feature")), - ("v7", Some("arm_target_feature")), - ("v8", Some("arm_target_feature")), - ("vfp2", Some("arm_target_feature")), - ("vfp3", Some("arm_target_feature")), - ("vfp4", Some("arm_target_feature")), +const ARM_WHITELIST: &[(&str, Option)] = &[ + ("aclass", Some(sym::arm_target_feature)), + ("mclass", Some(sym::arm_target_feature)), + ("rclass", Some(sym::arm_target_feature)), + ("dsp", Some(sym::arm_target_feature)), + ("neon", Some(sym::arm_target_feature)), + ("v5te", Some(sym::arm_target_feature)), + ("v6", Some(sym::arm_target_feature)), + ("v6k", Some(sym::arm_target_feature)), + ("v6t2", Some(sym::arm_target_feature)), + ("v7", Some(sym::arm_target_feature)), + ("v8", Some(sym::arm_target_feature)), + ("vfp2", Some(sym::arm_target_feature)), + ("vfp3", Some(sym::arm_target_feature)), + ("vfp4", Some(sym::arm_target_feature)), ]; -const AARCH64_WHITELIST: &[(&str, Option<&str>)] = &[ - ("fp", Some("aarch64_target_feature")), - ("neon", Some("aarch64_target_feature")), - ("sve", Some("aarch64_target_feature")), - ("crc", Some("aarch64_target_feature")), - ("crypto", Some("aarch64_target_feature")), - ("ras", Some("aarch64_target_feature")), - ("lse", Some("aarch64_target_feature")), - ("rdm", Some("aarch64_target_feature")), - ("fp16", Some("aarch64_target_feature")), - ("rcpc", Some("aarch64_target_feature")), - ("dotprod", Some("aarch64_target_feature")), - ("v8.1a", Some("aarch64_target_feature")), - ("v8.2a", Some("aarch64_target_feature")), - ("v8.3a", Some("aarch64_target_feature")), +const AARCH64_WHITELIST: &[(&str, Option)] = &[ + ("fp", Some(sym::aarch64_target_feature)), + ("neon", Some(sym::aarch64_target_feature)), + ("sve", Some(sym::aarch64_target_feature)), + ("crc", Some(sym::aarch64_target_feature)), + ("crypto", Some(sym::aarch64_target_feature)), + ("ras", Some(sym::aarch64_target_feature)), + ("lse", Some(sym::aarch64_target_feature)), + ("rdm", Some(sym::aarch64_target_feature)), + ("fp16", Some(sym::aarch64_target_feature)), + ("rcpc", Some(sym::aarch64_target_feature)), + ("dotprod", Some(sym::aarch64_target_feature)), + ("v8.1a", Some(sym::aarch64_target_feature)), + ("v8.2a", Some(sym::aarch64_target_feature)), + ("v8.3a", Some(sym::aarch64_target_feature)), ]; -const X86_WHITELIST: &[(&str, Option<&str>)] = &[ - ("adx", Some("adx_target_feature")), +const X86_WHITELIST: &[(&str, Option)] = &[ + ("adx", Some(sym::adx_target_feature)), ("aes", None), ("avx", None), ("avx2", None), - ("avx512bw", Some("avx512_target_feature")), - ("avx512cd", Some("avx512_target_feature")), - ("avx512dq", Some("avx512_target_feature")), - ("avx512er", Some("avx512_target_feature")), - ("avx512f", Some("avx512_target_feature")), - ("avx512ifma", Some("avx512_target_feature")), - ("avx512pf", Some("avx512_target_feature")), - ("avx512vbmi", Some("avx512_target_feature")), - ("avx512vl", Some("avx512_target_feature")), - ("avx512vpopcntdq", Some("avx512_target_feature")), + ("avx512bw", Some(sym::avx512_target_feature)), + ("avx512cd", Some(sym::avx512_target_feature)), + ("avx512dq", Some(sym::avx512_target_feature)), + ("avx512er", Some(sym::avx512_target_feature)), + ("avx512f", Some(sym::avx512_target_feature)), + ("avx512ifma", Some(sym::avx512_target_feature)), + ("avx512pf", Some(sym::avx512_target_feature)), + ("avx512vbmi", Some(sym::avx512_target_feature)), + ("avx512vl", Some(sym::avx512_target_feature)), + ("avx512vpopcntdq", Some(sym::avx512_target_feature)), ("bmi1", None), ("bmi2", None), - ("cmpxchg16b", Some("cmpxchg16b_target_feature")), - ("f16c", Some("f16c_target_feature")), + ("cmpxchg16b", Some(sym::cmpxchg16b_target_feature)), + ("f16c", Some(sym::f16c_target_feature)), ("fma", None), ("fxsr", None), ("lzcnt", None), - ("mmx", Some("mmx_target_feature")), - ("movbe", Some("movbe_target_feature")), + ("mmx", Some(sym::mmx_target_feature)), + ("movbe", Some(sym::movbe_target_feature)), ("pclmulqdq", None), ("popcnt", None), ("rdrand", None), ("rdseed", None), - ("rtm", Some("rtm_target_feature")), + ("rtm", Some(sym::rtm_target_feature)), ("sha", None), ("sse", None), ("sse2", None), ("sse3", None), ("sse4.1", None), ("sse4.2", None), - ("sse4a", Some("sse4a_target_feature")), + ("sse4a", Some(sym::sse4a_target_feature)), ("ssse3", None), - ("tbm", Some("tbm_target_feature")), + ("tbm", Some(sym::tbm_target_feature)), ("xsave", None), ("xsavec", None), ("xsaveopt", None), ("xsaves", None), ]; -const HEXAGON_WHITELIST: &[(&str, Option<&str>)] = &[ - ("hvx", Some("hexagon_target_feature")), - ("hvx-double", Some("hexagon_target_feature")), +const HEXAGON_WHITELIST: &[(&str, Option)] = &[ + ("hvx", Some(sym::hexagon_target_feature)), + ("hvx-double", Some(sym::hexagon_target_feature)), ]; -const POWERPC_WHITELIST: &[(&str, Option<&str>)] = &[ - ("altivec", Some("powerpc_target_feature")), - ("power8-altivec", Some("powerpc_target_feature")), - ("power9-altivec", Some("powerpc_target_feature")), - ("power8-vector", Some("powerpc_target_feature")), - ("power9-vector", Some("powerpc_target_feature")), - ("vsx", Some("powerpc_target_feature")), +const POWERPC_WHITELIST: &[(&str, Option)] = &[ + ("altivec", Some(sym::powerpc_target_feature)), + ("power8-altivec", Some(sym::powerpc_target_feature)), + ("power9-altivec", Some(sym::powerpc_target_feature)), + ("power8-vector", Some(sym::powerpc_target_feature)), + ("power9-vector", Some(sym::powerpc_target_feature)), + ("vsx", Some(sym::powerpc_target_feature)), ]; -const MIPS_WHITELIST: &[(&str, Option<&str>)] = &[ - ("fp64", Some("mips_target_feature")), - ("msa", Some("mips_target_feature")), +const MIPS_WHITELIST: &[(&str, Option)] = &[ + ("fp64", Some(sym::mips_target_feature)), + ("msa", Some(sym::mips_target_feature)), ]; -const WASM_WHITELIST: &[(&str, Option<&str>)] = &[ - ("simd128", Some("wasm_target_feature")), - ("atomics", Some("wasm_target_feature")), +const WASM_WHITELIST: &[(&str, Option)] = &[ + ("simd128", Some(sym::wasm_target_feature)), + ("atomics", Some(sym::wasm_target_feature)), ]; /// When rustdoc is running, provide a list of all known features so that all their respective @@ -200,7 +201,7 @@ const WASM_WHITELIST: &[(&str, Option<&str>)] = &[ /// /// IMPORTANT: If you're adding another whitelist to the above lists, make sure to add it to this /// iterator! -pub fn all_known_features() -> impl Iterator)> { +pub fn all_known_features() -> impl Iterator)> { ARM_WHITELIST.iter().cloned() .chain(AARCH64_WHITELIST.iter().cloned()) .chain(X86_WHITELIST.iter().cloned()) @@ -247,7 +248,7 @@ pub fn target_features(sess: &Session) -> Vec { } pub fn target_feature_whitelist(sess: &Session) - -> &'static [(&'static str, Option<&'static str>)] + -> &'static [(&'static str, Option)] { match &*sess.target.target.arch { "arm" => ARM_WHITELIST, diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 576bcc8f38e6..204ca59efc8d 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -28,7 +28,7 @@ use rustc_target::spec::MergeFunctions; use syntax::attr; use syntax::ext::hygiene::Mark; use syntax_pos::MultiSpan; -use syntax_pos::symbol::Symbol; +use syntax_pos::symbol::{Symbol, sym}; use jobserver::{Client, Acquired}; use std::any::Any; @@ -382,9 +382,9 @@ pub fn start_async_codegen( let sess = tcx.sess; let crate_name = tcx.crate_name(LOCAL_CRATE); let crate_hash = tcx.crate_hash(LOCAL_CRATE); - let no_builtins = attr::contains_name(&tcx.hir().krate().attrs, "no_builtins"); + let no_builtins = attr::contains_name(&tcx.hir().krate().attrs, sym::no_builtins); let subsystem = attr::first_attr_value_str_by_name(&tcx.hir().krate().attrs, - "windows_subsystem"); + sym::windows_subsystem); let windows_subsystem = subsystem.map(|subsystem| { if subsystem != "windows" && subsystem != "console" { tcx.sess.fatal(&format!("invalid windows subsystem `{}`, only \ diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 8d3e64c1aa6c..586db5cfabea 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -5,6 +5,7 @@ use rustc::mir; use rustc::middle::lang_items::ExchangeMallocFnLangItem; use rustc_apfloat::{ieee, Float, Status, Round}; use std::{u128, i128}; +use syntax::symbol::sym; use crate::base; use crate::MemFlags; @@ -181,9 +182,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::CastKind::Pointer(PointerCast::ReifyFnPointer) => { match operand.layout.ty.sty { ty::FnDef(def_id, substs) => { - if bx.cx().tcx().has_attr(def_id, "rustc_args_required_const") { - bug!("reifying a fn ptr that requires \ - const arguments"); + if bx.cx().tcx().has_attr(def_id, sym::rustc_args_required_const) { + bug!("reifying a fn ptr that requires const arguments"); } OperandValue::Immediate( callee::resolve_and_get_fn(bx.cx(), def_id, substs)) diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index 437515f1e9ab..b4ba90c61f65 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -23,6 +23,7 @@ extern crate rustc; use rustc::ty::TyCtxt; use rustc::hir::def_id::LOCAL_CRATE; +use syntax::symbol::sym; pub mod link; pub mod codegen_backend; @@ -35,7 +36,7 @@ pub mod symbol_names_test; /// reporting an error. pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_, '_, '_>) { if let Some((def_id, _)) = tcx.entry_fn(LOCAL_CRATE) { - if tcx.has_attr(def_id, "rustc_error") { + if tcx.has_attr(def_id, sym::rustc_error) { tcx.sess.span_fatal(tcx.def_span(def_id), "compilation successful"); } } diff --git a/src/librustc_codegen_utils/link.rs b/src/librustc_codegen_utils/link.rs index f3a1b219f8a8..30f37fefa7cf 100644 --- a/src/librustc_codegen_utils/link.rs +++ b/src/librustc_codegen_utils/link.rs @@ -2,6 +2,7 @@ use rustc::session::config::{self, OutputFilenames, Input, OutputType}; use rustc::session::Session; use std::path::{Path, PathBuf}; use syntax::{ast, attr}; +use syntax::symbol::sym; use syntax_pos::Span; pub fn out_filename(sess: &Session, @@ -49,7 +50,7 @@ pub fn find_crate_name(sess: Option<&Session>, // as used. After doing this, however, we still prioritize a crate name from // the command line over one found in the #[crate_name] attribute. If we // find both we ensure that they're the same later on as well. - let attr_crate_name = attr::find_by_name(attrs, "crate_name") + let attr_crate_name = attr::find_by_name(attrs, sym::crate_name) .and_then(|at| at.value_str().map(|s| (at, s))); if let Some(sess) = sess { diff --git a/src/librustc_codegen_utils/symbol_names_test.rs b/src/librustc_codegen_utils/symbol_names_test.rs index 6a2b6f1321b8..27ae0b97e594 100644 --- a/src/librustc_codegen_utils/symbol_names_test.rs +++ b/src/librustc_codegen_utils/symbol_names_test.rs @@ -6,11 +6,11 @@ use rustc::hir; use rustc::ty::TyCtxt; - use rustc_mir::monomorphize::Instance; +use syntax::symbol::{Symbol, sym}; -const SYMBOL_NAME: &'static str = "rustc_symbol_name"; -const DEF_PATH: &'static str = "rustc_def_path"; +const SYMBOL_NAME: Symbol = sym::rustc_symbol_name; +const DEF_PATH: Symbol = sym::rustc_def_path; pub fn report_symbol_names<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { // if the `rustc_attrs` feature is not enabled, then the diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs index 2c83501c86f5..04dad9c5355c 100644 --- a/src/librustc_incremental/assert_module_sources.rs +++ b/src/librustc_incremental/assert_module_sources.rs @@ -27,12 +27,13 @@ use rustc::mir::mono::CodegenUnitNameBuilder; use rustc::ty::TyCtxt; use std::collections::BTreeSet; use syntax::ast; +use syntax::symbol::{Symbol, sym}; use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED, ATTR_EXPECTED_CGU_REUSE}; -const MODULE: &str = "module"; -const CFG: &str = "cfg"; -const KIND: &str = "kind"; +const MODULE: Symbol = sym::module; +const CFG: Symbol = sym::cfg; +const KIND: Symbol = sym::kind; pub fn assert_module_sources<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.dep_graph.with_ignore(|| { @@ -146,7 +147,7 @@ impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> { comp_kind); } - fn field(&self, attr: &ast::Attribute, name: &str) -> ast::Name { + fn field(&self, attr: &ast::Attribute, name: Symbol) -> ast::Name { for item in attr.meta_item_list().unwrap_or_else(Vec::new) { if item.check_name(name) { if let Some(value) = item.value_str() { diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 6f5b411946c2..f404a4f82e67 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -23,14 +23,15 @@ use rustc::hir::def_id::DefId; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::intravisit; use rustc::ich::{ATTR_DIRTY, ATTR_CLEAN}; -use syntax::ast::{self, Attribute, NestedMetaItem}; -use rustc_data_structures::fx::FxHashSet; -use syntax_pos::Span; use rustc::ty::TyCtxt; +use rustc_data_structures::fx::FxHashSet; +use syntax::ast::{self, Attribute, NestedMetaItem}; +use syntax::symbol::{Symbol, sym}; +use syntax_pos::Span; -const EXCEPT: &str = "except"; -const LABEL: &str = "label"; -const CFG: &str = "cfg"; +const EXCEPT: Symbol = sym::except; +const LABEL: Symbol = sym::label; +const CFG: Symbol = sym::cfg; // Base and Extra labels to build up the labels @@ -591,7 +592,7 @@ fn expect_associated_value(tcx: TyCtxt<'_, '_, '_>, item: &NestedMetaItem) -> as // nodes. pub struct FindAllAttrs<'a, 'tcx:'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - attr_names: Vec<&'static str>, + attr_names: Vec, found_attrs: Vec<&'tcx Attribute>, } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 54b3e7342056..c5ac8860ccd9 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -230,7 +230,7 @@ impl BoxedResolver { pub struct PluginInfo { syntax_exts: Vec, - attributes: Vec<(String, AttributeType)>, + attributes: Vec<(Symbol, AttributeType)>, } pub fn register_plugins<'a>( diff --git a/src/librustc_interface/proc_macro_decls.rs b/src/librustc_interface/proc_macro_decls.rs index 8ed03efd1a78..e9f2f0410d44 100644 --- a/src/librustc_interface/proc_macro_decls.rs +++ b/src/librustc_interface/proc_macro_decls.rs @@ -4,6 +4,7 @@ use rustc::hir; use rustc::ty::TyCtxt; use rustc::ty::query::Providers; use syntax::attr; +use syntax::symbol::sym; pub fn find<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> Option { tcx.proc_macro_decls_static(LOCAL_CRATE) @@ -27,7 +28,7 @@ struct Finder { impl<'v> ItemLikeVisitor<'v> for Finder { fn visit_item(&mut self, item: &hir::Item) { - if attr::contains_name(&item.attrs, "rustc_proc_macro_decls") { + if attr::contains_name(&item.attrs, sym::rustc_proc_macro_decls) { self.decls = Some(item.hir_id); } } diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 17523aedffb5..2b1a993d1cc2 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -35,7 +35,7 @@ use syntax::mut_visit::{*, MutVisitor, visit_clobber}; use syntax::ast::BlockCheckMode; use syntax::util::lev_distance::find_best_match_for_name; use syntax::source_map::{FileLoader, RealFileLoader, SourceMap}; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax::{self, ast, attr}; #[cfg(not(parallel_compiler))] use std::{thread, panic}; @@ -495,7 +495,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec = attrs .iter() .filter_map(|a| { - if a.check_name("crate_type") { + if a.check_name(sym::crate_type) { match a.value_str() { Some(ref n) if *n == "rlib" => Some(config::CrateType::Rlib), Some(ref n) if *n == "dylib" => Some(config::CrateType::Dylib), diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index f7a89271ec55..af4f1b88b0fb 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -42,7 +42,7 @@ use syntax::edition::Edition; use syntax::feature_gate::{AttributeGate, AttributeTemplate, AttributeType}; use syntax::feature_gate::{Stability, deprecated_attributes}; use syntax_pos::{BytePos, Span, SyntaxContext}; -use syntax::symbol::{Symbol, keywords}; +use syntax::symbol::{Symbol, keywords, sym}; use syntax::errors::{Applicability, DiagnosticBuilder}; use syntax::print::pprust::expr_to_string; use syntax::visit::FnKind; @@ -207,7 +207,7 @@ impl UnsafeCode { impl EarlyLintPass for UnsafeCode { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) { - if attr.check_name("allow_internal_unsafe") { + if attr.check_name(sym::allow_internal_unsafe) { self.report_unsafe(cx, attr.span, "`allow_internal_unsafe` allows defining \ macros using unsafe without triggering \ the `unsafe_code` lint at their call site"); @@ -285,7 +285,7 @@ pub struct MissingDoc { impl_lint_pass!(MissingDoc => [MISSING_DOCS]); fn has_doc(attr: &ast::Attribute) -> bool { - if !attr.check_name("doc") { + if !attr.check_name(sym::doc) { return false; } @@ -295,7 +295,7 @@ fn has_doc(attr: &ast::Attribute) -> bool { if let Some(list) = attr.meta_item_list() { for meta in list { - if meta.check_name("include") || meta.check_name("hidden") { + if meta.check_name(sym::include) || meta.check_name(sym::hidden) { return true; } } @@ -355,10 +355,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { fn enter_lint_attrs(&mut self, _: &LateContext<'_, '_>, attrs: &[ast::Attribute]) { let doc_hidden = self.doc_hidden() || attrs.iter().any(|attr| { - attr.check_name("doc") && + attr.check_name(sym::doc) && match attr.meta_item_list() { None => false, - Some(l) => attr::list_contains_name(&l, "hidden"), + Some(l) => attr::list_contains_name(&l, sym::hidden), } }); self.doc_hidden_stack.push(doc_hidden); @@ -723,7 +723,7 @@ impl UnusedDocComment { let span = sugared_span.take().unwrap_or_else(|| attr.span); - if attr.check_name("doc") { + if attr.check_name(sym::doc) { let mut err = cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, "unused doc comment"); err.span_label( @@ -829,7 +829,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) { match it.node { hir::ItemKind::Fn(.., ref generics, _) => { - if let Some(no_mangle_attr) = attr::find_by_name(&it.attrs, "no_mangle") { + if let Some(no_mangle_attr) = attr::find_by_name(&it.attrs, sym::no_mangle) { for param in &generics.params { match param.kind { GenericParamKind::Lifetime { .. } => {} @@ -856,7 +856,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { } } hir::ItemKind::Const(..) => { - if attr::contains_name(&it.attrs, "no_mangle") { + if attr::contains_name(&it.attrs, sym::no_mangle) { // Const items do not refer to a particular location in memory, and therefore // don't have anything to attach a symbol to let msg = "const items should never be #[no_mangle]"; @@ -947,7 +947,7 @@ declare_lint_pass!( impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnstableFeatures { fn check_attribute(&mut self, ctx: &LateContext<'_, '_>, attr: &ast::Attribute) { - if attr.check_name("feature") { + if attr.check_name(sym::feature) { if let Some(items) = attr.meta_item_list() { for item in items { ctx.span_lint(UNSTABLE_FEATURES, item.span(), "unstable feature"); @@ -1382,7 +1382,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems { return; } - if let Some(attr) = attr::find_by_name(&it.attrs, "rustc_test_marker") { + if let Some(attr) = attr::find_by_name(&it.attrs, sym::rustc_test_marker) { cx.struct_span_lint( UNNAMEABLE_TEST_ITEMS, attr.span, diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index 7a003d14b2bf..551eded9858a 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -9,6 +9,7 @@ use lint::{EarlyLintPass, LintPass, LateLintPass}; use syntax::ast; use syntax::attr; use syntax::errors::Applicability; +use syntax::symbol::sym; use syntax_pos::{BytePos, symbol::Ident, Span}; #[derive(PartialEq)] @@ -253,7 +254,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name { Some(Ident::from_str(name)) } else { - attr::find_by_name(&cx.tcx.hir().attrs_by_hir_id(hir::CRATE_HIR_ID), "crate_name") + attr::find_by_name(&cx.tcx.hir().attrs_by_hir_id(hir::CRATE_HIR_ID), sym::crate_name) .and_then(|attr| attr.meta()) .and_then(|meta| { meta.name_value_literal().and_then(|lit| { @@ -315,7 +316,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { } FnKind::ItemFn(ident, _, header, _, attrs) => { // Skip foreign-ABI #[no_mangle] functions (Issue #31924) - if header.abi != Abi::Rust && attr::contains_name(attrs, "no_mangle") { + if header.abi != Abi::Rust && attr::contains_name(attrs, sym::no_mangle) { return; } self.check_snake_case(cx, "function", ident); @@ -390,7 +391,7 @@ impl NonUpperCaseGlobals { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals { fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) { match it.node { - hir::ItemKind::Static(..) if !attr::contains_name(&it.attrs, "no_mangle") => { + hir::ItemKind::Static(..) if !attr::contains_name(&it.attrs, sym::no_mangle) => { NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident); } hir::ItemKind::Const(..) => { diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 92508ad51f10..93af7a1cd8f2 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -12,7 +12,7 @@ use syntax::attr; use syntax::errors::Applicability; use syntax::feature_gate::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use syntax::print::pprust; -use syntax::symbol::keywords; +use syntax::symbol::{keywords, sym}; use syntax::symbol::Symbol; use syntax::util::parser; use syntax_pos::Span; @@ -170,7 +170,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { descr_post_path: &str, ) -> bool { for attr in cx.tcx.get_attrs(def_id).iter() { - if attr.check_name("must_use") { + if attr.check_name(sym::must_use) { let msg = format!("unused {}`{}`{} that must be used", descr_pre_path, cx.tcx.def_path_str(def_id), descr_post_path); let mut err = cx.struct_span_lint(UNUSED_MUST_USE, sp, &msg); @@ -243,8 +243,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes { } let plugin_attributes = cx.sess().plugin_attributes.borrow_mut(); - for &(ref name, ty) in plugin_attributes.iter() { - if ty == AttributeType::Whitelisted && attr.check_name(&**name) { + for &(name, ty) in plugin_attributes.iter() { + if ty == AttributeType::Whitelisted && attr.check_name(name) { debug!("{:?} (plugin attr) is whitelisted with ty {:?}", name, ty); break; } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index c47d7d85a376..20caad70f2b5 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -27,7 +27,7 @@ use std::{cmp, fs}; use syntax::ast; use syntax::attr; use syntax::ext::base::SyntaxExtension; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax::visit; use syntax::{span_err, span_fatal}; use syntax_pos::{Span, DUMMY_SP}; @@ -704,7 +704,7 @@ impl<'a> CrateLoader<'a> { let desired_strategy = self.sess.panic_strategy(); let mut runtime_found = false; let mut needs_panic_runtime = attr::contains_name(&krate.attrs, - "needs_panic_runtime"); + sym::needs_panic_runtime); self.cstore.iter_crate_data(|cnum, data| { needs_panic_runtime = needs_panic_runtime || @@ -898,7 +898,7 @@ impl<'a> CrateLoader<'a> { // about through the `#![needs_allocator]` attribute and is typically // written down in liballoc. let mut needs_allocator = attr::contains_name(&krate.attrs, - "needs_allocator"); + sym::needs_allocator); self.cstore.iter_crate_data(|_, data| { needs_allocator = needs_allocator || data.root.needs_allocator; }); @@ -964,7 +964,7 @@ impl<'a> CrateLoader<'a> { // allocator. At this point our allocator request is typically fulfilled // by the standard library, denoted by the `#![default_lib_allocator]` // attribute. - let mut has_default = attr::contains_name(&krate.attrs, "default_lib_allocator"); + let mut has_default = attr::contains_name(&krate.attrs, sym::default_lib_allocator); self.cstore.iter_crate_data(|_, data| { if data.root.has_default_lib_allocator { has_default = true; @@ -987,7 +987,7 @@ impl<'a> CrateLoader<'a> { impl<'ast> visit::Visitor<'ast> for Finder { fn visit_item(&mut self, i: &'ast ast::Item) { - if attr::contains_name(&i.attrs, "global_allocator") { + if attr::contains_name(&i.attrs, sym::global_allocator) { self.0 = true; } visit::walk_item(self, i) @@ -1065,7 +1065,7 @@ impl<'a> CrateLoader<'a> { } None => item.ident.name, }; - let dep_kind = if attr::contains_name(&item.attrs, "no_link") { + let dep_kind = if attr::contains_name(&item.attrs, sym::no_link) { DepKind::UnexportedMacrosOnly } else { DepKind::Explicit diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 4b9db466da84..e950c2815e9b 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -29,7 +29,7 @@ use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque}; use syntax::attr; use syntax::ast::{self, Ident}; use syntax::source_map; -use syntax::symbol::InternedString; +use syntax::symbol::{InternedString, sym}; use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::hygiene::Mark; use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, NO_EXPANSION}; @@ -841,7 +841,7 @@ impl<'a, 'tcx> CrateMetadata { // for other constructors correct visibilities // were already encoded in metadata. let attrs = self.get_item_attrs(def_id.index, sess); - if attr::contains_name(&attrs, "non_exhaustive") { + if attr::contains_name(&attrs, sym::non_exhaustive) { let crate_def_id = self.local_def_id(CRATE_DEF_INDEX); vis = ty::Visibility::Restricted(crate_def_id); } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 0946dad53203..0ac03526832b 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -33,7 +33,7 @@ use std::u32; use syntax::ast; use syntax::attr; use syntax::source_map::Spanned; -use syntax::symbol::keywords; +use syntax::symbol::{keywords, sym}; use syntax_pos::{self, hygiene, FileName, SourceFile, Span}; use log::{debug, trace}; @@ -469,7 +469,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let attrs = tcx.hir().krate_attrs(); let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro); - let has_default_lib_allocator = attr::contains_name(&attrs, "default_lib_allocator"); + let has_default_lib_allocator = attr::contains_name(&attrs, sym::default_lib_allocator); let has_global_allocator = *tcx.sess.has_global_allocator.get(); let has_panic_handler = *tcx.sess.has_panic_handler.try_get().unwrap_or(&false); @@ -496,13 +496,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } else { None }, - compiler_builtins: attr::contains_name(&attrs, "compiler_builtins"), - needs_allocator: attr::contains_name(&attrs, "needs_allocator"), - needs_panic_runtime: attr::contains_name(&attrs, "needs_panic_runtime"), - no_builtins: attr::contains_name(&attrs, "no_builtins"), - panic_runtime: attr::contains_name(&attrs, "panic_runtime"), - profiler_runtime: attr::contains_name(&attrs, "profiler_runtime"), - sanitizer_runtime: attr::contains_name(&attrs, "sanitizer_runtime"), + compiler_builtins: attr::contains_name(&attrs, sym::compiler_builtins), + needs_allocator: attr::contains_name(&attrs, sym::needs_allocator), + needs_panic_runtime: attr::contains_name(&attrs, sym::needs_panic_runtime), + no_builtins: attr::contains_name(&attrs, sym::no_builtins), + panic_runtime: attr::contains_name(&attrs, sym::panic_runtime), + profiler_runtime: attr::contains_name(&attrs, sym::profiler_runtime), + sanitizer_runtime: attr::contains_name(&attrs, sym::sanitizer_runtime), crate_deps, dylib_dependency_formats, diff --git a/src/librustc_metadata/link_args.rs b/src/librustc_metadata/link_args.rs index 6741b5235db3..cd5951f0e0e3 100644 --- a/src/librustc_metadata/link_args.rs +++ b/src/librustc_metadata/link_args.rs @@ -2,6 +2,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir; use rustc::ty::TyCtxt; use rustc_target::spec::abi::Abi; +use syntax::symbol::sym; pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec { let mut collector = Collector { @@ -37,7 +38,7 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector { } // First, add all of the custom #[link_args] attributes - for m in it.attrs.iter().filter(|a| a.check_name("link_args")) { + for m in it.attrs.iter().filter(|a| a.check_name(sym::link_args)) { if let Some(linkarg) = m.value_str() { self.add_link_args(&linkarg.as_str()); } diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index e0665127c0fb..3e7e740a15c0 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -8,7 +8,7 @@ use rustc_target::spec::abi::Abi; use syntax::attr; use syntax::source_map::Span; use syntax::feature_gate::{self, GateIssue}; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax::{span_err, struct_span_err}; pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec { @@ -47,7 +47,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> { } // Process all of the #[link(..)]-style arguments - for m in it.attrs.iter().filter(|a| a.check_name("link")) { + for m in it.attrs.iter().filter(|a| a.check_name(sym::link)) { let items = match m.meta_item_list() { Some(item) => item, None => continue, @@ -62,7 +62,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> { let mut kind_specified = false; for item in items.iter() { - if item.check_name("kind") { + if item.check_name(sym::kind) { kind_specified = true; let kind = match item.value_str() { Some(name) => name, @@ -81,9 +81,9 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> { cstore::NativeUnknown } }; - } else if item.check_name("name") { + } else if item.check_name(sym::name) { lib.name = item.value_str(); - } else if item.check_name("cfg") { + } else if item.check_name(sym::cfg) { let cfg = match item.meta_item_list() { Some(list) => list, None => continue, // skip like historical compilers @@ -98,7 +98,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> { } else { self.tcx.sess.span_err(cfg[0].span(), "invalid argument for `cfg(..)`"); } - } else if item.check_name("wasm_import_module") { + } else if item.check_name(sym::wasm_import_module) { match item.value_str() { Some(s) => lib.wasm_import_module = Some(s), None => { @@ -156,7 +156,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> { } if lib.cfg.is_some() && !self.tcx.features().link_cfg { feature_gate::emit_feature_err(&self.tcx.sess.parse_sess, - "link_cfg", + sym::link_cfg, span.unwrap(), GateIssue::Language, "is feature gated"); @@ -164,7 +164,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> { if lib.kind == cstore::NativeStaticNobundle && !self.tcx.features().static_nobundle { feature_gate::emit_feature_err(&self.tcx.sess.parse_sess, - "static_nobundle", + sym::static_nobundle, span.unwrap_or_else(|| syntax_pos::DUMMY_SP), GateIssue::Language, "kind=\"static-nobundle\" is feature gated"); diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 8aa6456ebe77..1068305a1134 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -20,6 +20,7 @@ use rustc_data_structures::indexed_vec::Idx; use rustc_errors::{Applicability, DiagnosticBuilder}; use syntax_pos::Span; use syntax::source_map::CompilerDesugaringKind; +use syntax::symbol::sym; use super::borrow_set::BorrowData; use super::{MirBorrowckCtxt}; @@ -1839,7 +1840,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. }) ) = place { let attrs = self.infcx.tcx.get_attrs(*def_id); - let is_thread_local = attrs.iter().any(|attr| attr.check_name("thread_local")); + let is_thread_local = attrs.iter().any(|attr| attr.check_name(sym::thread_local)); debug!( "is_place_thread_local: attrs={:?} is_thread_local={:?}", diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index ad43c8ef66f4..fa490c108c89 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -20,6 +20,7 @@ use std::io; use std::path::PathBuf; use std::rc::Rc; use std::str::FromStr; +use syntax::symbol::sym; use self::mir_util::PassWhere; use polonius_engine::{Algorithm, Output}; @@ -280,7 +281,7 @@ fn dump_annotation<'a, 'gcx, 'tcx>( ) { let tcx = infcx.tcx; let base_def_id = tcx.closure_base_def_id(mir_def_id); - if !tcx.has_attr(base_def_id, "rustc_regions") { + if !tcx.has_attr(base_def_id, sym::rustc_regions) { return; } diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index 83221aca6c5b..a9d23a0afeab 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -1,4 +1,5 @@ use syntax::ast::{self, MetaItem}; +use syntax::symbol::{Symbol, sym}; use rustc_data_structures::bit_set::{BitSet, BitSetOperator, HybridBitSet}; use rustc_data_structures::indexed_vec::Idx; @@ -100,9 +101,9 @@ where fn propagate(&mut self) { self.flow_state.propagate(); } } -pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option { +pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: Symbol) -> Option { for attr in attrs { - if attr.check_name("rustc_mir") { + if attr.check_name(sym::rustc_mir) { let items = attr.meta_item_list(); for item in items.iter().flat_map(|l| l.iter()) { match item.meta_item() { @@ -158,10 +159,8 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitD return None; }; - let print_preflow_to = - name_found(tcx.sess, attributes, "borrowck_graphviz_preflow"); - let print_postflow_to = - name_found(tcx.sess, attributes, "borrowck_graphviz_postflow"); + let print_preflow_to = name_found(tcx.sess, attributes, sym::borrowck_graphviz_preflow); + let print_postflow_to = name_found(tcx.sess, attributes, sym::borrowck_graphviz_postflow); let mut mbcx = DataflowBuilder { def_id, diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 7aed0bace8c0..e8070b21bb8c 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -16,7 +16,7 @@ use rustc::ty::subst::{Kind, InternalSubsts}; use rustc::ty::layout::VariantIdx; use syntax::ast; use syntax::attr; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use rustc::hir; use crate::hair::constant::{lit_to_const, LitToConstError}; @@ -67,7 +67,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { // Some functions always have overflow checks enabled, // however, they may not get codegen'd, depending on // the settings for the crate they are codegened in. - let mut check_overflow = attr::contains_name(attrs, "rustc_inherit_overflow_checks"); + let mut check_overflow = attr::contains_name(attrs, sym::rustc_inherit_overflow_checks); // Respect -C overflow-checks. check_overflow |= tcx.sess.overflow_checks(); diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 01b1780a2054..0576bb53d8f4 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -27,6 +27,7 @@ use std::cmp::Ordering; use std::fmt; use syntax::ast; use syntax::ptr::P; +use syntax::symbol::sym; use syntax_pos::Span; #[derive(Clone, Debug)] @@ -978,7 +979,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { self.tcx.sess.span_err(span, "cannot use unions in constant patterns"); PatternKind::Wild } - ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, "structural_match") => { + ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, sym::structural_match) => { let path = self.tcx.def_path_str(adt_def.did); let msg = format!( "to use a constant of type `{}` in a pattern, \ @@ -990,7 +991,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { PatternKind::Wild } ty::Ref(_, ty::TyS { sty: ty::Adt(adt_def, _), .. }, _) - if !self.tcx.has_attr(adt_def.did, "structural_match") => { + if !self.tcx.has_attr(adt_def.did, sym::structural_match) => { // HACK(estebank): Side-step ICE #53708, but anything other than erroring here // would be wrong. Returnging `PatternKind::Wild` is not technically correct. let path = self.tcx.def_path_str(adt_def.did); diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 58e474658ead..2512525b4bb7 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -2,6 +2,7 @@ use rustc::ty::{self, Ty, TypeAndMut}; use rustc::ty::layout::{self, TyLayout, Size}; use rustc::ty::adjustment::{PointerCast}; use syntax::ast::{FloatTy, IntTy, UintTy}; +use syntax::symbol::sym; use rustc_apfloat::ieee::{Single, Double}; use rustc::mir::interpret::{ @@ -76,9 +77,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> // The src operand does not matter, just its type match src.layout.ty.sty { ty::FnDef(def_id, substs) => { - if self.tcx.has_attr(def_id, "rustc_args_required_const") { - bug!("reifying a fn ptr that requires \ - const arguments"); + if self.tcx.has_attr(def_id, sym::rustc_args_required_const) { + bug!("reifying a fn ptr that requires const arguments"); } let instance: EvalResult<'tcx, _> = ty::Instance::resolve( *self.tcx, diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 078b347fb3f6..fab07a2290eb 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -12,7 +12,7 @@ use rustc::lint::builtin::{SAFE_EXTERN_STATICS, SAFE_PACKED_BORROWS, UNUSED_UNSA use rustc::mir::*; use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext}; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use std::ops::Bound; @@ -612,7 +612,7 @@ fn report_unused_unsafe(tcx: TyCtxt<'_, '_, '_>, fn builtin_derive_def_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option { debug!("builtin_derive_def_id({:?})", def_id); if let Some(impl_def_id) = tcx.impl_of_method(def_id) { - if tcx.has_attr(impl_def_id, "automatically_derived") { + if tcx.has_attr(impl_def_id, sym::automatically_derived) { debug!("builtin_derive_def_id({:?}) - is {:?}", def_id, impl_def_id); Some(impl_def_id) } else { diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 9a39e0717211..579f75ba5165 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -22,6 +22,7 @@ use rustc::middle::lang_items; use rustc::session::config::nightly_options; use syntax::ast::LitKind; use syntax::feature_gate::{emit_feature_err, GateIssue}; +use syntax::symbol::sym; use syntax_pos::{Span, DUMMY_SP}; use std::fmt; @@ -380,8 +381,8 @@ impl Qualif for IsNotPromotable { !allowed || cx.tcx.get_attrs(def_id).iter().any( - |attr| attr.check_name("thread_local" - )) + |attr| attr.check_name(sym::thread_local) + ) } } } @@ -939,7 +940,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { if self.tcx .get_attrs(def_id) .iter() - .any(|attr| attr.check_name("thread_local")) { + .any(|attr| attr.check_name(sym::thread_local)) { if self.mode != Mode::Fn { span_err!(self.tcx.sess, self.span, E0625, "thread-local statics cannot be \ @@ -994,7 +995,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { if let ty::RawPtr(_) = base_ty.sty { if !self.tcx.features().const_raw_ptr_deref { emit_feature_err( - &self.tcx.sess.parse_sess, "const_raw_ptr_deref", + &self.tcx.sess.parse_sess, sym::const_raw_ptr_deref, self.span, GateIssue::Language, &format!( "dereferencing raw pointers in {}s is unstable", @@ -1018,7 +1019,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { Mode::ConstFn => { if !self.tcx.features().const_fn_union { emit_feature_err( - &self.tcx.sess.parse_sess, "const_fn_union", + &self.tcx.sess.parse_sess, sym::const_fn_union, self.span, GateIssue::Language, "unions in const fn are unstable", ); @@ -1123,7 +1124,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { // in const fn and constants require the feature gate // FIXME: make it unsafe inside const fn and constants emit_feature_err( - &self.tcx.sess.parse_sess, "const_raw_ptr_to_usize_cast", + &self.tcx.sess.parse_sess, sym::const_raw_ptr_to_usize_cast, self.span, GateIssue::Language, &format!( "casting pointers to integers in {}s is unstable", @@ -1149,7 +1150,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { // FIXME: make it unsafe to use these operations emit_feature_err( &self.tcx.sess.parse_sess, - "const_compare_raw_pointers", + sym::const_compare_raw_pointers, self.span, GateIssue::Language, &format!("comparing raw pointers inside {}", self.mode), @@ -1210,7 +1211,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { // const eval transmute calls only with the feature gate if !self.tcx.features().const_transmute { emit_feature_err( - &self.tcx.sess.parse_sess, "const_transmute", + &self.tcx.sess.parse_sess, sym::const_transmute, self.span, GateIssue::Language, &format!("The use of std::mem::transmute() \ is gated in {}s", self.mode)); @@ -1249,7 +1250,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { // Don't allow panics in constants without the feature gate. emit_feature_err( &self.tcx.sess.parse_sess, - "const_panic", + sym::const_panic, self.span, GateIssue::Language, &format!("panicking in {}s is unstable", self.mode), @@ -1260,7 +1261,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { // Check `#[unstable]` const fns or `#[rustc_const_unstable]` // functions without the feature gate active in this crate in // order to report a better error message than the one below. - if !self.span.allows_unstable(&feature.as_str()) { + if !self.span.allows_unstable(feature) { let mut err = self.tcx.sess.struct_span_err(self.span, &format!("`{}` is not yet stable as a const fn", self.tcx.def_path_str(def_id))); @@ -1592,7 +1593,7 @@ impl MirPass for QualifyAndPromoteConstants { if mode == Mode::Static { // `#[thread_local]` statics don't have to be `Sync`. for attr in &tcx.get_attrs(def_id)[..] { - if attr.check_name("thread_local") { + if attr.check_name(sym::thread_local) { return; } } @@ -1616,7 +1617,7 @@ impl MirPass for QualifyAndPromoteConstants { fn args_required_const(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option> { let attrs = tcx.get_attrs(def_id); - let attr = attrs.iter().find(|a| a.check_name("rustc_args_required_const"))?; + let attr = attrs.iter().find(|a| a.check_name(sym::rustc_args_required_const))?; let mut ret = FxHashSet::default(); for meta in attr.meta_item_list()? { match meta.literal()?.node { diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index 246f876235d7..815821f6ff03 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -1,5 +1,6 @@ use rustc_target::spec::abi::{Abi}; use syntax::ast; +use syntax::symbol::sym; use syntax_pos::Span; use rustc::ty::{self, TyCtxt}; @@ -27,7 +28,7 @@ impl MirPass for SanityCheck { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource<'tcx>, mir: &mut Mir<'tcx>) { let def_id = src.def_id(); - if !tcx.has_attr(def_id, "rustc_mir") { + if !tcx.has_attr(def_id, sym::rustc_mir) { debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id)); return; } else { @@ -52,16 +53,16 @@ impl MirPass for SanityCheck { DefinitelyInitializedPlaces::new(tcx, mir, &mdpe), |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i])); - if has_rustc_mir_with(&attributes, "rustc_peek_maybe_init").is_some() { + if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_init).is_some() { sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_inits); } - if has_rustc_mir_with(&attributes, "rustc_peek_maybe_uninit").is_some() { + if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_uninit).is_some() { sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_uninits); } - if has_rustc_mir_with(&attributes, "rustc_peek_definite_init").is_some() { + if has_rustc_mir_with(&attributes, sym::rustc_peek_definite_init).is_some() { sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_def_inits); } - if has_rustc_mir_with(&attributes, "stop_after_dataflow").is_some() { + if has_rustc_mir_with(&attributes, sym::stop_after_dataflow).is_some() { tcx.sess.fatal("stop_after_dataflow ended compilation"); } } diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 6cb3161382af..7adf0af31c66 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -15,7 +15,7 @@ use rustc_data_structures::fx::FxHashMap; use syntax::ast::*; use syntax::attr; use syntax::source_map::Spanned; -use syntax::symbol::keywords; +use syntax::symbol::{keywords, sym}; use syntax::ptr::P; use syntax::visit::{self, Visitor}; use syntax::{span_err, struct_span_err, walk_list}; @@ -565,7 +565,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.has_proc_macro_decls = true; } - if attr::contains_name(&item.attrs, "global_allocator") { + if attr::contains_name(&item.attrs, sym::global_allocator) { self.has_global_allocator = true; } @@ -676,8 +676,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } ItemKind::Mod(_) => { // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584). - attr::first_attr_value_str_by_name(&item.attrs, "path"); - if attr::contains_name(&item.attrs, "warn_directory_ownership") { + attr::first_attr_value_str_by_name(&item.attrs, sym::path); + if attr::contains_name(&item.attrs, sym::warn_directory_ownership) { let lint = lint::builtin::LEGACY_DIRECTORY_OWNERSHIP; let msg = "cannot declare a new module at this location"; self.session.buffer_lint(lint, item.id, item.span, msg); diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs index 7041a5593abb..c865845b5e36 100644 --- a/src/librustc_passes/layout_test.rs +++ b/src/librustc_passes/layout_test.rs @@ -12,6 +12,7 @@ use rustc::ty::ParamEnv; use rustc::ty::Ty; use rustc::ty::TyCtxt; use syntax::ast::Attribute; +use syntax::symbol::sym; pub fn test_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { if tcx.features().rustc_attrs { @@ -32,7 +33,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for VarianceTest<'a, 'tcx> { if let ItemKind::Ty(..) = item.node { for attr in self.tcx.get_attrs(item_def_id).iter() { - if attr.check_name("rustc_layout") { + if attr.check_name(sym::rustc_layout) { self.dump_layout_of(item_def_id, item, attr); } } diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 2d35a0de7953..37917aaa4a80 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -25,6 +25,7 @@ use rustc::ty::query::Providers; use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::util::nodemap::{ItemLocalSet, HirIdSet}; use rustc::hir; +use syntax::symbol::sym; use syntax_pos::{Span, DUMMY_SP}; use log::debug; use Promotability::*; @@ -335,7 +336,7 @@ fn check_expr_kind<'a, 'tcx>( if v.in_static { for attr in &v.tcx.get_attrs(did)[..] { - if attr.check_name("thread_local") { + if attr.check_name(sym::thread_local) { debug!("Reference to Static(id={:?}) is unpromotable \ due to a #[thread_local] attribute", did); return NotPromotable; diff --git a/src/librustc_plugin/build.rs b/src/librustc_plugin/build.rs index 31018a7cd7a3..8259419c64ae 100644 --- a/src/librustc_plugin/build.rs +++ b/src/librustc_plugin/build.rs @@ -1,6 +1,7 @@ //! Used by `rustc` when compiling a plugin crate. use syntax::attr; +use syntax::symbol::sym; use syntax_pos::Span; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir; @@ -15,8 +16,7 @@ struct RegistrarFinder { impl<'v> ItemLikeVisitor<'v> for RegistrarFinder { fn visit_item(&mut self, item: &hir::Item) { if let hir::ItemKind::Fn(..) = item.node { - if attr::contains_name(&item.attrs, - "plugin_registrar") { + if attr::contains_name(&item.attrs, sym::plugin_registrar) { self.registrars.push((item.hir_id, item.span)); } } diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs index 8b86bddb29f4..43eddbb653fe 100644 --- a/src/librustc_plugin/load.rs +++ b/src/librustc_plugin/load.rs @@ -11,6 +11,7 @@ use std::mem; use std::path::PathBuf; use syntax::ast; use syntax::span_err; +use syntax::symbol::sym; use syntax_pos::{Span, DUMMY_SP}; /// Pointer to a registrar function. @@ -45,7 +46,7 @@ pub fn load_plugins(sess: &Session, // the feature enabled will result in an error later... if sess.features_untracked().plugin { for attr in &krate.attrs { - if !attr.check_name("plugin") { + if !attr.check_name(sym::plugin) { continue; } diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 5c5b6f232b27..913657b2934e 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -49,7 +49,7 @@ pub struct Registry<'a> { pub llvm_passes: Vec, #[doc(hidden)] - pub attributes: Vec<(String, AttributeType)>, + pub attributes: Vec<(Symbol, AttributeType)>, } impl<'a> Registry<'a> { @@ -169,7 +169,7 @@ impl<'a> Registry<'a> { /// Registered attributes will bypass the `custom_attribute` feature gate. /// `Whitelisted` attributes will additionally not trigger the `unused_attribute` /// lint. `CrateLevel` attributes will not be allowed on anything other than a crate. - pub fn register_attribute(&mut self, name: String, ty: AttributeType) { + pub fn register_attribute(&mut self, name: Symbol, ty: AttributeType) { self.attributes.push((name, ty)); } } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index e561b387389e..cd21713cddf9 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -27,7 +27,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; use syntax::ast::Ident; use syntax::attr; -use syntax::symbol::keywords; +use syntax::symbol::{keywords, sym}; use syntax_pos::Span; use std::{cmp, fmt, mem}; @@ -260,7 +260,8 @@ fn def_id_visibility<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) ctor_vis = ty::Visibility::Restricted( DefId::local(CRATE_DEF_INDEX)); let attrs = tcx.get_attrs(variant.def_id); - span = attr::find_by_name(&attrs, "non_exhaustive").unwrap().span; + span = attr::find_by_name(&attrs, sym::non_exhaustive) + .unwrap().span; descr = "crate-visible"; } @@ -291,7 +292,7 @@ fn def_id_visibility<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) if adt_def.non_enum_variant().is_field_list_non_exhaustive() { ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)); - span = attr::find_by_name(&item.attrs, "non_exhaustive") + span = attr::find_by_name(&item.attrs, sym::non_exhaustive) .unwrap().span; descr = "crate-visible"; } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 3c5760c746fc..cf09e31bb628 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -37,7 +37,7 @@ use syntax::feature_gate::is_builtin_attr; use syntax::parse::token::{self, Token}; use syntax::span_err; use syntax::std_inject::injected_crate_name; -use syntax::symbol::keywords; +use syntax::symbol::{keywords, sym}; use syntax::visit::{self, Visitor}; use syntax_pos::{Span, DUMMY_SP}; @@ -257,7 +257,7 @@ impl<'a> Resolver<'a> { } ast::UseTreeKind::Glob => { let subclass = GlobImport { - is_prelude: attr::contains_name(&item.attrs, "prelude_import"), + is_prelude: attr::contains_name(&item.attrs, sym::prelude_import), max_vis: Cell::new(ty::Visibility::Invisible), }; self.add_import_directive( @@ -427,7 +427,7 @@ impl<'a> Resolver<'a> { let module_kind = ModuleKind::Def(DefKind::Mod, def_id, ident.name); let module = self.arenas.alloc_module(ModuleData { no_implicit_prelude: parent.no_implicit_prelude || { - attr::contains_name(&item.attrs, "no_implicit_prelude") + attr::contains_name(&item.attrs, sym::no_implicit_prelude) }, ..ModuleData::new(Some(parent), module_kind, def_id, expansion, item.span) }); @@ -456,12 +456,12 @@ impl<'a> Resolver<'a> { // Functions introducing procedural macros reserve a slot // in the macro namespace as well (see #52225). - if attr::contains_name(&item.attrs, "proc_macro") || - attr::contains_name(&item.attrs, "proc_macro_attribute") { + if attr::contains_name(&item.attrs, sym::proc_macro) || + attr::contains_name(&item.attrs, sym::proc_macro_attribute) { let res = Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), res.def_id()); self.define(parent, ident, MacroNS, (res, vis, sp, expansion)); } - if let Some(attr) = attr::find_by_name(&item.attrs, "proc_macro_derive") { + if let Some(attr) = attr::find_by_name(&item.attrs, sym::proc_macro_derive) { if let Some(trait_attr) = attr.meta_item_list().and_then(|list| list.get(0).cloned()) { if let Some(ident) = trait_attr.ident() { @@ -518,7 +518,7 @@ impl<'a> Resolver<'a> { let mut ctor_vis = vis; - let has_non_exhaustive = attr::contains_name(&item.attrs, "non_exhaustive"); + let has_non_exhaustive = attr::contains_name(&item.attrs, sym::non_exhaustive); // If the structure is marked as non_exhaustive then lower the visibility // to within the crate. @@ -599,7 +599,7 @@ impl<'a> Resolver<'a> { // If the variant is marked as non_exhaustive then lower the visibility to within the // crate. let mut ctor_vis = vis; - let has_non_exhaustive = attr::contains_name(&variant.node.attrs, "non_exhaustive"); + let has_non_exhaustive = attr::contains_name(&variant.node.attrs, sym::non_exhaustive); if has_non_exhaustive && vis == ty::Visibility::Public { ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)); } @@ -825,7 +825,7 @@ impl<'a> Resolver<'a> { let mut import_all = None; let mut single_imports = Vec::new(); for attr in &item.attrs { - if attr.check_name("macro_use") { + if attr.check_name(sym::macro_use) { if self.current_module.parent.is_some() { span_err!(self.session, item.span, E0468, "an `extern crate` loading macros must be at the crate root"); @@ -908,7 +908,7 @@ impl<'a> Resolver<'a> { /// Returns `true` if this attribute list contains `macro_use`. fn contains_macro_use(&mut self, attrs: &[ast::Attribute]) -> bool { for attr in attrs { - if attr.check_name("macro_escape") { + if attr.check_name(sym::macro_escape) { let msg = "macro_escape is a deprecated synonym for macro_use"; let mut err = self.session.struct_span_warn(attr.span, msg); if let ast::AttrStyle::Inner = attr.style { @@ -916,7 +916,7 @@ impl<'a> Resolver<'a> { } else { err.emit(); } - } else if !attr.check_name("macro_use") { + } else if !attr.check_name(sym::macro_use) { continue; } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 18da89b9099a..0dd6f378730f 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -43,7 +43,7 @@ use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy}; use syntax::ext::base::SyntaxExtension; use syntax::ext::base::Determinacy::{self, Determined, Undetermined}; use syntax::ext::base::MacroKind; -use syntax::symbol::{Symbol, keywords}; +use syntax::symbol::{Symbol, keywords, sym}; use syntax::util::lev_distance::find_best_match_for_name; use syntax::visit::{self, FnKind, Visitor}; @@ -1964,7 +1964,7 @@ impl<'a> Resolver<'a> { keywords::Invalid.name(), ); let graph_root = arenas.alloc_module(ModuleData { - no_implicit_prelude: attr::contains_name(&krate.attrs, "no_implicit_prelude"), + no_implicit_prelude: attr::contains_name(&krate.attrs, sym::no_implicit_prelude), ..ModuleData::new(None, root_module_kind, root_def_id, Mark::root(), krate.span) }); let mut module_map = FxHashMap::default(); @@ -1978,9 +1978,9 @@ impl<'a> Resolver<'a> { session.opts.externs.iter().map(|kv| (Ident::from_str(kv.0), Default::default())) .collect(); - if !attr::contains_name(&krate.attrs, "no_core") { + if !attr::contains_name(&krate.attrs, sym::no_core) { extern_prelude.insert(Ident::from_str("core"), Default::default()); - if !attr::contains_name(&krate.attrs, "no_std") { + if !attr::contains_name(&krate.attrs, sym::no_std) { extern_prelude.insert(Ident::from_str("std"), Default::default()); if session.rust_2018() { extern_prelude.insert(Ident::from_str("meta"), Default::default()); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 79a92d595c2e..62f2768888ad 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -22,7 +22,7 @@ use syntax::ext::tt::macro_rules; use syntax::feature_gate::{ feature_err, is_builtin_attr_name, AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES, }; -use syntax::symbol::{Symbol, keywords}; +use syntax::symbol::{Symbol, keywords, sym}; use syntax::visit::Visitor; use syntax::util::lev_distance::find_best_match_for_name; use syntax_pos::{Span, DUMMY_SP}; @@ -313,7 +313,8 @@ impl<'a> Resolver<'a> { if !features.rustc_attrs { let msg = "unless otherwise specified, attributes with the prefix \ `rustc_` are reserved for internal compiler diagnostics"; - self.report_unknown_attribute(path.span, &name, msg, "rustc_attrs"); + self.report_unknown_attribute(path.span, &name, msg, + sym::rustc_attrs); } } else if !features.custom_attribute { let msg = format!("The attribute `{}` is currently unknown to the \ @@ -323,7 +324,7 @@ impl<'a> Resolver<'a> { path.span, &name, &msg, - "custom_attribute", + sym::custom_attribute, ); } } @@ -345,7 +346,7 @@ impl<'a> Resolver<'a> { Ok((res, self.get_macro(res))) } - fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: &str) { + fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: Symbol) { let mut err = feature_err( &self.session.parse_sess, feature, @@ -693,7 +694,7 @@ impl<'a> Resolver<'a> { WhereToResolve::LegacyPluginHelpers => { if (use_prelude || rust_2015) && self.session.plugin_attributes.borrow().iter() - .any(|(name, _)| ident.name == &**name) { + .any(|(name, _)| ident.name == *name) { let binding = (Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper), ty::Visibility::Public, DUMMY_SP, Mark::root()) .to_name_binding(self.arenas); @@ -1106,7 +1107,7 @@ impl<'a> Resolver<'a> { let ident = ident.modern(); self.macro_names.insert(ident); let res = Res::Def(DefKind::Macro(MacroKind::Bang), def_id); - let is_macro_export = attr::contains_name(&item.attrs, "macro_export"); + let is_macro_export = attr::contains_name(&item.attrs, sym::macro_export); let vis = if is_macro_export { ty::Visibility::Public } else { @@ -1124,7 +1125,7 @@ impl<'a> Resolver<'a> { self.define(module, ident, MacroNS, (res, vis, item.span, expansion, IsMacroExport)); } else { - if !attr::contains_name(&item.attrs, "rustc_doc_only_macro") { + if !attr::contains_name(&item.attrs, sym::rustc_doc_only_macro) { self.check_reserved_macro_name(ident, MacroNS); } self.unused_macros.insert(def_id); diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index f3e0fb32ec2d..cb2454aa4b56 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -879,7 +879,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { let mut result = String::new(); for attr in attrs { - if attr.check_name("doc") { + if attr.check_name(sym::doc) { if let Some(val) = attr.value_str() { if attr.is_sugared_doc { result.push_str(&strip_doc_comment_decoration(&val.as_str())); @@ -889,10 +889,10 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { result.push('\n'); } else if let Some(meta_list) = attr.meta_item_list() { meta_list.into_iter() - .filter(|it| it.check_name("include")) + .filter(|it| it.check_name(sym::include)) .filter_map(|it| it.meta_item_list().map(|l| l.to_owned())) .flat_map(|it| it) - .filter(|meta| meta.check_name("contents")) + .filter(|meta| meta.check_name(sym::contents)) .filter_map(|meta| meta.value_str()) .for_each(|val| { result.push_str(&val.as_str()); diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs index 50c213026329..580b1571e52b 100644 --- a/src/librustc_traits/lowering/mod.rs +++ b/src/librustc_traits/lowering/mod.rs @@ -21,6 +21,7 @@ use rustc::ty::query::Providers; use rustc::ty::{self, List, TyCtxt}; use rustc::ty::subst::{Subst, InternalSubsts}; use syntax::ast; +use syntax::symbol::sym; use std::iter; @@ -640,11 +641,11 @@ impl<'a, 'tcx> ClauseDumper<'a, 'tcx> { for attr in attrs { let mut clauses = None; - if attr.check_name("rustc_dump_program_clauses") { + if attr.check_name(sym::rustc_dump_program_clauses) { clauses = Some(self.tcx.program_clauses_for(def_id)); } - if attr.check_name("rustc_dump_env_program_clauses") { + if attr.check_name(sym::rustc_dump_env_program_clauses) { let environment = self.tcx.environment(def_id); clauses = Some(self.tcx.program_clauses_for_env(environment)); } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index da47ccf38a02..caefe1242115 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -25,6 +25,7 @@ use syntax::ast; use syntax::feature_gate::{GateIssue, emit_feature_err}; use syntax::ptr::P; use syntax::util::lev_distance::find_best_match_for_name; +use syntax::symbol::sym; use syntax_pos::{DUMMY_SP, Span, MultiSpan}; use crate::util::common::ErrorReported; use crate::util::nodemap::FxHashMap; @@ -802,7 +803,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } else { "parenthetical notation is only stable when used with `Fn`-family traits" }; - emit_feature_err(&self.tcx().sess.parse_sess, "unboxed_closures", + emit_feature_err(&self.tcx().sess.parse_sess, sym::unboxed_closures, span, GateIssue::Language, msg); } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 008975068e58..90b2643d165b 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -68,6 +68,7 @@ use smallvec::{smallvec, SmallVec}; use std::ops::Deref; use syntax::feature_gate; use syntax::ptr::P; +use syntax::symbol::sym; use syntax_pos; struct Coerce<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { @@ -620,7 +621,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion { feature_gate::emit_feature_err(&self.tcx.sess.parse_sess, - "unsized_tuple_coercion", + sym::unsized_tuple_coercion, self.cause.span, feature_gate::GateIssue::Language, feature_gate::EXPLAIN_UNSIZED_TUPLE_COERCION); diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 1699447886ae..8d68179b495c 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -2,6 +2,7 @@ use crate::check::FnCtxt; use rustc::infer::InferOk; use rustc::traits::{self, ObligationCause, ObligationCauseCode}; +use syntax::symbol::sym; use syntax::util::parser::PREC_POSTFIX; use syntax_pos::Span; use rustc::hir; @@ -197,7 +198,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // // FIXME? Other potential candidate methods: `as_ref` and // `as_mut`? - .find(|a| a.check_name("rustc_conversion_suggestion")).is_some() + .find(|a| a.check_name(sym::rustc_conversion_suggestion)).is_some() }); methods diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index dc73ada1506c..a184a2daeb6a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -123,7 +123,7 @@ use syntax::attr; use syntax::feature_gate::{GateIssue, emit_feature_err}; use syntax::ptr::P; use syntax::source_map::{DUMMY_SP, original_sp}; -use syntax::symbol::{Symbol, LocalInternedString, keywords}; +use syntax::symbol::{Symbol, LocalInternedString, keywords, sym}; use syntax::util::lev_distance::find_best_match_for_name; use std::cell::{Cell, RefCell, Ref, RefMut}; @@ -1840,7 +1840,7 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if vs.is_empty() { let attributes = tcx.get_attrs(def_id); - if let Some(attr) = attr::find_by_name(&attributes, "repr") { + if let Some(attr) = attr::find_by_name(&attributes, sym::repr) { struct_span_err!( tcx.sess, attr.span, E0084, "unsupported representation for zero-variant enum") @@ -1853,7 +1853,7 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 { if !tcx.features().repr128 { emit_feature_err(&tcx.sess.parse_sess, - "repr128", + sym::repr128, sp, GateIssue::Language, "repr with 128-bit type is unstable"); @@ -5499,7 +5499,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span: Span) { // We're only interested in functions tagged with // #[rustc_args_required_const], so ignore anything that's not. - if !self.tcx.has_attr(def_id, "rustc_args_required_const") { + if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) { return } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index fd7d6fe694cc..b009c8ea6dce 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -13,6 +13,7 @@ use rustc::infer::opaque_types::may_define_existential_type; use syntax::ast; use syntax::feature_gate::{self, GateIssue}; use syntax_pos::Span; +use syntax::symbol::sym; use errors::{DiagnosticBuilder, DiagnosticId}; use rustc::hir::itemlikevisit::ParItemLikeVisitor; @@ -796,7 +797,7 @@ fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, // report error, would have worked with arbitrary_self_types feature_gate::feature_err( &fcx.tcx.sess.parse_sess, - "arbitrary_self_types", + sym::arbitrary_self_types, span, GateIssue::Language, &format!( diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index bf978352faee..ecb8e09ec246 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -16,6 +16,7 @@ use rustc::mir::interpret::ConstValue; use rustc::util::nodemap::DefIdSet; use rustc_data_structures::sync::Lrc; use std::mem; +use syntax::symbol::sym; use syntax_pos::Span; /////////////////////////////////////////////////////////////////////////// @@ -36,8 +37,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let item_def_id = self.tcx.hir().local_def_id(item_id); // This attribute causes us to dump some writeback information - // in the form of errors, which is used for unit tests. - let rustc_dump_user_substs = self.tcx.has_attr(item_def_id, "rustc_dump_user_substs"); + // in the form of errors, which is uSymbolfor unit tests. + let rustc_dump_user_substs = self.tcx.has_attr(item_def_id, sym::rustc_dump_user_substs); let mut wbcx = WritebackCx::new(self, body, rustc_dump_user_substs); for arg in &body.arguments { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4185999fdd6d..29b470894095 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -39,7 +39,7 @@ use syntax::ast::{Ident, MetaItemKind}; use syntax::attr::{InlineAttr, OptimizeAttr, list_contains_name, mark_used}; use syntax::source_map::Spanned; use syntax::feature_gate; -use syntax::symbol::{keywords, Symbol}; +use syntax::symbol::{keywords, Symbol, sym}; use syntax_pos::{Span, DUMMY_SP}; use rustc::hir::def::{CtorKind, Res, DefKind}; @@ -750,7 +750,7 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty:: _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"), }; - let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar"); + let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar); if paren_sugar && !tcx.features().unboxed_closures { let mut err = tcx.sess.struct_span_err( item.span, @@ -765,7 +765,7 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty:: err.emit(); } - let is_marker = tcx.has_attr(def_id, "marker"); + let is_marker = tcx.has_attr(def_id, sym::marker); let def_path_hash = tcx.def_path_hash(def_id); let def = ty::TraitDef::new(def_id, unsafety, paren_sugar, is_auto, is_marker, def_path_hash); tcx.alloc_trait_def(def) @@ -2382,7 +2382,7 @@ fn from_target_feature( tcx: TyCtxt<'_, '_, '_>, id: DefId, attr: &ast::Attribute, - whitelist: &FxHashMap>, + whitelist: &FxHashMap>, target_features: &mut Vec, ) { let list = match attr.meta_item_list() { @@ -2392,7 +2392,7 @@ fn from_target_feature( let rust_features = tcx.features(); for item in list { // Only `enable = ...` is accepted in the meta item list - if !item.check_name("enable") { + if !item.check_name(sym::enable) { let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \ currently"; tcx.sess.span_err(item.span(), &msg); @@ -2435,29 +2435,29 @@ fn from_target_feature( }; // Only allow features whose feature gates have been enabled - let allowed = match feature_gate.as_ref().map(|s| &**s) { - Some("arm_target_feature") => rust_features.arm_target_feature, - Some("aarch64_target_feature") => rust_features.aarch64_target_feature, - Some("hexagon_target_feature") => rust_features.hexagon_target_feature, - Some("powerpc_target_feature") => rust_features.powerpc_target_feature, - Some("mips_target_feature") => rust_features.mips_target_feature, - Some("avx512_target_feature") => rust_features.avx512_target_feature, - Some("mmx_target_feature") => rust_features.mmx_target_feature, - Some("sse4a_target_feature") => rust_features.sse4a_target_feature, - Some("tbm_target_feature") => rust_features.tbm_target_feature, - Some("wasm_target_feature") => rust_features.wasm_target_feature, - Some("cmpxchg16b_target_feature") => rust_features.cmpxchg16b_target_feature, - Some("adx_target_feature") => rust_features.adx_target_feature, - Some("movbe_target_feature") => rust_features.movbe_target_feature, - Some("rtm_target_feature") => rust_features.rtm_target_feature, - Some("f16c_target_feature") => rust_features.f16c_target_feature, + let allowed = match feature_gate.as_ref().map(|s| *s) { + Some(sym::arm_target_feature) => rust_features.arm_target_feature, + Some(sym::aarch64_target_feature) => rust_features.aarch64_target_feature, + Some(sym::hexagon_target_feature) => rust_features.hexagon_target_feature, + Some(sym::powerpc_target_feature) => rust_features.powerpc_target_feature, + Some(sym::mips_target_feature) => rust_features.mips_target_feature, + Some(sym::avx512_target_feature) => rust_features.avx512_target_feature, + Some(sym::mmx_target_feature) => rust_features.mmx_target_feature, + Some(sym::sse4a_target_feature) => rust_features.sse4a_target_feature, + Some(sym::tbm_target_feature) => rust_features.tbm_target_feature, + Some(sym::wasm_target_feature) => rust_features.wasm_target_feature, + Some(sym::cmpxchg16b_target_feature) => rust_features.cmpxchg16b_target_feature, + Some(sym::adx_target_feature) => rust_features.adx_target_feature, + Some(sym::movbe_target_feature) => rust_features.movbe_target_feature, + Some(sym::rtm_target_feature) => rust_features.rtm_target_feature, + Some(sym::f16c_target_feature) => rust_features.f16c_target_feature, Some(name) => bug!("unknown target feature gate {}", name), None => true, }; if !allowed && id.is_local() { feature_gate::emit_feature_err( &tcx.sess.parse_sess, - feature_gate.as_ref().unwrap(), + feature_gate.unwrap(), item.span(), feature_gate::GateIssue::Language, &format!("the target feature `{}` is currently unstable", feature), @@ -2512,13 +2512,13 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen let mut inline_span = None; for attr in attrs.iter() { - if attr.check_name("cold") { + if attr.check_name(sym::cold) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD; - } else if attr.check_name("allocator") { + } else if attr.check_name(sym::allocator) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR; - } else if attr.check_name("unwind") { + } else if attr.check_name(sym::unwind) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::UNWIND; - } else if attr.check_name("ffi_returns_twice") { + } else if attr.check_name(sym::ffi_returns_twice) { if tcx.is_foreign_item(id) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_RETURNS_TWICE; } else { @@ -2530,21 +2530,21 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen "`#[ffi_returns_twice]` may only be used on foreign functions" ).emit(); } - } else if attr.check_name("rustc_allocator_nounwind") { + } else if attr.check_name(sym::rustc_allocator_nounwind) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND; - } else if attr.check_name("naked") { + } else if attr.check_name(sym::naked) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED; - } else if attr.check_name("no_mangle") { + } else if attr.check_name(sym::no_mangle) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE; - } else if attr.check_name("rustc_std_internal_symbol") { + } else if attr.check_name(sym::rustc_std_internal_symbol) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL; - } else if attr.check_name("no_debug") { + } else if attr.check_name(sym::no_debug) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_DEBUG; - } else if attr.check_name("used") { + } else if attr.check_name(sym::used) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED; - } else if attr.check_name("thread_local") { + } else if attr.check_name(sym::thread_local) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL; - } else if attr.check_name("export_name") { + } else if attr.check_name(sym::export_name) { if let Some(s) = attr.value_str() { if s.as_str().contains("\0") { // `#[export_name = ...]` will be converted to a null-terminated string, @@ -2558,7 +2558,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen } codegen_fn_attrs.export_name = Some(s); } - } else if attr.check_name("target_feature") { + } else if attr.check_name(sym::target_feature) { if tcx.fn_sig(id).unsafety() == Unsafety::Normal { let msg = "#[target_feature(..)] can only be applied to \ `unsafe` function"; @@ -2571,11 +2571,11 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen &whitelist, &mut codegen_fn_attrs.target_features, ); - } else if attr.check_name("linkage") { + } else if attr.check_name(sym::linkage) { if let Some(val) = attr.value_str() { codegen_fn_attrs.linkage = Some(linkage_by_name(tcx, id, &val.as_str())); } - } else if attr.check_name("link_section") { + } else if attr.check_name(sym::link_section) { if let Some(val) = attr.value_str() { if val.as_str().bytes().any(|b| b == 0) { let msg = format!( @@ -2588,7 +2588,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen codegen_fn_attrs.link_section = Some(val); } } - } else if attr.check_name("link_name") { + } else if attr.check_name(sym::link_name) { codegen_fn_attrs.link_name = attr.value_str(); } } @@ -2613,9 +2613,9 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen "expected one argument" ); InlineAttr::None - } else if list_contains_name(&items[..], "always") { + } else if list_contains_name(&items[..], sym::always) { InlineAttr::Always - } else if list_contains_name(&items[..], "never") { + } else if list_contains_name(&items[..], sym::never) { InlineAttr::Never } else { span_err!( @@ -2649,9 +2649,9 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen if items.len() != 1 { err(attr.span, "expected one argument"); OptimizeAttr::None - } else if list_contains_name(&items[..], "size") { + } else if list_contains_name(&items[..], sym::size) { OptimizeAttr::Size - } else if list_contains_name(&items[..], "speed") { + } else if list_contains_name(&items[..], sym::speed) { OptimizeAttr::Speed } else { err(items[0].span(), "invalid argument"); diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs index e3e2fe7106a0..a6b5b99982ec 100644 --- a/src/librustc_typeck/outlives/mod.rs +++ b/src/librustc_typeck/outlives/mod.rs @@ -5,6 +5,7 @@ use rustc::ty::query::Providers; use rustc::ty::subst::UnpackedKind; use rustc::ty::{self, CratePredicatesMap, TyCtxt}; use rustc_data_structures::sync::Lrc; +use syntax::symbol::sym; mod explicit; mod implicit_infer; @@ -40,7 +41,7 @@ fn inferred_outlives_of<'a, 'tcx>( .map(|p| *p) .unwrap_or(&[]); - if tcx.has_attr(item_def_id, "rustc_outlives") { + if tcx.has_attr(item_def_id, sym::rustc_outlives) { let mut pred: Vec = predicates .iter() .map(|out_pred| match out_pred { diff --git a/src/librustc_typeck/outlives/test.rs b/src/librustc_typeck/outlives/test.rs index e10c83612071..54fd4fad1d19 100644 --- a/src/librustc_typeck/outlives/test.rs +++ b/src/librustc_typeck/outlives/test.rs @@ -1,6 +1,7 @@ use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::TyCtxt; +use syntax::symbol::sym; pub fn test_inferred_outlives<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.hir() @@ -18,7 +19,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for OutlivesTest<'a, 'tcx> { // For unit testing: check for a special "rustc_outlives" // attribute and report an error with various results if found. - if self.tcx.has_attr(item_def_id, "rustc_outlives") { + if self.tcx.has_attr(item_def_id, sym::rustc_outlives) { let inferred_outlives_of = self.tcx.inferred_outlives_of(item_def_id); span_err!( self.tcx.sess, diff --git a/src/librustc_typeck/variance/test.rs b/src/librustc_typeck/variance/test.rs index d04b1b276a2c..b5195826b863 100644 --- a/src/librustc_typeck/variance/test.rs +++ b/src/librustc_typeck/variance/test.rs @@ -1,6 +1,7 @@ use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::TyCtxt; +use syntax::symbol::sym; pub fn test_variance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.hir().krate().visit_all_item_likes(&mut VarianceTest { tcx }); @@ -16,7 +17,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for VarianceTest<'a, 'tcx> { // For unit testing: check for a special "rustc_variance" // attribute and report an error with various results if found. - if self.tcx.has_attr(item_def_id, "rustc_variance") { + if self.tcx.has_attr(item_def_id, sym::rustc_variance) { let variances_of = self.tcx.variances_of(item_def_id); span_err!(self.tcx.sess, item.span, diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index d9d6b8e07e99..15108a7dbb91 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -4,6 +4,7 @@ use std::iter::once; use syntax::ast; use syntax::ext::base::{MacroKind, SyntaxExtension}; +use syntax::symbol::sym; use syntax_pos::Span; use rustc::hir; @@ -186,7 +187,7 @@ pub fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait { let generics = (cx.tcx.generics_of(did), &predicates).clean(cx); let generics = filter_non_trait_generics(did, generics); let (generics, supertrait_bounds) = separate_supertrait_bounds(generics); - let is_spotlight = load_attrs(cx, did).has_doc_flag("spotlight"); + let is_spotlight = load_attrs(cx, did).has_doc_flag(sym::spotlight); let is_auto = cx.tcx.trait_is_auto(did); clean::Trait { auto: auto_trait, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3a260db80652..6790b13dbf8d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -32,6 +32,7 @@ use syntax::ext::base::MacroKind; use syntax::source_map::{dummy_spanned, Spanned}; use syntax::ptr::P; use syntax::symbol::keywords::{self, Keyword}; +use syntax::symbol::{Symbol, sym}; use syntax::symbol::InternedString; use syntax_pos::{self, Pos, FileName}; @@ -170,7 +171,7 @@ impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { // `compiler_builtins` should be masked too, but we can't apply // `#[doc(masked)]` to the injected `extern crate` because it's unstable. if it.is_extern_crate() - && (it.attrs.has_doc_flag("masked") + && (it.attrs.has_doc_flag(sym::masked) || self.cx.tcx.is_compiler_builtins(it.def_id.krate)) { masked_crates.insert(it.def_id.krate); @@ -261,9 +262,9 @@ impl Clean for CrateNum { if let Res::Def(DefKind::Mod, def_id) = res { let attrs = cx.tcx.get_attrs(def_id).clean(cx); let mut prim = None; - for attr in attrs.lists("doc") { + for attr in attrs.lists(sym::doc) { if let Some(v) = attr.value_str() { - if attr.check_name("primitive") { + if attr.check_name(sym::primitive) { prim = PrimitiveType::from_str(&v.as_str()); if prim.is_some() { break; @@ -305,9 +306,9 @@ impl Clean for CrateNum { if let Res::Def(DefKind::Mod, def_id) = res { let attrs = cx.tcx.get_attrs(def_id).clean(cx); let mut keyword = None; - for attr in attrs.lists("doc") { + for attr in attrs.lists(sym::doc) { if let Some(v) = attr.value_str() { - if attr.check_name("keyword") { + if attr.check_name(sym::keyword) { keyword = Keyword::from_str(&v.as_str()).ok() .map(|x| x.name().to_string()); if keyword.is_some() { @@ -501,7 +502,7 @@ impl Item { pub fn is_non_exhaustive(&self) -> bool { self.attrs.other_attrs.iter() - .any(|a| a.check_name("non_exhaustive")) + .any(|a| a.check_name(sym::non_exhaustive)) } /// Returns a documentation-level item type from the item. @@ -669,7 +670,7 @@ impl Clean for doctree::Module { pub struct ListAttributesIter<'a> { attrs: slice::Iter<'a, ast::Attribute>, current_list: vec::IntoIter, - name: &'a str + name: Symbol, } impl<'a> Iterator for ListAttributesIter<'a> { @@ -702,11 +703,11 @@ impl<'a> Iterator for ListAttributesIter<'a> { pub trait AttributesExt { /// Finds an attribute as List and returns the list of attributes nested inside. - fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a>; + fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a>; } impl AttributesExt for [ast::Attribute] { - fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a> { + fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> { ListAttributesIter { attrs: self.iter(), current_list: Vec::new().into_iter(), @@ -717,11 +718,11 @@ impl AttributesExt for [ast::Attribute] { pub trait NestedAttributesExt { /// Returns `true` if the attribute list contains a specific `Word` - fn has_word(self, word: &str) -> bool; + fn has_word(self, word: Symbol) -> bool; } impl> NestedAttributesExt for I { - fn has_word(self, word: &str) -> bool { + fn has_word(self, word: Symbol) -> bool { self.into_iter().any(|attr| attr.is_word() && attr.check_name(word)) } } @@ -803,7 +804,7 @@ impl Attributes { if let ast::MetaItemKind::List(ref nmis) = mi.node { if nmis.len() == 1 { if let MetaItem(ref cfg_mi) = nmis[0] { - if cfg_mi.check_name("cfg") { + if cfg_mi.check_name(sym::cfg) { if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.node { if cfg_nmis.len() == 1 { if let MetaItem(ref content_mi) = cfg_nmis[0] { @@ -827,7 +828,7 @@ impl Attributes { { mi.meta_item_list().and_then(|list| { for meta in list { - if meta.check_name("include") { + if meta.check_name(sym::include) { // the actual compiled `#[doc(include="filename")]` gets expanded to // `#[doc(include(file="filename", contents="file contents")]` so we need to // look for that instead @@ -836,11 +837,11 @@ impl Attributes { let mut contents: Option = None; for it in list { - if it.check_name("file") { + if it.check_name(sym::file) { if let Some(name) = it.value_str() { filename = Some(name.to_string()); } - } else if it.check_name("contents") { + } else if it.check_name(sym::contents) { if let Some(docs) = it.value_str() { contents = Some(docs.to_string()); } @@ -860,9 +861,9 @@ impl Attributes { }) } - pub fn has_doc_flag(&self, flag: &str) -> bool { + pub fn has_doc_flag(&self, flag: Symbol) -> bool { for attr in &self.other_attrs { - if !attr.check_name("doc") { continue; } + if !attr.check_name(sym::doc) { continue; } if let Some(items) = attr.meta_item_list() { if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name(flag)) { @@ -883,7 +884,7 @@ impl Attributes { let other_attrs = attrs.iter().filter_map(|attr| { attr.with_desugared_doc(|attr| { - if attr.check_name("doc") { + if attr.check_name(sym::doc) { if let Some(mi) = attr.meta() { if let Some(value) = mi.value_str() { // Extracted #[doc = "..."] @@ -925,8 +926,8 @@ impl Attributes { // treat #[target_feature(enable = "feat")] attributes as if they were // #[doc(cfg(target_feature = "feat"))] attributes as well - for attr in attrs.lists("target_feature") { - if attr.check_name("enable") { + for attr in attrs.lists(sym::target_feature) { + if attr.check_name(sym::enable) { if let Some(feat) = attr.value_str() { let meta = attr::mk_name_value_item_str(Ident::from_str("target_feature"), dummy_spanned(feat)); @@ -938,7 +939,7 @@ impl Attributes { } let inner_docs = attrs.iter() - .filter(|a| a.check_name("doc")) + .filter(|a| a.check_name(sym::doc)) .next() .map_or(true, |a| a.style == AttrStyle::Inner); @@ -1039,7 +1040,7 @@ impl Hash for Attributes { } impl AttributesExt for Attributes { - fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a> { + fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> { self.other_attrs.lists(name) } } @@ -2133,7 +2134,7 @@ pub struct Trait { impl Clean for doctree::Trait { fn clean(&self, cx: &DocContext<'_>) -> Item { let attrs = self.attrs.clean(cx); - let is_spotlight = attrs.has_doc_flag("spotlight"); + let is_spotlight = attrs.has_doc_flag(sym::spotlight); Item { name: Some(self.name.clean(cx)), attrs: attrs, @@ -3893,8 +3894,8 @@ impl Clean> for doctree::ExternCrate { fn clean(&self, cx: &DocContext<'_>) -> Vec { let please_inline = self.vis.node.is_pub() && self.attrs.iter().any(|a| { - a.check_name("doc") && match a.meta_item_list() { - Some(l) => attr::list_contains_name(&l, "inline"), + a.check_name(sym::doc) && match a.meta_item_list() { + Some(l) => attr::list_contains_name(&l, sym::inline), None => false, } }); @@ -3935,15 +3936,15 @@ impl Clean> for doctree::Import { // #[doc(no_inline)] attribute is present. // Don't inline doc(hidden) imports so they can be stripped at a later stage. let mut denied = !self.vis.node.is_pub() || self.attrs.iter().any(|a| { - a.check_name("doc") && match a.meta_item_list() { - Some(l) => attr::list_contains_name(&l, "no_inline") || - attr::list_contains_name(&l, "hidden"), + a.check_name(sym::doc) && match a.meta_item_list() { + Some(l) => attr::list_contains_name(&l, sym::no_inline) || + attr::list_contains_name(&l, sym::hidden), None => false, } }); // Also check whether imports were asked to be inlined, in case we're trying to re-export a // crate in Rust 2018+ - let please_inline = self.attrs.lists("doc").has_word("inline"); + let please_inline = self.attrs.lists(sym::doc).has_word(sym::inline); let path = self.path.clean(cx); let inner = if self.glob { if !denied { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index e91e3a029dac..1b099fbd91d1 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -18,6 +18,7 @@ use rustc_target::spec::TargetTriple; use syntax::source_map; use syntax::feature_gate::UnstableFeatures; use syntax::json::JsonEmitter; +use syntax::symbol::sym; use errors; use errors::emitter::{Emitter, EmitterWriter}; use parking_lot::ReentrantMutex; @@ -415,7 +416,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt // Process all of the crate attributes, extracting plugin metadata along // with the passes which we are supposed to run. - for attr in krate.module.as_ref().unwrap().attrs.lists("doc") { + for attr in krate.module.as_ref().unwrap().attrs.lists(sym::doc) { let diag = ctxt.sess().diagnostic(); let name = attr.name_or_empty(); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 472192a64649..cbaa911eccca 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -50,6 +50,7 @@ use syntax::ast; use syntax::ext::base::MacroKind; use syntax::source_map::FileName; use syntax::feature_gate::UnstableFeatures; +use syntax::symbol::sym; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId}; use rustc::middle::privacy::AccessLevels; use rustc::middle::stability; @@ -571,7 +572,7 @@ pub fn run(mut krate: clean::Crate, // Crawl the crate attributes looking for attributes which control how we're // going to emit HTML if let Some(attrs) = krate.module.as_ref().map(|m| &m.attrs) { - for attr in attrs.lists("doc") { + for attr in attrs.lists(sym::doc) { match (attr.name_or_empty().get(), attr.value_str()) { ("html_favicon_url", Some(s)) => { scx.layout.favicon = s.to_string(); @@ -1388,8 +1389,8 @@ fn extern_location(e: &clean::ExternalCrate, extern_url: Option<&str>, dst: &Pat // Failing that, see if there's an attribute specifying where to find this // external crate - e.attrs.lists("doc") - .filter(|a| a.check_name("html_root_url")) + e.attrs.lists(sym::doc) + .filter(|a| a.check_name(sym::html_root_url)) .filter_map(|a| a.value_str()) .map(|url| { let mut url = url.to_string(); @@ -1779,8 +1780,8 @@ impl<'a> Cache { let path = self.paths.get(&item.def_id) .map(|p| p.0[..p.0.len() - 1].join("::")) .unwrap_or("std".to_owned()); - for alias in item.attrs.lists("doc") - .filter(|a| a.check_name("alias")) + for alias in item.attrs.lists(sym::doc) + .filter(|a| a.check_name(sym::alias)) .filter_map(|a| a.value_str() .map(|s| s.to_string().replace("\"", ""))) .filter(|v| !v.is_empty()) diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index fe407fa24d93..4ee09f7096b6 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -5,6 +5,7 @@ use crate::passes::Pass; use syntax::attr; use syntax_pos::FileName; +use syntax::symbol::sym; use std::collections::BTreeMap; use std::ops; @@ -131,7 +132,7 @@ impl fold::DocFolder for CoverageCalculator { return Some(i); } clean::ImplItem(ref impl_) - if attr::contains_name(&i.attrs.other_attrs, "automatically_derived") + if attr::contains_name(&i.attrs.other_attrs, sym::automatically_derived) || impl_.synthetic || impl_.blanket_impl.is_some() => { // built-in derives get the `#[automatically_derived]` attribute, and diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 8d33cd72e29a..70cd4b72199b 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -5,6 +5,7 @@ use super::Pass; use rustc::util::nodemap::FxHashSet; use rustc::hir::def_id::DefId; +use syntax::symbol::sym; pub const COLLECT_TRAIT_IMPLS: Pass = Pass { name: "collect-trait-impls", @@ -68,7 +69,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { inline::build_impl(cx, def_id, &mut new_items); // FIXME(eddyb) is this `doc(hidden)` check needed? - if !cx.tcx.get_attrs(def_id).lists("doc").has_word("hidden") { + if !cx.tcx.get_attrs(def_id).lists(sym::doc).has_word(sym::hidden) { let self_ty = cx.tcx.type_of(def_id); let impls = get_auto_trait_and_blanket_impls(cx, self_ty, def_id); let mut renderinfo = cx.renderinfo.borrow_mut(); @@ -154,7 +155,7 @@ impl<'a, 'tcx> DocFolder for SyntheticImplCollector<'a, 'tcx> { fn fold_item(&mut self, i: Item) -> Option { if i.is_struct() || i.is_enum() || i.is_union() { // FIXME(eddyb) is this `doc(hidden)` check needed? - if !self.cx.tcx.get_attrs(i.def_id).lists("doc").has_word("hidden") { + if !self.cx.tcx.get_attrs(i.def_id).lists(sym::doc).has_word(sym::hidden) { self.impls.extend(get_auto_trait_and_blanket_impls( self.cx, self.cx.tcx.type_of(i.def_id), diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index 240299c212ab..da8977544f64 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -1,5 +1,6 @@ use rustc::util::nodemap::DefIdSet; use std::mem; +use syntax::symbol::sym; use crate::clean::{self, AttributesExt, NestedAttributesExt}; use crate::clean::Item; @@ -37,7 +38,7 @@ struct Stripper<'a> { impl<'a> DocFolder for Stripper<'a> { fn fold_item(&mut self, i: Item) -> Option { - if i.attrs.lists("doc").has_word("hidden") { + if i.attrs.lists(sym::doc).has_word(sym::hidden) { debug!("strip_hidden: stripping {} {:?}", i.type_(), i.name); // use a dedicated hidden item for given item type if any match i.inner { diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 5c0a4da1cd7e..e40dbe52ffe6 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -11,10 +11,6 @@ use syntax::ast; use syntax::source_map::SourceMap; use syntax::edition::Edition; use syntax::feature_gate::UnstableFeatures; -use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName}; -use tempfile::Builder as TempFileBuilder; -use testing; - use std::env; use std::io::prelude::*; use std::io; @@ -23,6 +19,10 @@ use std::path::PathBuf; use std::process::Command; use std::str; use std::sync::{Arc, Mutex}; +use syntax::symbol::sym; +use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName}; +use tempfile::Builder as TempFileBuilder; +use testing; use crate::clean::Attributes; use crate::config::Options; @@ -137,17 +137,17 @@ fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions { }; let test_attrs: Vec<_> = krate.attrs.iter() - .filter(|a| a.check_name("doc")) + .filter(|a| a.check_name(sym::doc)) .flat_map(|a| a.meta_item_list().unwrap_or_else(Vec::new)) - .filter(|a| a.check_name("test")) + .filter(|a| a.check_name(sym::test)) .collect(); let attrs = test_attrs.iter().flat_map(|a| a.meta_item_list().unwrap_or(&[])); for attr in attrs { - if attr.check_name("no_crate_inject") { + if attr.check_name(sym::no_crate_inject) { opts.no_crate_inject = true; } - if attr.check_name("attr") { + if attr.check_name(sym::attr) { if let Some(l) = attr.meta_item_list() { for item in l { opts.attrs.push(pprust::meta_list_item_to_string(item)); diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 94d2d7ffdb8c..eb9de43e3886 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -10,6 +10,7 @@ use syntax::ast; use syntax::attr; use syntax::ext::base::MacroKind; use syntax::source_map::Spanned; +use syntax::symbol::sym; use syntax_pos::{self, Span}; use std::mem; @@ -165,11 +166,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { body: hir::BodyId) { debug!("Visiting fn"); let macro_kind = item.attrs.iter().filter_map(|a| { - if a.check_name("proc_macro") { + if a.check_name(sym::proc_macro) { Some(MacroKind::Bang) - } else if a.check_name("proc_macro_derive") { + } else if a.check_name(sym::proc_macro_derive) { Some(MacroKind::Derive) - } else if a.check_name("proc_macro_attribute") { + } else if a.check_name(sym::proc_macro_attribute) { Some(MacroKind::Attr) } else { None @@ -178,7 +179,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { match macro_kind { Some(kind) => { let name = if kind == MacroKind::Derive { - item.attrs.lists("proc_macro_derive") + item.attrs.lists(sym::proc_macro_derive) .filter_map(|mi| mi.ident()) .next() .expect("proc-macro derives require a name") @@ -188,8 +189,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { }; let mut helpers = Vec::new(); - for mi in item.attrs.lists("proc_macro_derive") { - if !mi.check_name("attributes") { + for mi in item.attrs.lists(sym::proc_macro_derive) { + if !mi.check_name(sym::attributes) { continue; } @@ -274,7 +275,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { fn inherits_doc_hidden(cx: &core::DocContext<'_>, mut node: hir::HirId) -> bool { while let Some(id) = cx.tcx.hir().get_enclosing_scope(node) { node = id; - if cx.tcx.hir().attrs_by_hir_id(node).lists("doc").has_word("hidden") { + if cx.tcx.hir().attrs_by_hir_id(node) + .lists(sym::doc).has_word(sym::hidden) { return true; } if node == hir::CRATE_HIR_ID { @@ -295,8 +297,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let use_attrs = tcx.hir().attrs_by_hir_id(id); // Don't inline `doc(hidden)` imports so they can be stripped at a later stage. - let is_no_inline = use_attrs.lists("doc").has_word("no_inline") || - use_attrs.lists("doc").has_word("hidden"); + let is_no_inline = use_attrs.lists(sym::doc).has_word(sym::no_inline) || + use_attrs.lists(sym::doc).has_word(sym::hidden); // For cross-crate impl inlining we need to know whether items are // reachable in documentation -- a previously nonreachable item can be @@ -304,7 +306,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // (this is done here because we need to know this upfront). if !res_did.is_local() && !is_no_inline { let attrs = clean::inline::load_attrs(self.cx, res_did); - let self_is_hidden = attrs.lists("doc").has_word("hidden"); + let self_is_hidden = attrs.lists(sym::doc).has_word(sym::hidden); match res { Res::Def(DefKind::Trait, did) | Res::Def(DefKind::Struct, did) | @@ -432,8 +434,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { if item.vis.node.is_pub() && self.inside_public_path { let please_inline = item.attrs.iter().any(|item| { match item.meta_item_list() { - Some(ref list) if item.check_name("doc") => { - list.iter().any(|i| i.check_name("inline")) + Some(ref list) if item.check_name(sym::doc) => { + list.iter().any(|i| i.check_name(sym::inline)) } _ => false, } diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index 326c9a10f7df..2547e3a06e9e 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -3,6 +3,7 @@ use rustc::hir::def::{Res, DefKind}; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId}; use rustc::ty::Visibility; use rustc::util::nodemap::FxHashSet; +use syntax::symbol::sym; use std::cell::RefMut; @@ -42,7 +43,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> { // Updates node level and returns the updated level fn update(&mut self, did: DefId, level: Option) -> Option { - let is_hidden = self.cx.tcx.get_attrs(did).lists("doc").has_word("hidden"); + let is_hidden = self.cx.tcx.get_attrs(did).lists(sym::doc).has_word(sym::hidden); let old_level = self.access_levels.map.get(&did).cloned(); // Accessibility levels can only grow diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index db821f4e5369..a8310c48b962 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -5,7 +5,7 @@ use crate::feature_gate::{Features, GatedCfg}; use crate::parse::ParseSess; use errors::{Applicability, Handler}; -use syntax_pos::{symbol::Symbol, Span}; +use syntax_pos::{symbol::Symbol, symbol::sym, Span}; use super::{mark_used, MetaItemKind}; @@ -80,13 +80,13 @@ pub enum UnwindAttr { /// Determine what `#[unwind]` attribute is present in `attrs`, if any. pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Option { attrs.iter().fold(None, |ia, attr| { - if attr.check_name("unwind") { + if attr.check_name(sym::unwind) { if let Some(meta) = attr.meta() { if let MetaItemKind::List(items) = meta.node { if items.len() == 1 { - if items[0].check_name("allowed") { + if items[0].check_name(sym::allowed) { return Some(UnwindAttr::Allowed); - } else if items[0].check_name("aborts") { + } else if items[0].check_name(sym::aborts) { return Some(UnwindAttr::Aborts); } } @@ -153,9 +153,9 @@ pub struct RustcDeprecation { /// Checks if `attrs` contains an attribute like `#![feature(feature_name)]`. /// This will not perform any "sanity checks" on the form of the attributes. -pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> bool { +pub fn contains_feature_attr(attrs: &[Attribute], feature_name: Symbol) -> bool { attrs.iter().any(|item| { - item.check_name("feature") && + item.check_name(sym::feature) && item.meta_item_list().map(|list| { list.iter().any(|mi| mi.is_word() && mi.check_name(feature_name)) }).unwrap_or(false) @@ -482,7 +482,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, } pub fn find_crate_name(attrs: &[Attribute]) -> Option { - super::first_attr_value_str_by_name(attrs, "crate_name") + super::first_attr_value_str_by_name(attrs, sym::crate_name) } /// Tests if a cfg-pattern matches the cfg set @@ -593,7 +593,7 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess, let diagnostic = &sess.span_diagnostic; 'outer: for attr in attrs_iter { - if !attr.check_name("deprecated") { + if !attr.check_name(sym::deprecated) { continue; } @@ -790,7 +790,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec { } } else { if let Some(meta_item) = item.meta_item() { - if meta_item.check_name("align") { + if meta_item.check_name(sym::align) { if let MetaItemKind::NameValue(ref value) = meta_item.node { recognised = true; let mut err = struct_span_err!(diagnostic, item.span(), E0693, diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 07e4bbf78ffd..c0defa1c6e01 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -81,10 +81,7 @@ impl NestedMetaItem { } /// Returns `true` if this list item is a MetaItem with a name of `name`. - pub fn check_name(&self, name: T) -> bool - where - Path: PartialEq, - { + pub fn check_name(&self, name: Symbol) -> bool { self.meta_item().map_or(false, |meta_item| meta_item.check_name(name)) } @@ -154,10 +151,7 @@ impl Attribute { /// attribute is marked as used. /// /// To check the attribute name without marking it used, use the `path` field directly. - pub fn check_name(&self, name: T) -> bool - where - Path: PartialEq, - { + pub fn check_name(&self, name: Symbol) -> bool { let matches = self.path == name; if matches { mark_used(self); @@ -250,10 +244,7 @@ impl MetaItem { } } - pub fn check_name(&self, name: T) -> bool - where - Path: PartialEq, - { + pub fn check_name(&self, name: Symbol) -> bool { self.path == name } @@ -430,28 +421,28 @@ pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute { } } -pub fn list_contains_name(items: &[NestedMetaItem], name: &str) -> bool { +pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool { items.iter().any(|item| { item.check_name(name) }) } -pub fn contains_name(attrs: &[Attribute], name: &str) -> bool { +pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool { attrs.iter().any(|item| { item.check_name(name) }) } -pub fn find_by_name<'a>(attrs: &'a [Attribute], name: &str) -> Option<&'a Attribute> { +pub fn find_by_name<'a>(attrs: &'a [Attribute], name: Symbol) -> Option<&'a Attribute> { attrs.iter().find(|attr| attr.check_name(name)) } -pub fn filter_by_name<'a>(attrs: &'a [Attribute], name: &'a str) +pub fn filter_by_name<'a>(attrs: &'a [Attribute], name: Symbol) -> impl Iterator { attrs.iter().filter(move |attr| attr.check_name(name)) } -pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str) -> Option { +pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: Symbol) -> Option { attrs.iter() .find(|at| at.check_name(name)) .and_then(|at| at.value_str()) diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 18173628a260..c82936afa3d9 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -12,6 +12,7 @@ use crate::edition::Edition; use crate::mut_visit::*; use crate::parse::{token, ParseSess}; use crate::ptr::P; +use crate::symbol::sym; use crate::util::map_in_place::MapInPlace; use errors::Applicability; @@ -90,7 +91,7 @@ impl<'a> StripUnconfigured<'a> { /// is in the original source file. Gives a compiler error if the syntax of /// the attribute is incorrect. fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec { - if !attr.check_name("cfg_attr") { + if !attr.check_name(sym::cfg_attr) { return vec![attr]; } @@ -205,7 +206,7 @@ impl<'a> StripUnconfigured<'a> { pub fn maybe_emit_expr_attr_err(&self, attr: &ast::Attribute) { if !self.features.map(|features| features.stmt_expr_attributes).unwrap_or(true) { let mut err = feature_err(self.sess, - "stmt_expr_attributes", + sym::stmt_expr_attributes, attr.span, GateIssue::Language, EXPLAIN_STMT_ATTR_SYNTAX); @@ -285,9 +286,9 @@ impl<'a> StripUnconfigured<'a> { /// See issue #51279. pub fn disallow_cfg_on_generic_param(&mut self, param: &ast::GenericParam) { for attr in param.attrs() { - let offending_attr = if attr.check_name("cfg") { + let offending_attr = if attr.check_name(sym::cfg) { "cfg" - } else if attr.check_name("cfg_attr") { + } else if attr.check_name(sym::cfg_attr) { "cfg_attr" } else { continue; @@ -350,5 +351,5 @@ impl<'a> MutVisitor for StripUnconfigured<'a> { } fn is_cfg(attr: &ast::Attribute) -> bool { - attr.check_name("cfg") + attr.check_name(sym::cfg) } diff --git a/src/libsyntax/entry.rs b/src/libsyntax/entry.rs index 09e26e29d86a..267f863ce35e 100644 --- a/src/libsyntax/entry.rs +++ b/src/libsyntax/entry.rs @@ -1,5 +1,6 @@ use crate::attr; use crate::ast::{Item, ItemKind}; +use crate::symbol::sym; pub enum EntryPointType { None, @@ -14,9 +15,9 @@ pub enum EntryPointType { pub fn entry_point_type(item: &Item, depth: usize) -> EntryPointType { match item.node { ItemKind::Fn(..) => { - if attr::contains_name(&item.attrs, "start") { + if attr::contains_name(&item.attrs, sym::start) { EntryPointType::Start - } else if attr::contains_name(&item.attrs, "main") { + } else if attr::contains_name(&item.attrs, sym::main) { EntryPointType::MainAttr } else if item.ident.name == "main" { if depth == 1 { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 82358679c0e8..7ebfcfd176ad 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -14,7 +14,7 @@ use crate::parse::token::{self, Token}; use crate::parse::parser::Parser; use crate::ptr::P; use crate::symbol::Symbol; -use crate::symbol::keywords; +use crate::symbol::{keywords, sym}; use crate::tokenstream::{TokenStream, TokenTree}; use crate::visit::{self, Visitor}; use crate::util::map_in_place::MapInPlace; @@ -356,7 +356,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.collect_invocations(fragment, &[]) } else if let InvocationKind::Attr { attr: None, traits, item, .. } = invoc.kind { if !item.derive_allowed() { - let attr = attr::find_by_name(item.attrs(), "derive") + let attr = attr::find_by_name(item.attrs(), sym::derive) .expect("`derive` attribute should exist"); let span = attr.span; let mut err = self.cx.mut_span_err(span, @@ -510,7 +510,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { if invoc.fragment_kind == AstFragmentKind::ForeignItems && !self.cx.ecfg.macros_in_extern_enabled() { if let SyntaxExtension::NonMacroAttr { .. } = *ext {} else { - emit_feature_err(&self.cx.parse_sess, "macros_in_extern", + emit_feature_err(&self.cx.parse_sess, sym::macros_in_extern, invoc.span(), GateIssue::Language, "macro invocations in `extern {}` blocks are experimental"); } @@ -636,7 +636,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { Annotatable::Item(ref item) => { match item.node { ItemKind::Mod(_) if self.cx.ecfg.proc_macro_hygiene() => return, - ItemKind::Mod(_) => ("modules", "proc_macro_hygiene"), + ItemKind::Mod(_) => ("modules", sym::proc_macro_hygiene), _ => return, } } @@ -645,8 +645,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> { Annotatable::ForeignItem(_) => return, Annotatable::Stmt(_) | Annotatable::Expr(_) if self.cx.ecfg.proc_macro_hygiene() => return, - Annotatable::Stmt(_) => ("statements", "proc_macro_hygiene"), - Annotatable::Expr(_) => ("expressions", "proc_macro_hygiene"), + Annotatable::Stmt(_) => ("statements", sym::proc_macro_hygiene), + Annotatable::Expr(_) => ("expressions", sym::proc_macro_hygiene), }; emit_feature_err( self.cx.parse_sess, @@ -681,7 +681,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { if let ast::ItemKind::MacroDef(_) = i.node { emit_feature_err( self.parse_sess, - "proc_macro_hygiene", + sym::proc_macro_hygiene, self.span, GateIssue::Language, "procedural macros cannot expand to macro definitions", @@ -724,13 +724,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> { // don't stability-check macros in the same crate // (the only time this is null is for syntax extensions registered as macros) if def_site_span.map_or(false, |def_span| !crate_span.contains(def_span)) - && !span.allows_unstable(&feature.as_str()) + && !span.allows_unstable(feature) && this.cx.ecfg.features.map_or(true, |feats| { // macro features will count as lib features !feats.declared_lib_features.iter().any(|&(feat, _)| feat == feature) }) { let explain = format!("macro {}! is unstable", path); - emit_feature_err(this.cx.parse_sess, &*feature.as_str(), span, + emit_feature_err(this.cx.parse_sess, feature, span, GateIssue::Library(Some(issue)), &explain); this.cx.trace_macros_diag(); } @@ -885,7 +885,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } emit_feature_err( self.cx.parse_sess, - "proc_macro_hygiene", + sym::proc_macro_hygiene, span, GateIssue::Language, &format!("procedural macros cannot be expanded to {}", kind), @@ -1118,7 +1118,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { if let Some(attr) = &attr { if !self.cx.ecfg.enable_custom_inner_attributes() && attr.style == ast::AttrStyle::Inner && attr.path != "test" { - emit_feature_err(&self.cx.parse_sess, "custom_inner_attributes", + emit_feature_err(&self.cx.parse_sess, sym::custom_inner_attributes, attr.span, GateIssue::Language, "non-builtin inner attributes are unstable"); } @@ -1352,7 +1352,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { let inline_module = item.span.contains(inner) || inner.is_dummy(); if inline_module { - if let Some(path) = attr::first_attr_value_str_by_name(&item.attrs, "path") { + if let Some(path) = attr::first_attr_value_str_by_name(&item.attrs, sym::path) { self.cx.current_expansion.directory_ownership = DirectoryOwnership::Owned { relative: None }; module.directory.push(&*path.as_str()); @@ -1485,19 +1485,19 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { fn visit_attribute(&mut self, at: &mut ast::Attribute) { // turn `#[doc(include="filename")]` attributes into `#[doc(include(file="filename", // contents="file contents")]` attributes - if !at.check_name("doc") { + if !at.check_name(sym::doc) { return noop_visit_attribute(at, self); } if let Some(list) = at.meta_item_list() { - if !list.iter().any(|it| it.check_name("include")) { + if !list.iter().any(|it| it.check_name(sym::include)) { return noop_visit_attribute(at, self); } let mut items = vec![]; for mut it in list { - if !it.check_name("include") { + if !it.check_name(sym::include) { items.push({ noop_visit_meta_list_item(&mut it, self); it }); continue; } diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 549de1628eb5..e1cb90d9e71d 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -4,7 +4,7 @@ use crate::ext::build::AstBuilder; use crate::parse::{self, token, DirectoryOwnership}; use crate::print::pprust; use crate::ptr::P; -use crate::symbol::Symbol; +use crate::symbol::{Symbol, sym}; use crate::tokenstream; use smallvec::SmallVec; @@ -44,7 +44,7 @@ pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTr /* __rust_unstable_column!(): expands to the current column number */ pub fn expand_column_gated(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { - if sp.allows_unstable("__rust_unstable_column") { + if sp.allows_unstable(sym::__rust_unstable_column) { expand_column(cx, sp, tts) } else { cx.span_fatal(sp, "the __rust_unstable_column macro is unstable"); diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index a53cc2fe6617..555962100936 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -13,7 +13,7 @@ use crate::parse::{Directory, ParseSess}; use crate::parse::parser::Parser; use crate::parse::token::{self, NtTT}; use crate::parse::token::Token::*; -use crate::symbol::Symbol; +use crate::symbol::{Symbol, sym}; use crate::tokenstream::{DelimSpan, TokenStream, TokenTree}; use errors::FatalError; @@ -376,7 +376,7 @@ pub fn compile( }); if body.legacy { - let allow_internal_unstable = attr::find_by_name(&def.attrs, "allow_internal_unstable") + let allow_internal_unstable = attr::find_by_name(&def.attrs, sym::allow_internal_unstable) .map(|attr| attr .meta_item_list() .map(|list| list.iter() @@ -399,11 +399,11 @@ pub fn compile( vec![Symbol::intern("allow_internal_unstable_backcompat_hack")].into() }) ); - let allow_internal_unsafe = attr::contains_name(&def.attrs, "allow_internal_unsafe"); + let allow_internal_unsafe = attr::contains_name(&def.attrs, sym::allow_internal_unsafe); let mut local_inner_macros = false; - if let Some(macro_export) = attr::find_by_name(&def.attrs, "macro_export") { + if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) { if let Some(l) = macro_export.meta_item_list() { - local_inner_macros = attr::list_contains_name(&l, "local_inner_macros"); + local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros); } } @@ -426,7 +426,7 @@ pub fn compile( edition, } } else { - let is_transparent = attr::contains_name(&def.attrs, "rustc_transparent_macro"); + let is_transparent = attr::contains_name(&def.attrs, sym::rustc_transparent_macro); SyntaxExtension::DeclMacro { expander, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index c4977f924023..53ecb0762ab4 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -48,8 +48,8 @@ macro_rules! declare_features { /// Represents active features that are currently being implemented or /// currently being considered for addition/removal. const ACTIVE_FEATURES: - &[(&str, &str, Option, Option, fn(&mut Features, Span))] = - &[$((stringify!($feature), $ver, $issue, $edition, set!($feature))),+]; + &[(Symbol, &str, Option, Option, fn(&mut Features, Span))] = + &[$((sym::$feature, $ver, $issue, $edition, set!($feature))),+]; /// A set of features to be used by later passes. #[derive(Clone)] @@ -80,22 +80,22 @@ macro_rules! declare_features { ($((removed, $feature: ident, $ver: expr, $issue: expr, None, $reason: expr),)+) => { /// Represents unstable features which have since been removed (it was once Active) - const REMOVED_FEATURES: &[(&str, &str, Option, Option<&str>)] = &[ - $((stringify!($feature), $ver, $issue, $reason)),+ + const REMOVED_FEATURES: &[(Symbol, &str, Option, Option<&str>)] = &[ + $((sym::$feature, $ver, $issue, $reason)),+ ]; }; ($((stable_removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => { /// Represents stable features which have since been removed (it was once Accepted) - const STABLE_REMOVED_FEATURES: &[(&str, &str, Option, Option<&str>)] = &[ - $((stringify!($feature), $ver, $issue, None)),+ + const STABLE_REMOVED_FEATURES: &[(Symbol, &str, Option, Option<&str>)] = &[ + $((sym::$feature, $ver, $issue, None)),+ ]; }; ($((accepted, $feature: ident, $ver: expr, $issue: expr, None),)+) => { /// Those language feature has since been Accepted (it was once Active) - const ACCEPTED_FEATURES: &[(&str, &str, Option, Option<&str>)] = &[ - $((stringify!($feature), $ver, $issue, None)),+ + const ACCEPTED_FEATURES: &[(Symbol, &str, Option, Option<&str>)] = &[ + $((sym::$feature, $ver, $issue, None)),+ ]; } } @@ -860,7 +860,7 @@ pub enum AttributeType { pub enum AttributeGate { /// Is gated by a given feature gate, reason /// and function to check if enabled - Gated(Stability, &'static str, &'static str, fn(&Features) -> bool), + Gated(Stability, Symbol, &'static str, fn(&Features) -> bool), /// Ungated attribute, can be used on all release channels Ungated, @@ -1010,7 +1010,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ (sym::no_implicit_prelude, Normal, template!(Word), Ungated), (sym::reexport_test_harness_main, Normal, template!(NameValueStr: "name"), Ungated), (sym::link_args, Normal, template!(NameValueStr: "args"), Gated(Stability::Unstable, - "link_args", + sym::link_args, "the `link_args` attribute is experimental and not \ portable across platforms, it is recommended to \ use `#[link(name = \"foo\")] instead", @@ -1019,46 +1019,46 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // RFC #1445. (sym::structural_match, Whitelisted, template!(Word), Gated(Stability::Unstable, - "structural_match", + sym::structural_match, "the semantics of constant patterns is \ not yet settled", cfg_fn!(structural_match))), // RFC #2008 (sym::non_exhaustive, Whitelisted, template!(Word), Gated(Stability::Unstable, - "non_exhaustive", + sym::non_exhaustive, "non exhaustive is an experimental feature", cfg_fn!(non_exhaustive))), // RFC #1268 (sym::marker, Normal, template!(Word), Gated(Stability::Unstable, - "marker_trait_attr", + sym::marker_trait_attr, "marker traits is an experimental feature", cfg_fn!(marker_trait_attr))), (sym::plugin, CrateLevel, template!(List: "name|name(args)"), Gated(Stability::Unstable, - "plugin", + sym::plugin, "compiler plugins are experimental \ and possibly buggy", cfg_fn!(plugin))), (sym::no_std, CrateLevel, template!(Word), Ungated), (sym::no_core, CrateLevel, template!(Word), Gated(Stability::Unstable, - "no_core", + sym::no_core, "no_core is experimental", cfg_fn!(no_core))), (sym::lang, Normal, template!(NameValueStr: "name"), Gated(Stability::Unstable, - "lang_items", + sym::lang_items, "language items are subject to change", cfg_fn!(lang_items))), (sym::linkage, Whitelisted, template!(NameValueStr: "external|internal|..."), Gated(Stability::Unstable, - "linkage", + sym::linkage, "the `linkage` attribute is experimental \ and not portable across platforms", cfg_fn!(linkage))), (sym::thread_local, Whitelisted, template!(Word), Gated(Stability::Unstable, - "thread_local", + sym::thread_local, "`#[thread_local]` is an experimental feature, and does \ not currently handle destructors", cfg_fn!(thread_local))), @@ -1067,100 +1067,100 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#, NameValueStr: "message"), Gated(Stability::Unstable, - "on_unimplemented", + sym::on_unimplemented, "the `#[rustc_on_unimplemented]` attribute \ is an experimental feature", cfg_fn!(on_unimplemented))), (sym::rustc_const_unstable, Normal, template!(List: r#"feature = "name""#), Gated(Stability::Unstable, - "rustc_const_unstable", + sym::rustc_const_unstable, "the `#[rustc_const_unstable]` attribute \ is an internal feature", cfg_fn!(rustc_const_unstable))), (sym::global_allocator, Normal, template!(Word), Ungated), (sym::default_lib_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable, - "allocator_internals", + sym::allocator_internals, "the `#[default_lib_allocator]` \ attribute is an experimental feature", cfg_fn!(allocator_internals))), (sym::needs_allocator, Normal, template!(Word), Gated(Stability::Unstable, - "allocator_internals", + sym::allocator_internals, "the `#[needs_allocator]` \ attribute is an experimental \ feature", cfg_fn!(allocator_internals))), (sym::panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, - "panic_runtime", + sym::panic_runtime, "the `#[panic_runtime]` attribute is \ an experimental feature", cfg_fn!(panic_runtime))), (sym::needs_panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, - "needs_panic_runtime", + sym::needs_panic_runtime, "the `#[needs_panic_runtime]` \ attribute is an experimental \ feature", cfg_fn!(needs_panic_runtime))), (sym::rustc_outlives, Normal, template!(Word), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "the `#[rustc_outlives]` attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), (sym::rustc_variance, Normal, template!(Word), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "the `#[rustc_variance]` attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), (sym::rustc_layout, Normal, template!(List: "field1, field2, ..."), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "the `#[rustc_layout]` attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), (sym::rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "the `#[rustc_layout_scalar_valid_range_start]` attribute \ is just used to enable niche optimizations in libcore \ and will never be stable", cfg_fn!(rustc_attrs))), (sym::rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "the `#[rustc_layout_scalar_valid_range_end]` attribute \ is just used to enable niche optimizations in libcore \ and will never be stable", cfg_fn!(rustc_attrs))), (sym::rustc_regions, Normal, template!(Word), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "the `#[rustc_regions]` attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), (sym::rustc_error, Whitelisted, template!(Word), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "the `#[rustc_error]` attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), (sym::rustc_dump_user_substs, Whitelisted, template!(Word), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "this attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), (sym::rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode"), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "the `#[rustc_if_this_changed]` attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), (sym::rustc_then_this_would_need, Whitelisted, template!(List: "DepNode"), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "the `#[rustc_if_this_changed]` attribute \ is just used for rustc unit tests \ and will never be stable", @@ -1168,7 +1168,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ (sym::rustc_dirty, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "the `#[rustc_dirty]` attribute \ is just used for rustc unit tests \ and will never be stable", @@ -1176,7 +1176,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ (sym::rustc_clean, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "the `#[rustc_clean]` attribute \ is just used for rustc unit tests \ and will never be stable", @@ -1187,7 +1187,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ template!(List: r#"cfg = "...", module = "...""#), Gated( Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "this attribute \ is just used for rustc unit tests \ and will never be stable", @@ -1200,7 +1200,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ template!(List: r#"cfg = "...", module = "...""#), Gated( Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "this attribute \ is just used for rustc unit tests \ and will never be stable", @@ -1210,27 +1210,27 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ (sym::rustc_expected_cgu_reuse, Whitelisted, template!(List: r#"cfg = "...", module = "...", kind = "...""#), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "this attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), (sym::rustc_synthetic, Whitelisted, template!(Word), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "this attribute \ is just used for rustc unit tests \ and will never be stable", cfg_fn!(rustc_attrs))), (sym::rustc_symbol_name, Whitelisted, template!(Word), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "internal rustc attributes will never be stable", cfg_fn!(rustc_attrs))), (sym::rustc_def_path, Whitelisted, template!(Word), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "internal rustc attributes will never be stable", cfg_fn!(rustc_attrs))), (sym::rustc_mir, Whitelisted, template!(List: "arg1, arg2, ..."), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "the `#[rustc_mir]` attribute \ is just used for rustc unit tests \ and will never be stable", @@ -1241,7 +1241,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ template!(Word), Gated( Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "the `#[rustc_inherit_overflow_checks]` \ attribute is just used to control \ overflow checking behavior of several \ @@ -1252,35 +1252,35 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), (sym::rustc_dump_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "the `#[rustc_dump_program_clauses]` \ attribute is just used for rustc unit \ tests and will never be stable", cfg_fn!(rustc_attrs))), (sym::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "the `#[rustc_test_marker]` attribute \ is used internally to track tests", cfg_fn!(rustc_attrs))), (sym::rustc_transparent_macro, Whitelisted, template!(Word), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "used internally for testing macro hygiene", cfg_fn!(rustc_attrs))), (sym::compiler_builtins, Whitelisted, template!(Word), Gated(Stability::Unstable, - "compiler_builtins", + sym::compiler_builtins, "the `#[compiler_builtins]` attribute is used to \ identify the `compiler_builtins` crate which \ contains compiler-rt intrinsics and will never be \ stable", cfg_fn!(compiler_builtins))), (sym::sanitizer_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, - "sanitizer_runtime", + sym::sanitizer_runtime, "the `#[sanitizer_runtime]` attribute is used to \ identify crates that contain the runtime of a \ sanitizer and will never be stable", cfg_fn!(sanitizer_runtime))), (sym::profiler_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, - "profiler_runtime", + sym::profiler_runtime, "the `#[profiler_runtime]` attribute is used to \ identify the `profiler_builtins` crate which \ contains the profiler runtime and will never be \ @@ -1289,17 +1289,17 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ (sym::allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."), Gated(Stability::Unstable, - "allow_internal_unstable", + sym::allow_internal_unstable, EXPLAIN_ALLOW_INTERNAL_UNSTABLE, cfg_fn!(allow_internal_unstable))), (sym::allow_internal_unsafe, Normal, template!(Word), Gated(Stability::Unstable, - "allow_internal_unsafe", + sym::allow_internal_unsafe, EXPLAIN_ALLOW_INTERNAL_UNSAFE, cfg_fn!(allow_internal_unsafe))), (sym::fundamental, Whitelisted, template!(Word), Gated(Stability::Unstable, - "fundamental", + sym::fundamental, "the `#[fundamental]` attribute \ is an experimental feature", cfg_fn!(fundamental))), @@ -1309,7 +1309,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ Ungated), (sym::rustc_copy_clone_marker, Whitelisted, template!(Word), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "internal implementation detail", cfg_fn!(rustc_attrs))), @@ -1325,12 +1325,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // lint pass (sym::cold, Whitelisted, template!(Word), Ungated), (sym::naked, Whitelisted, template!(Word), Gated(Stability::Unstable, - "naked_functions", + sym::naked_functions, "the `#[naked]` attribute \ is an experimental feature", cfg_fn!(naked_functions))), (sym::ffi_returns_twice, Whitelisted, template!(Word), Gated(Stability::Unstable, - "ffi_returns_twice", + sym::ffi_returns_twice, "the `#[ffi_returns_twice]` attribute \ is an experimental feature", cfg_fn!(ffi_returns_twice))), @@ -1344,7 +1344,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ (sym::no_builtins, Whitelisted, template!(Word), Ungated), (sym::no_debug, Whitelisted, template!(Word), Gated( Stability::Deprecated("https://github.com/rust-lang/rust/issues/29721", None), - "no_debug", + sym::no_debug, "the `#[no_debug]` attribute was an experimental feature that has been \ deprecated due to lack of demand", cfg_fn!(no_debug))), @@ -1354,7 +1354,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ template!(Word), Gated( Stability::Unstable, - "omit_gdb_pretty_printer_section", + sym::omit_gdb_pretty_printer_section, "the `#[omit_gdb_pretty_printer_section]` \ attribute is just used for the Rust test \ suite", @@ -1366,7 +1366,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ template!(Word), Gated(Stability::Deprecated("https://github.com/rust-lang/rust/issues/34761", Some("replace this attribute with `#[may_dangle]`")), - "dropck_parametricity", + sym::dropck_parametricity, "unsafe_destructor_blind_to_params has been replaced by \ may_dangle and will be removed in the future", cfg_fn!(dropck_parametricity))), @@ -1374,18 +1374,18 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ Normal, template!(Word), Gated(Stability::Unstable, - "dropck_eyepatch", + sym::dropck_eyepatch, "may_dangle has unstable semantics and may be removed in the future", cfg_fn!(dropck_eyepatch))), (sym::unwind, Whitelisted, template!(List: "allowed|aborts"), Gated(Stability::Unstable, - "unwind_attributes", + sym::unwind_attributes, "#[unwind] is experimental", cfg_fn!(unwind_attributes))), (sym::used, Whitelisted, template!(Word), Ungated), // used in resolve (sym::prelude_import, Whitelisted, template!(Word), Gated(Stability::Unstable, - "prelude_import", + sym::prelude_import, "`#[prelude_import]` is for use by rustc only", cfg_fn!(prelude_import))), @@ -1421,7 +1421,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), (sym::rustc_paren_sugar, Normal, template!(Word), Gated(Stability::Unstable, - "unboxed_closures", + sym::unboxed_closures, "unboxed_closures are still evolving", cfg_fn!(unboxed_closures))), @@ -1431,24 +1431,24 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ (sym::proc_macro, Normal, template!(Word), Ungated), (sym::rustc_proc_macro_decls, Normal, template!(Word), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "used internally by rustc", cfg_fn!(rustc_attrs))), (sym::allow_fail, Normal, template!(Word), Gated(Stability::Unstable, - "allow_fail", + sym::allow_fail, "allow_fail attribute is currently unstable", cfg_fn!(allow_fail))), (sym::rustc_std_internal_symbol, Whitelisted, template!(Word), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "this is an internal attribute that will \ never be stable", cfg_fn!(rustc_attrs))), // whitelists "identity-like" conversion methods to suggest on type mismatch (sym::rustc_conversion_suggestion, Whitelisted, template!(Word), Gated(Stability::Unstable, - "rustc_attrs", + sym::rustc_attrs, "this is an internal attribute that will \ never be stable", cfg_fn!(rustc_attrs))), @@ -1457,19 +1457,20 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ sym::rustc_args_required_const, Whitelisted, template!(List: "N"), - Gated(Stability::Unstable, "rustc_attrs", "never will be stable", cfg_fn!(rustc_attrs)) + Gated(Stability::Unstable, sym::rustc_attrs, "never will be stable", + cfg_fn!(rustc_attrs)) ), // RFC 2070 (sym::panic_handler, Normal, template!(Word), Ungated), (sym::alloc_error_handler, Normal, template!(Word), Gated(Stability::Unstable, - "alloc_error_handler", + sym::alloc_error_handler, "#[alloc_error_handler] is an unstable feature", cfg_fn!(alloc_error_handler))), // RFC 2412 (sym::optimize, Whitelisted, template!(List: "size|speed"), Gated(Stability::Unstable, - "optimize_attribute", + sym::optimize_attribute, "#[optimize] attribute is an unstable feature", cfg_fn!(optimize_attribute))), @@ -1483,7 +1484,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ (sym::recursion_limit, CrateLevel, template!(NameValueStr: "N"), Ungated), (sym::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated), (sym::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable, - "custom_test_frameworks", + sym::custom_test_frameworks, EXPLAIN_CUSTOM_TEST_FRAMEWORKS, cfg_fn!(custom_test_frameworks))), ]; @@ -1503,11 +1504,11 @@ lazy_static! { } // cfg(...)'s that are feature gated -const GATED_CFGS: &[(&str, &str, fn(&Features) -> bool)] = &[ +const GATED_CFGS: &[(Symbol, Symbol, fn(&Features) -> bool)] = &[ // (name in cfg, feature, function to check if the feature is enabled) - ("target_thread_local", "cfg_target_thread_local", cfg_fn!(cfg_target_thread_local)), - ("target_has_atomic", "cfg_target_has_atomic", cfg_fn!(cfg_target_has_atomic)), - ("rustdoc", "doc_cfg", cfg_fn!(doc_cfg)), + (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)), + (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)), + (sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)), ]; #[derive(Debug)] @@ -1540,7 +1541,7 @@ impl GatedCfg { struct Context<'a> { features: &'a Features, parse_sess: &'a ParseSess, - plugin_attributes: &'a [(String, AttributeType)], + plugin_attributes: &'a [(Symbol, AttributeType)], } macro_rules! gate_feature_fn { @@ -1559,11 +1560,11 @@ macro_rules! gate_feature_fn { macro_rules! gate_feature { ($cx: expr, $feature: ident, $span: expr, $explain: expr) => { gate_feature_fn!($cx, |x:&Features| x.$feature, $span, - stringify!($feature), $explain, GateStrength::Hard) + sym::$feature, $explain, GateStrength::Hard) }; ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => { gate_feature_fn!($cx, |x:&Features| x.$feature, $span, - stringify!($feature), $explain, $level) + sym::$feature, $explain, $level) }; } @@ -1594,8 +1595,8 @@ impl<'a> Context<'a> { debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage); return; } - for &(ref n, ref ty) in self.plugin_attributes { - if attr.path == &**n { + for &(n, ty) in self.plugin_attributes { + if attr.path == n { // Plugins can't gate attributes, so we don't check for it // unlike the code above; we only use this loop to // short-circuit to avoid the checks below. @@ -1629,7 +1630,7 @@ pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: ); } -fn find_lang_feature_issue(feature: &str) -> Option { +fn find_lang_feature_issue(feature: Symbol) -> Option { if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.0 == feature) { let issue = info.2; // FIXME (#28244): enforce that active features have issue numbers @@ -1661,7 +1662,7 @@ pub enum GateStrength { pub fn emit_feature_err( sess: &ParseSess, - feature: &str, + feature: Symbol, span: Span, issue: GateIssue, explain: &str, @@ -1671,7 +1672,7 @@ pub fn emit_feature_err( pub fn feature_err<'a>( sess: &'a ParseSess, - feature: &str, + feature: Symbol, span: Span, issue: GateIssue, explain: &str, @@ -1681,7 +1682,7 @@ pub fn feature_err<'a>( fn leveled_feature_err<'a>( sess: &'a ParseSess, - feature: &str, + feature: Symbol, span: Span, issue: GateIssue, explain: &str, @@ -1769,13 +1770,13 @@ struct PostExpansionVisitor<'a> { macro_rules! gate_feature_post { ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{ let (cx, span) = ($cx, $span); - if !span.allows_unstable(stringify!($feature)) { + if !span.allows_unstable(sym::$feature) { gate_feature!(cx.context, $feature, span, $explain) } }}; ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{ let (cx, span) = ($cx, $span); - if !span.allows_unstable(stringify!($feature)) { + if !span.allows_unstable(sym::$feature) { gate_feature!(cx.context, $feature, span, $explain, $level) } }} @@ -1957,17 +1958,17 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } ast::ItemKind::Fn(..) => { - if attr::contains_name(&i.attrs[..], "plugin_registrar") { + if attr::contains_name(&i.attrs[..], sym::plugin_registrar) { gate_feature_post!(&self, plugin_registrar, i.span, "compiler plugins are experimental and possibly buggy"); } - if attr::contains_name(&i.attrs[..], "start") { + if attr::contains_name(&i.attrs[..], sym::start) { gate_feature_post!(&self, start, i.span, "a #[start] function is an experimental \ feature whose signature may change \ over time"); } - if attr::contains_name(&i.attrs[..], "main") { + if attr::contains_name(&i.attrs[..], sym::main) { gate_feature_post!(&self, main, i.span, "declaration of a nonstandard #[main] \ function may change over time, for now \ @@ -1976,7 +1977,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } ast::ItemKind::Struct(..) => { - for attr in attr::filter_by_name(&i.attrs[..], "repr") { + for attr in attr::filter_by_name(&i.attrs[..], sym::repr) { for item in attr.meta_item_list().unwrap_or_else(Vec::new) { if item.check_name(sym::simd) { gate_feature_post!(&self, repr_simd, attr.span, @@ -1987,7 +1988,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } ast::ItemKind::Enum(..) => { - for attr in attr::filter_by_name(&i.attrs[..], "repr") { + for attr in attr::filter_by_name(&i.attrs[..], sym::repr) { for item in attr.meta_item_list().unwrap_or_else(Vec::new) { if item.check_name(sym::align) { gate_feature_post!(&self, repr_align_enum, attr.span, @@ -2051,7 +2052,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { match i.node { ast::ForeignItemKind::Fn(..) | ast::ForeignItemKind::Static(..) => { - let link_name = attr::first_attr_value_str_by_name(&i.attrs, "link_name"); + let link_name = attr::first_attr_value_str_by_name(&i.attrs, sym::link_name); let links_to_llvm = match link_name { Some(val) => val.as_str().starts_with("llvm."), _ => false @@ -2311,7 +2312,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], if let Some(f_edition) = f_edition { if f_edition <= crate_edition { set(&mut features, DUMMY_SP); - edition_enabled_features.insert(Symbol::intern(name), crate_edition); + edition_enabled_features.insert(name, crate_edition); } } } @@ -2355,7 +2356,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], // FIXME(Manishearth) there is currently no way to set // lib features by edition set(&mut features, DUMMY_SP); - edition_enabled_features.insert(Symbol::intern(name), *edition); + edition_enabled_features.insert(name, *edition); } } } @@ -2438,7 +2439,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], pub fn check_crate(krate: &ast::Crate, sess: &ParseSess, features: &Features, - plugin_attributes: &[(String, AttributeType)], + plugin_attributes: &[(Symbol, AttributeType)], unstable: UnstableFeatures) { maybe_stage_features(&sess.span_diagnostic, krate, unstable); let ctx = Context { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 526143b28755..64f3704e8083 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -575,13 +575,15 @@ mod tests { #[test] fn crlf_doc_comments() { with_globals(|| { + use crate::symbol::sym; + let sess = ParseSess::new(FilePathMapping::empty()); let name_1 = FileName::Custom("crlf_source_1".to_string()); let source = "/// doc comment\r\nfn foo() {}".to_string(); let item = parse_item_from_source_str(name_1, source, &sess) .unwrap().unwrap(); - let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap(); + let doc = first_attr_value_str_by_name(&item.attrs, sym::doc).unwrap(); assert_eq!(doc, "/// doc comment"); let name_2 = FileName::Custom("crlf_source_2".to_string()); @@ -596,7 +598,7 @@ mod tests { let name_3 = FileName::Custom("clrf_source_3".to_string()); let source = "/** doc comment\r\n * with CRLF */\r\nfn foo() {}".to_string(); let item = parse_item_from_source_str(name_3, source, &sess).unwrap().unwrap(); - let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap(); + let doc = first_attr_value_str_by_name(&item.attrs, sym::doc).unwrap(); assert_eq!(doc, "/** doc comment\n * with CRLF */"); }); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f95981680b94..d3dd6bb1e01a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -46,7 +46,7 @@ use crate::ptr::P; use crate::parse::PResult; use crate::ThinVec; use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint}; -use crate::symbol::{keywords, Symbol}; +use crate::symbol::{keywords, sym, Symbol}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError}; use rustc_target::spec::abi::{self, Abi}; @@ -7263,7 +7263,7 @@ impl<'a> Parser<'a> { } fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) { - if let Some(path) = attr::first_attr_value_str_by_name(attrs, "path") { + if let Some(path) = attr::first_attr_value_str_by_name(attrs, sym::path) { self.directory.path.to_mut().push(&path.as_str()); self.directory.ownership = DirectoryOwnership::Owned { relative: None }; } else { @@ -7283,7 +7283,7 @@ impl<'a> Parser<'a> { } pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option { - if let Some(s) = attr::first_attr_value_str_by_name(attrs, "path") { + if let Some(s) = attr::first_attr_value_str_by_name(attrs, sym::path) { let s = s.as_str(); // On windows, the base path might have the form diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index b9758bd655c1..42ca8b7c23cb 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -2,7 +2,7 @@ use crate::ast; use crate::attr; use crate::edition::Edition; use crate::ext::hygiene::{Mark, SyntaxContext}; -use crate::symbol::{Symbol, keywords}; +use crate::symbol::{Symbol, keywords, sym}; use crate::source_map::{ExpnInfo, MacroAttribute, dummy_spanned, hygiene, respan}; use crate::ptr::P; use crate::tokenstream::TokenStream; @@ -46,10 +46,10 @@ pub fn maybe_inject_crates_ref( let rust_2018 = edition >= Edition::Edition2018; // the first name in this list is the crate name of the crate with the prelude - let names: &[&str] = if attr::contains_name(&krate.attrs, "no_core") { + let names: &[&str] = if attr::contains_name(&krate.attrs, sym::no_core) { return krate; - } else if attr::contains_name(&krate.attrs, "no_std") { - if attr::contains_name(&krate.attrs, "compiler_builtins") { + } else if attr::contains_name(&krate.attrs, sym::no_std) { + if attr::contains_name(&krate.attrs, sym::compiler_builtins) { &["core"] } else { &["core", "compiler_builtins"] diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 03d0eff266e7..8e5e594ce9aa 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -29,7 +29,7 @@ use crate::parse::{token, ParseSess}; use crate::print::pprust; use crate::ast::{self, Ident}; use crate::ptr::P; -use crate::symbol::{self, Symbol, keywords}; +use crate::symbol::{self, Symbol, keywords, sym}; use crate::ThinVec; struct Test { @@ -65,8 +65,7 @@ pub fn modify_for_testing(sess: &ParseSess, // unconditional, so that the attribute is still marked as used in // non-test builds. let reexport_test_harness_main = - attr::first_attr_value_str_by_name(&krate.attrs, - "reexport_test_harness_main"); + attr::first_attr_value_str_by_name(&krate.attrs, sym::reexport_test_harness_main); // Do this here so that the test_runner crate attribute gets marked as used // even in non-test builds @@ -185,7 +184,7 @@ impl MutVisitor for EntryPointCleaner { ident, attrs: attrs.into_iter() .filter(|attr| { - !attr.check_name("main") && !attr.check_name("start") + !attr.check_name(sym::main) && !attr.check_name(sym::start) }) .chain(iter::once(allow_dead_code)) .collect(), @@ -428,11 +427,11 @@ fn visible_path(cx: &TestCtxt<'_>, path: &[Ident]) -> Vec{ } fn is_test_case(i: &ast::Item) -> bool { - attr::contains_name(&i.attrs, "rustc_test_marker") + attr::contains_name(&i.attrs, sym::rustc_test_marker) } fn get_test_runner(sd: &errors::Handler, krate: &ast::Crate) -> Option { - let test_attr = attr::find_by_name(&krate.attrs, "test_runner")?; + let test_attr = attr::find_by_name(&krate.attrs, sym::test_runner)?; test_attr.meta_item_list().map(|meta_list| { if meta_list.len() != 1 { sd.span_fatal(test_attr.span, diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs index 8edd0e1ae388..6213736ed5f4 100644 --- a/src/libsyntax_ext/asm.rs +++ b/src/libsyntax_ext/asm.rs @@ -11,7 +11,7 @@ use syntax::ext::base::{self, *}; use syntax::feature_gate; use syntax::parse::{self, token}; use syntax::ptr::P; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax::ast::AsmDialect; use syntax_pos::Span; use syntax::tokenstream; @@ -47,7 +47,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>, -> Box { if !cx.ecfg.enable_asm() { feature_gate::emit_feature_err(&cx.parse_sess, - "asm", + sym::asm, sp, feature_gate::GateIssue::Language, feature_gate::EXPLAIN_ASM); diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs index 8c9eb4bf2d8f..77c53f402cc9 100644 --- a/src/libsyntax_ext/concat_idents.rs +++ b/src/libsyntax_ext/concat_idents.rs @@ -6,7 +6,7 @@ use syntax::feature_gate; use syntax::parse::token; use syntax::ptr::P; use syntax_pos::Span; -use syntax_pos::symbol::Symbol; +use syntax_pos::symbol::{Symbol, sym}; use syntax::tokenstream::TokenTree; pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>, @@ -15,7 +15,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>, -> Box { if !cx.ecfg.enable_concat_idents() { feature_gate::emit_feature_err(&cx.parse_sess, - "concat_idents", + sym::concat_idents, sp, feature_gate::GateIssue::Language, feature_gate::EXPLAIN_CONCAT_IDENTS); diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs index b347092e1bc4..1b0d572324a7 100644 --- a/src/libsyntax_ext/deriving/clone.rs +++ b/src/libsyntax_ext/deriving/clone.rs @@ -7,7 +7,7 @@ use syntax::attr; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; use syntax::ptr::P; -use syntax::symbol::{Symbol, keywords}; +use syntax::symbol::{Symbol, keywords, sym}; use syntax_pos::Span; pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>, @@ -37,7 +37,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>, match annitem.node { ItemKind::Struct(_, Generics { ref params, .. }) | ItemKind::Enum(_, Generics { ref params, .. }) => { - if attr::contains_name(&annitem.attrs, "rustc_copy_clone_marker") && + if attr::contains_name(&annitem.attrs, sym::rustc_copy_clone_marker) && !params.iter().any(|param| match param.kind { ast::GenericParamKind::Type { .. } => true, _ => false, diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index e5939e396e5c..228862c830fd 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -191,7 +191,7 @@ use syntax::ext::build::AstBuilder; use syntax::source_map::{self, respan}; use syntax::util::map_in_place::MapInPlace; use syntax::ptr::P; -use syntax::symbol::{Symbol, keywords}; +use syntax::symbol::{Symbol, keywords, sym}; use syntax::parse::ParseSess; use syntax_pos::{DUMMY_SP, Span}; @@ -426,7 +426,7 @@ impl<'a> TraitDef<'a> { } }; let is_always_copy = - attr::contains_name(&item.attrs, "rustc_copy_clone_marker") && + attr::contains_name(&item.attrs, sym::rustc_copy_clone_marker) && has_no_type_params; let use_temporaries = is_packed && is_always_copy; diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 24fbc9b6caf3..9e54c0634b66 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -12,7 +12,7 @@ use syntax::ext::build::AstBuilder; use syntax::feature_gate; use syntax::parse::token; use syntax::ptr::P; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax::tokenstream; use syntax_pos::{MultiSpan, Span, DUMMY_SP}; @@ -711,12 +711,12 @@ pub fn expand_format_args_nl<'cx>( //if !ecx.ecfg.enable_allow_internal_unstable() { // For some reason, the only one that actually works for `println` is the first check - if !sp.allows_unstable("format_args_nl") // the span is marked as `#[allow_insternal_unsable]` + if !sp.allows_unstable(sym::format_args_nl) // the span is marked `#[allow_insternal_unsable]` && !ecx.ecfg.enable_allow_internal_unstable() // NOTE: when is this enabled? && !ecx.ecfg.enable_format_args_nl() // enabled using `#[feature(format_args_nl]` { feature_gate::emit_feature_err(&ecx.parse_sess, - "format_args_nl", + sym::format_args_nl, sp, feature_gate::GateIssue::Language, feature_gate::EXPLAIN_FORMAT_ARGS_NL); diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs index 2baf530aedae..3f2853e4b0e2 100644 --- a/src/libsyntax_ext/global_asm.rs +++ b/src/libsyntax_ext/global_asm.rs @@ -16,12 +16,12 @@ use syntax::ext::base::{self, *}; use syntax::feature_gate; use syntax::parse::token; use syntax::ptr::P; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax_pos::Span; use syntax::tokenstream; use smallvec::smallvec; -pub const MACRO: &str = "global_asm"; +pub const MACRO: Symbol = sym::global_asm; pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, diff --git a/src/libsyntax_ext/log_syntax.rs b/src/libsyntax_ext/log_syntax.rs index 658ce98d2688..1be3990837cf 100644 --- a/src/libsyntax_ext/log_syntax.rs +++ b/src/libsyntax_ext/log_syntax.rs @@ -2,6 +2,7 @@ use syntax::ext::base; use syntax::feature_gate; use syntax::print; use syntax::tokenstream; +use syntax::symbol::sym; use syntax_pos; pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt<'_>, @@ -10,7 +11,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt<'_>, -> Box { if !cx.ecfg.enable_log_syntax() { feature_gate::emit_feature_err(&cx.parse_sess, - "log_syntax", + sym::log_syntax, sp, feature_gate::GateIssue::Language, feature_gate::EXPLAIN_LOG_SYNTAX); diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs index f0390ba3d40c..5ced1400acb0 100644 --- a/src/libsyntax_ext/proc_macro_decls.rs +++ b/src/libsyntax_ext/proc_macro_decls.rs @@ -13,12 +13,16 @@ use syntax::mut_visit::MutVisitor; use syntax::parse::ParseSess; use syntax::ptr::P; use syntax::symbol::Symbol; -use syntax::symbol::keywords; +use syntax::symbol::{keywords, sym}; use syntax::visit::{self, Visitor}; use syntax_pos::{Span, DUMMY_SP}; -const PROC_MACRO_KINDS: [&str; 3] = ["proc_macro_derive", "proc_macro_attribute", "proc_macro"]; +const PROC_MACRO_KINDS: [Symbol; 3] = [ + sym::proc_macro_derive, + sym::proc_macro_attribute, + sym::proc_macro +]; struct ProcMacroDerive { trait_name: ast::Name, @@ -139,7 +143,7 @@ impl<'a> CollectProcMacros<'a> { let attributes_attr = list.get(1); let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr { - if !attr.check_name("attributes") { + if !attr.check_name(sym::attributes) { self.handler.span_err(attr.span(), "second argument must be `attributes`") } attr.meta_item_list().unwrap_or_else(|| { @@ -231,7 +235,7 @@ impl<'a> CollectProcMacros<'a> { impl<'a> Visitor<'a> for CollectProcMacros<'a> { fn visit_item(&mut self, item: &'a ast::Item) { if let ast::ItemKind::MacroDef(..) = item.node { - if self.is_proc_macro_crate && attr::contains_name(&item.attrs, "macro_export") { + if self.is_proc_macro_crate && attr::contains_name(&item.attrs, sym::macro_export) { let msg = "cannot export macro_rules! macros from a `proc-macro` crate type currently"; self.handler.span_err(item.span, msg); @@ -304,11 +308,11 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { return; } - if attr.check_name("proc_macro_derive") { + if attr.check_name(sym::proc_macro_derive) { self.collect_custom_derive(item, attr); - } else if attr.check_name("proc_macro_attribute") { + } else if attr.check_name(sym::proc_macro_attribute) { self.collect_attr_proc_macro(item); - } else if attr.check_name("proc_macro") { + } else if attr.check_name(sym::proc_macro) { self.collect_bang_proc_macro(item); }; diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs index 0fa5cd64360c..86ae6ab5fece 100644 --- a/src/libsyntax_ext/test.rs +++ b/src/libsyntax_ext/test.rs @@ -7,7 +7,7 @@ use syntax::ext::hygiene::{self, Mark, SyntaxContext}; use syntax::attr; use syntax::ast; use syntax::print::pprust; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax_pos::{DUMMY_SP, Span}; use syntax::source_map::{ExpnInfo, MacroAttribute}; use std::iter; @@ -206,15 +206,15 @@ enum ShouldPanic { } fn should_ignore(i: &ast::Item) -> bool { - attr::contains_name(&i.attrs, "ignore") + attr::contains_name(&i.attrs, sym::ignore) } fn should_fail(i: &ast::Item) -> bool { - attr::contains_name(&i.attrs, "allow_fail") + attr::contains_name(&i.attrs, sym::allow_fail) } fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic { - match attr::find_by_name(&i.attrs, "should_panic") { + match attr::find_by_name(&i.attrs, sym::should_panic) { Some(attr) => { let ref sd = cx.parse_sess.span_diagnostic; @@ -222,7 +222,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic { // Handle #[should_panic(expected = "foo")] Some(list) => { let msg = list.iter() - .find(|mi| mi.check_name("expected")) + .find(|mi| mi.check_name(sym::expected)) .and_then(|mi| mi.meta_item()) .and_then(|mi| mi.value_str()); if list.len() != 1 || msg.is_none() { @@ -247,7 +247,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic { } fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool { - let has_should_panic_attr = attr::contains_name(&i.attrs, "should_panic"); + let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic); let ref sd = cx.parse_sess.span_diagnostic; if let ast::ItemKind::Fn(ref decl, ref header, ref generics, _) = i.node { if header.unsafety == ast::Unsafety::Unsafe { diff --git a/src/libsyntax_ext/test_case.rs b/src/libsyntax_ext/test_case.rs index 1ed1ab0a07b9..802037f6d22b 100644 --- a/src/libsyntax_ext/test_case.rs +++ b/src/libsyntax_ext/test_case.rs @@ -14,7 +14,7 @@ use syntax::ext::build::AstBuilder; use syntax::ext::hygiene::{self, Mark, SyntaxContext}; use syntax::ast; use syntax::source_map::respan; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax_pos::{DUMMY_SP, Span}; use syntax::source_map::{ExpnInfo, MacroAttribute}; use syntax::feature_gate; @@ -27,7 +27,7 @@ pub fn expand( ) -> Vec { if !ecx.ecfg.enable_custom_test_frameworks() { feature_gate::emit_feature_err(&ecx.parse_sess, - "custom_test_frameworks", + sym::custom_test_frameworks, attr_sp, feature_gate::GateIssue::Language, feature_gate::EXPLAIN_CUSTOM_TEST_FRAMEWORKS); diff --git a/src/libsyntax_ext/trace_macros.rs b/src/libsyntax_ext/trace_macros.rs index 4d35daf3de99..eca658cb5473 100644 --- a/src/libsyntax_ext/trace_macros.rs +++ b/src/libsyntax_ext/trace_macros.rs @@ -1,6 +1,6 @@ use syntax::ext::base::{self, ExtCtxt}; use syntax::feature_gate; -use syntax::symbol::keywords; +use syntax::symbol::{keywords, sym}; use syntax_pos::Span; use syntax::tokenstream::TokenTree; @@ -10,7 +10,7 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt<'_>, -> Box { if !cx.ecfg.enable_trace_macros() { feature_gate::emit_feature_err(&cx.parse_sess, - "trace_macros", + sym::trace_macros, sp, feature_gate::GateIssue::Language, feature_gate::EXPLAIN_TRACE_MACROS); diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index d690a3919962..c5d6da74eb61 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -33,7 +33,7 @@ mod span_encoding; pub use span_encoding::{Span, DUMMY_SP}; pub mod symbol; -pub use symbol::sym; +pub use symbol::{Symbol, sym}; mod analyze_source_file; @@ -388,7 +388,7 @@ impl Span { /// Checks if a span is "internal" to a macro in which `#[unstable]` /// items can be used (that is, a macro marked with /// `#[allow_internal_unstable]`). - pub fn allows_unstable(&self, feature: &str) -> bool { + pub fn allows_unstable(&self, feature: Symbol) -> bool { match self.ctxt().outer().expn_info() { Some(info) => info .allow_internal_unstable diff --git a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs index 699972c9a85b..c6b33fbc75ee 100644 --- a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs +++ b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs @@ -14,7 +14,7 @@ use syntax::ast; use syntax::attr; use syntax::ext::base::{MultiDecorator, ExtCtxt, Annotatable}; use syntax::ext::build::AstBuilder; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax::ptr::P; use syntax_ext::deriving::generic::{TraitDef, MethodDef, combine_substructure}; use syntax_ext::deriving::generic::{Substructure, Struct, EnumMatching}; @@ -71,7 +71,7 @@ fn totalsum_substructure(cx: &mut ExtCtxt, trait_span: Span, }; fields.iter().fold(cx.expr_isize(trait_span, 0), |acc, ref item| { - if attr::contains_name(&item.attrs, "ignore") { + if attr::contains_name(&item.attrs, sym::ignore) { acc } else { cx.expr_binary(item.span, ast::BinOpKind::Add, acc, diff --git a/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs index 76d0906f97c9..40e0115c623e 100644 --- a/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs +++ b/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs @@ -23,7 +23,7 @@ use syntax::{ast, source_map}; #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { reg.register_late_lint_pass(box MissingWhitelistedAttrPass); - reg.register_attribute("whitelisted_attr".to_string(), Whitelisted); + reg.register_attribute(Symbol::intern("whitelisted_attr"), Whitelisted); } declare_lint! { @@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingWhitelistedAttrPass { _ => cx.tcx.hir().expect_item_by_hir_id(cx.tcx.hir().get_parent_item(id)), }; - if !attr::contains_name(&item.attrs, "whitelisted_attr") { + if !attr::contains_name(&item.attrs, Symbol::intern("whitelisted_attr")) { cx.span_lint(MISSING_WHITELISTED_ATTR, span, "Missing 'whitelisted_attr' attribute"); } diff --git a/src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs b/src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs index f34e10218d45..8c7bd7222e73 100644 --- a/src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs +++ b/src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs @@ -11,6 +11,7 @@ use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPass use rustc_plugin::Registry; use rustc::hir; use syntax::attr; +use syntax::symbol::Symbol; macro_rules! fake_lint_pass { ($struct:ident, $lints:expr, $($attr:expr),*) => { @@ -49,19 +50,19 @@ declare_lint!(CRATE_NOT_GREEN, Warn, "crate not marked with #![crate_green]"); fake_lint_pass! { PassOkay, lint_array!(CRATE_NOT_OKAY), // Single lint - "rustc_crate_okay" + Symbol::intern("rustc_crate_okay") } fake_lint_pass! { PassRedBlue, lint_array!(CRATE_NOT_RED, CRATE_NOT_BLUE), // Multiple lints - "rustc_crate_red", "rustc_crate_blue" + Symbol::intern("rustc_crate_red"), Symbol::intern("rustc_crate_blue") } fake_lint_pass! { PassGreyGreen, lint_array!(CRATE_NOT_GREY, CRATE_NOT_GREEN, ), // Trailing comma - "rustc_crate_grey", "rustc_crate_green" + Symbol::intern("rustc_crate_grey"), Symbol::intern("rustc_crate_green") } #[plugin_registrar] diff --git a/src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs index c83e7bdb9983..039124f31ff4 100644 --- a/src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs @@ -8,14 +8,14 @@ extern crate syntax; extern crate rustc; extern crate rustc_plugin; +use syntax::symbol::Symbol; use syntax::feature_gate::AttributeType; use rustc_plugin::Registry; - #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_attribute("foo".to_owned(), AttributeType::Normal); - reg.register_attribute("bar".to_owned(), AttributeType::CrateLevel); - reg.register_attribute("baz".to_owned(), AttributeType::Whitelisted); + reg.register_attribute(Symbol::intern("foo"), AttributeType::Normal); + reg.register_attribute(Symbol::intern("bar"), AttributeType::CrateLevel); + reg.register_attribute(Symbol::intern("baz"), AttributeType::Whitelisted); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs index e8f1d2eedf55..7656b15721ad 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs @@ -11,6 +11,7 @@ use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPass use rustc_plugin::Registry; use rustc::hir; use syntax::attr; +use syntax::symbol::Symbol; declare_lint! { CRATE_NOT_OKAY, @@ -22,7 +23,7 @@ declare_lint_pass!(Pass => [CRATE_NOT_OKAY]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { fn check_crate(&mut self, cx: &LateContext, krate: &hir::Crate) { - if !attr::contains_name(&krate.attrs, "crate_okay") { + if !attr::contains_name(&krate.attrs, Symbol::intern("crate_okay")) { cx.span_lint(CRATE_NOT_OKAY, krate.span, "crate is not marked with #![crate_okay]"); } From 999c1fc2819e34539706b193711735d997633ef1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 7 May 2019 16:03:44 +1000 Subject: [PATCH 118/239] Remove the equality operation between `Symbol` and strings. And also the equality between `Path` and strings, because `Path` is made up of `Symbol`s. --- src/librustc/hir/lowering.rs | 69 ++++++++++--------- src/librustc/hir/map/mod.rs | 4 +- src/librustc/lint/levels.rs | 4 +- src/librustc/middle/entry.rs | 2 +- src/librustc/middle/lib_features.rs | 2 +- src/librustc/middle/stability.rs | 2 +- src/librustc/middle/weak_lang_items.rs | 6 +- src/librustc/session/config.rs | 3 +- src/librustc/traits/project.rs | 5 +- src/librustc_codegen_ssa/back/write.rs | 2 +- src/librustc_codegen_utils/link.rs | 2 +- src/librustc_driver/lib.rs | 3 +- src/librustc_interface/util.rs | 30 ++++---- src/librustc_metadata/creader.rs | 2 +- src/librustc_metadata/cstore_impl.rs | 4 +- src/librustc_metadata/link_args.rs | 2 +- src/librustc_metadata/locator.rs | 4 +- src/librustc_metadata/native_libs.rs | 4 +- src/librustc_plugin/registry.rs | 4 +- src/librustc_resolve/build_reduced_graph.rs | 2 +- src/librustc_resolve/lib.rs | 6 +- src/librustc_resolve/macros.rs | 13 ++-- src/librustc_resolve/resolve_imports.rs | 13 ++-- src/librustc_save_analysis/lib.rs | 2 +- src/librustc_typeck/check/mod.rs | 3 +- src/librustc_typeck/collect.rs | 4 +- src/librustdoc/clean/cfg.rs | 4 +- src/librustdoc/clean/mod.rs | 4 +- src/librustdoc/core.rs | 4 +- .../passes/collect_intra_doc_links.rs | 2 +- src/libsyntax/ast.rs | 6 -- src/libsyntax/attr/builtin.rs | 22 +++--- src/libsyntax/entry.rs | 2 +- src/libsyntax/ext/base.rs | 4 +- src/libsyntax/ext/derive.rs | 4 +- src/libsyntax/ext/expand.rs | 8 +-- src/libsyntax/ext/tt/macro_rules.rs | 23 ++++--- src/libsyntax/feature_gate.rs | 18 ++--- src/libsyntax/parse/mod.rs | 16 +++-- src/libsyntax/parse/parser.rs | 2 +- src/libsyntax/std_inject.rs | 3 + src/libsyntax/test.rs | 3 +- src/libsyntax_ext/asm.rs | 8 +-- src/libsyntax_ext/deriving/mod.rs | 4 +- src/libsyntax_pos/edition.rs | 7 +- src/libsyntax_pos/lib.rs | 2 +- src/libsyntax_pos/symbol.rs | 6 -- .../ui-fulldeps/auxiliary/lint-plugin-test.rs | 2 +- .../ui-fulldeps/auxiliary/lint-tool-test.rs | 4 +- 49 files changed, 182 insertions(+), 173 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 0d80a0874e63..dd0d13d8f5a6 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -73,7 +73,7 @@ use syntax_pos::Span; const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF; pub struct LoweringContext<'a> { - crate_root: Option<&'static str>, + crate_root: Option, /// Used to assign ids to HIR nodes that do not directly correspond to an AST node. sess: &'a Session, @@ -164,8 +164,8 @@ pub trait Resolver { fn resolve_str_path( &mut self, span: Span, - crate_root: Option<&str>, - components: &[&str], + crate_root: Option, + components: &[Symbol], is_value: bool, ) -> hir::Path; } @@ -228,7 +228,7 @@ pub fn lower_crate( dep_graph.assert_ignored(); LoweringContext { - crate_root: std_inject::injected_crate_name(), + crate_root: std_inject::injected_crate_name().map(Symbol::intern), sess, cstore, resolver, @@ -1149,7 +1149,7 @@ impl<'a> LoweringContext<'a> { ].into()), ); let gen_future = self.expr_std_path( - unstable_span, &["future", "from_generator"], None, ThinVec::new()); + unstable_span, &[sym::future, sym::from_generator], None, ThinVec::new()); hir::ExprKind::Call(P(gen_future), hir_vec![generator]) } @@ -2548,7 +2548,7 @@ impl<'a> LoweringContext<'a> { // ::std::future::Future let future_path = - self.std_path(span, &["future", "Future"], Some(future_params), false); + self.std_path(span, &[sym::future, sym::Future], Some(future_params), false); hir::GenericBound::Trait( hir::PolyTraitRef { @@ -4194,7 +4194,7 @@ impl<'a> LoweringContext<'a> { |x: P| x.into_inner(), ); block.expr = Some(this.wrap_in_try_constructor( - "from_ok", tail, unstable_span)); + sym::from_ok, tail, unstable_span)); hir::ExprKind::Block(P(block), None) }) } @@ -4336,7 +4336,7 @@ impl<'a> LoweringContext<'a> { self.expr_call_std_assoc_fn( id, e.span, - &["ops", "RangeInclusive"], + &[sym::ops, sym::RangeInclusive], "new", hir_vec![e1, e2], ) @@ -4345,11 +4345,11 @@ impl<'a> LoweringContext<'a> { use syntax::ast::RangeLimits::*; let path = match (e1, e2, lims) { - (&None, &None, HalfOpen) => "RangeFull", - (&Some(..), &None, HalfOpen) => "RangeFrom", - (&None, &Some(..), HalfOpen) => "RangeTo", - (&Some(..), &Some(..), HalfOpen) => "Range", - (&None, &Some(..), Closed) => "RangeToInclusive", + (&None, &None, HalfOpen) => sym::RangeFull, + (&Some(..), &None, HalfOpen) => sym::RangeFrom, + (&None, &Some(..), HalfOpen) => sym::RangeTo, + (&Some(..), &Some(..), HalfOpen) => sym::Range, + (&None, &Some(..), Closed) => sym::RangeToInclusive, (&Some(..), &Some(..), Closed) => unreachable!(), (_, &None, Closed) => self.diagnostic() .span_fatal(e.span, "inclusive range with no end") @@ -4367,7 +4367,7 @@ impl<'a> LoweringContext<'a> { .collect::>(); let is_unit = fields.is_empty(); - let struct_path = ["ops", path]; + let struct_path = [sym::ops, path]; let struct_path = self.std_path(e.span, &struct_path, None, is_unit); let struct_path = hir::QPath::Resolved(None, P(struct_path)); @@ -4656,7 +4656,7 @@ impl<'a> LoweringContext<'a> { let match_expr = { let iter = P(self.expr_ident(head_sp, iter, iter_pat_nid)); let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter); - let next_path = &["iter", "Iterator", "next"]; + let next_path = &[sym::iter, sym::Iterator, sym::next]; let next_expr = P(self.expr_call_std_path( head_sp, next_path, @@ -4723,7 +4723,8 @@ impl<'a> LoweringContext<'a> { // `match ::std::iter::IntoIterator::into_iter() { ... }` let into_iter_expr = { - let into_iter_path = &["iter", "IntoIterator", "into_iter"]; + let into_iter_path = + &[sym::iter, sym::IntoIterator, sym::into_iter]; P(self.expr_call_std_path( head_sp, into_iter_path, @@ -4780,7 +4781,7 @@ impl<'a> LoweringContext<'a> { // expand let sub_expr = self.lower_expr(sub_expr); - let path = &["ops", "Try", "into_result"]; + let path = &[sym::ops, sym::Try, sym::into_result]; P(self.expr_call_std_path( unstable_span, path, @@ -4822,12 +4823,12 @@ impl<'a> LoweringContext<'a> { let err_ident = self.str_to_ident("err"); let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident); let from_expr = { - let from_path = &["convert", "From", "from"]; + let from_path = &[sym::convert, sym::From, sym::from]; let err_expr = self.expr_ident(try_span, err_ident, err_local_nid); self.expr_call_std_path(try_span, from_path, hir_vec![err_expr]) }; let from_err_expr = - self.wrap_in_try_constructor("from_error", from_expr, unstable_span); + self.wrap_in_try_constructor(sym::from_error, from_expr, unstable_span); let thin_attrs = ThinVec::from(attrs); let catch_scope = self.catch_scopes.last().map(|x| *x); let ret_expr = if let Some(catch_node) = catch_scope { @@ -5057,7 +5058,7 @@ impl<'a> LoweringContext<'a> { fn expr_call_std_path( &mut self, span: Span, - path_components: &[&str], + path_components: &[Symbol], args: hir::HirVec, ) -> hir::Expr { let path = P(self.expr_std_path(span, path_components, None, ThinVec::new())); @@ -5077,7 +5078,7 @@ impl<'a> LoweringContext<'a> { &mut self, ty_path_id: hir::HirId, span: Span, - ty_path_components: &[&str], + ty_path_components: &[Symbol], assoc_fn_name: &str, args: hir::HirVec, ) -> hir::ExprKind { @@ -5119,7 +5120,7 @@ impl<'a> LoweringContext<'a> { fn expr_std_path( &mut self, span: Span, - components: &[&str], + components: &[Symbol], params: Option>, attrs: ThinVec, ) -> hir::Expr { @@ -5250,25 +5251,25 @@ impl<'a> LoweringContext<'a> { } fn pat_ok(&mut self, span: Span, pat: P) -> P { - self.pat_std_enum(span, &["result", "Result", "Ok"], hir_vec![pat]) + self.pat_std_enum(span, &[sym::result, sym::Result, sym::Ok], hir_vec![pat]) } fn pat_err(&mut self, span: Span, pat: P) -> P { - self.pat_std_enum(span, &["result", "Result", "Err"], hir_vec![pat]) + self.pat_std_enum(span, &[sym::result, sym::Result, sym::Err], hir_vec![pat]) } fn pat_some(&mut self, span: Span, pat: P) -> P { - self.pat_std_enum(span, &["option", "Option", "Some"], hir_vec![pat]) + self.pat_std_enum(span, &[sym::option, sym::Option, sym::Some], hir_vec![pat]) } fn pat_none(&mut self, span: Span) -> P { - self.pat_std_enum(span, &["option", "Option", "None"], hir_vec![]) + self.pat_std_enum(span, &[sym::option, sym::Option, sym::None], hir_vec![]) } fn pat_std_enum( &mut self, span: Span, - components: &[&str], + components: &[Symbol], subpats: hir::HirVec>, ) -> P { let path = self.std_path(span, components, None, true); @@ -5321,7 +5322,7 @@ impl<'a> LoweringContext<'a> { fn std_path( &mut self, span: Span, - components: &[&str], + components: &[Symbol], params: Option>, is_value: bool, ) -> hir::Path { @@ -5520,11 +5521,11 @@ impl<'a> LoweringContext<'a> { fn wrap_in_try_constructor( &mut self, - method: &'static str, + method: Symbol, e: hir::Expr, unstable_span: Span, ) -> P { - let path = &["ops", "Try", method]; + let path = &[sym::ops, sym::Try, method]; let from_err = P(self.expr_std_path(unstable_span, path, None, ThinVec::new())); P(self.expr_call(e.span, from_err, hir_vec![e])) @@ -5594,7 +5595,7 @@ impl<'a> LoweringContext<'a> { let new_unchecked_expr_kind = self.expr_call_std_assoc_fn( pin_ty_id, span, - &["pin", "Pin"], + &[sym::pin, sym::Pin], "new_unchecked", hir_vec![ref_mut_pinned], ); @@ -5602,7 +5603,7 @@ impl<'a> LoweringContext<'a> { let unsafe_expr = self.expr_unsafe(new_unchecked); P(self.expr_call_std_path( gen_future_span, - &["future", "poll_with_tls_context"], + &[sym::future, sym::poll_with_tls_context], hir_vec![unsafe_expr], )) }; @@ -5616,7 +5617,7 @@ impl<'a> LoweringContext<'a> { let x_expr = P(self.expr_ident(span, x_ident, x_pat_hid)); let ready_pat = self.pat_std_enum( span, - &["task", "Poll", "Ready"], + &[sym::task, sym::Poll, sym::Ready], hir_vec![x_pat], ); let break_x = self.with_loop_scope(loop_node_id, |this| { @@ -5633,7 +5634,7 @@ impl<'a> LoweringContext<'a> { let pending_arm = { let pending_pat = self.pat_std_enum( span, - &["task", "Poll", "Pending"], + &[sym::task, sym::Poll, sym::Pending], hir_vec![], ); let empty_block = P(self.expr_block_empty(span)); diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 1a48dff213b5..b8ee98551a20 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -1146,7 +1146,7 @@ impl<'a> NodesMatchingSuffix<'a> { None => return false, Some((node_id, name)) => (node_id, name), }; - if mod_name != &**part { + if mod_name.as_str() != *part { return false; } cursor = self.map.get_parent_item(mod_id); @@ -1183,7 +1183,7 @@ impl<'a> NodesMatchingSuffix<'a> { // We are looking at some node `n` with a given name and parent // id; do their names match what I am seeking? fn matches_names(&self, parent_of_n: HirId, name: Name) -> bool { - name == &**self.item_name && self.suffix_matches(parent_of_n) + name.as_str() == *self.item_name && self.suffix_matches(parent_of_n) } fn matches_suffix(&self, hir: HirId) -> bool { diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index a69758e33bab..6481f9af00b8 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -221,7 +221,7 @@ impl<'a> LintLevelsBuilder<'a> { match item.node { ast::MetaItemKind::Word => {} // actual lint names handled later ast::MetaItemKind::NameValue(ref name_value) => { - if item.path == "reason" { + if item.path == sym::reason { // found reason, reslice meta list to exclude it metas = &metas[0..metas.len()-1]; // FIXME (#55112): issue unused-attributes lint if we thereby @@ -261,7 +261,7 @@ impl<'a> LintLevelsBuilder<'a> { let mut err = bad_attr(li.span()); if let Some(item) = li.meta_item() { if let ast::MetaItemKind::NameValue(_) = item.node { - if item.path == "reason" { + if item.path == sym::reason { err.help("reason in lint attribute must come last"); } } diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index e2e76e69dc4e..67db2ec24815 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -86,7 +86,7 @@ fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType { EntryPointType::Start } else if attr::contains_name(&item.attrs, sym::main) { EntryPointType::MainAttr - } else if item.ident.name == "main" { + } else if item.ident.name == sym::main { if at_root { // This is a top-level function so can be 'main'. EntryPointType::MainNamed diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs index 5acd48c77d82..8696e2af8c2b 100644 --- a/src/librustc/middle/lib_features.rs +++ b/src/librustc/middle/lib_features.rs @@ -76,7 +76,7 @@ impl<'a, 'tcx> LibFeatureCollector<'a, 'tcx> { // This additional check for stability is to make sure we // don't emit additional, irrelevant errors for malformed // attributes. - if *stab_attr != "stable" || since.is_some() { + if *stab_attr != sym::stable || since.is_some() { return Some((feature, since, attr.span)); } } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index c608c72430cb..d9a44714d7d0 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -686,7 +686,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // the `-Z force-unstable-if-unmarked` flag present (we're // compiling a compiler crate), then let this missing feature // annotation slide. - if feature == "rustc_private" && issue == 27812 { + if feature == sym::rustc_private && issue == 27812 { if self.sess.opts.debugging_opts.force_unstable_if_unmarked { return EvalResult::Allow; } diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index 312924e5e90f..75c21c738f7a 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -6,7 +6,7 @@ use crate::middle::lang_items; use rustc_data_structures::fx::FxHashSet; use rustc_target::spec::PanicStrategy; use syntax::ast; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax_pos::Span; use crate::hir::def_id::DefId; use crate::hir::intravisit::{Visitor, NestedVisitorMap}; @@ -46,8 +46,8 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pub fn link_name(attrs: &[ast::Attribute]) -> Option { lang_items::extract(attrs).and_then(|(name, _)| { - $(if name == stringify!($name) { - Some(Symbol::intern(stringify!($sym))) + $(if name == sym::$name { + Some(sym::$sym) } else)* { None } diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 12427daa3838..f61ffac15d5f 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -2753,6 +2753,7 @@ mod tests { // another --cfg test #[test] fn test_switch_implies_cfg_test_unless_cfg_test() { + use syntax::symbol::sym; syntax::with_globals(|| { let matches = &match optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]) { @@ -2763,7 +2764,7 @@ mod tests { let (sessopts, cfg) = build_session_options_and_crate_config(matches); let sess = build_session(sessopts, None, registry); let cfg = build_configuration(&sess, to_crate_config(cfg)); - let mut test_items = cfg.iter().filter(|&&(name, _)| name == "test"); + let mut test_items = cfg.iter().filter(|&&(name, _)| name == sym::test); assert!(test_items.next().is_some()); assert!(test_items.next().is_none()); }); diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index b5232e828c4c..f05a19372918 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -19,6 +19,7 @@ use crate::mir::interpret::{GlobalId, ConstValue}; use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap}; use rustc_macros::HashStable; use syntax::ast::Ident; +use syntax::symbol::sym; use crate::ty::subst::{Subst, InternalSubsts}; use crate::ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt}; use crate::ty::fold::{TypeFoldable, TypeFolder}; @@ -1318,9 +1319,9 @@ fn confirm_generator_candidate<'cx, 'gcx, 'tcx>( gen_sig) .map_bound(|(trait_ref, yield_ty, return_ty)| { let name = tcx.associated_item(obligation.predicate.item_def_id).ident.name; - let ty = if name == "Return" { + let ty = if name == sym::Return { return_ty - } else if name == "Yield" { + } else if name == sym::Yield { yield_ty } else { bug!() diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 204ca59efc8d..6320d8a671dd 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -386,7 +386,7 @@ pub fn start_async_codegen( let subsystem = attr::first_attr_value_str_by_name(&tcx.hir().krate().attrs, sym::windows_subsystem); let windows_subsystem = subsystem.map(|subsystem| { - if subsystem != "windows" && subsystem != "console" { + if subsystem != sym::windows && subsystem != sym::console { tcx.sess.fatal(&format!("invalid windows subsystem `{}`, only \ `windows` and `console` are allowed", subsystem)); diff --git a/src/librustc_codegen_utils/link.rs b/src/librustc_codegen_utils/link.rs index 30f37fefa7cf..a2ac64fa7e0c 100644 --- a/src/librustc_codegen_utils/link.rs +++ b/src/librustc_codegen_utils/link.rs @@ -56,7 +56,7 @@ pub fn find_crate_name(sess: Option<&Session>, if let Some(sess) = sess { if let Some(ref s) = sess.opts.crate_name { if let Some((attr, name)) = attr_crate_name { - if name != &**s { + if name.as_str() != *s { let msg = format!("--crate-name and #[crate_name] are \ required to match, but `{}` != `{}`", s, name); diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 5b42b049b5b1..02f8eee67b15 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -63,6 +63,7 @@ use syntax::ast; use syntax::source_map::FileLoader; use syntax::feature_gate::{GatedCfg, UnstableFeatures}; use syntax::parse::{self, PResult}; +use syntax::symbol::sym; use syntax_pos::{DUMMY_SP, MultiSpan, FileName}; pub mod pretty; @@ -669,7 +670,7 @@ impl RustcDefaultCalls { // through to build scripts. let value = value.as_ref().map(|s| s.as_str()); let value = value.as_ref().map(|s| s.as_ref()); - if name != "target_feature" || value != Some("crt-static") { + if name != sym::target_feature || value != Some("crt-static") { if !allow_unstable_cfg && gated_cfg.is_some() { return None } diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 2b1a993d1cc2..d2d0d1918078 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -497,22 +497,22 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec Some(config::CrateType::Rlib), - Some(ref n) if *n == "dylib" => Some(config::CrateType::Dylib), - Some(ref n) if *n == "cdylib" => Some(config::CrateType::Cdylib), - Some(ref n) if *n == "lib" => Some(config::default_lib_output()), - Some(ref n) if *n == "staticlib" => Some(config::CrateType::Staticlib), - Some(ref n) if *n == "proc-macro" => Some(config::CrateType::ProcMacro), - Some(ref n) if *n == "bin" => Some(config::CrateType::Executable), - Some(ref n) => { + Some(sym::rlib) => Some(config::CrateType::Rlib), + Some(sym::dylib) => Some(config::CrateType::Dylib), + Some(sym::cdylib) => Some(config::CrateType::Cdylib), + Some(sym::lib) => Some(config::default_lib_output()), + Some(sym::staticlib) => Some(config::CrateType::Staticlib), + Some(sym::proc_dash_macro) => Some(config::CrateType::ProcMacro), + Some(sym::bin) => Some(config::CrateType::Executable), + Some(n) => { let crate_types = vec![ - Symbol::intern("rlib"), - Symbol::intern("dylib"), - Symbol::intern("cdylib"), - Symbol::intern("lib"), - Symbol::intern("staticlib"), - Symbol::intern("proc-macro"), - Symbol::intern("bin") + sym::rlib, + sym::dylib, + sym::cdylib, + sym::lib, + sym::staticlib, + sym::proc_dash_macro, + sym::bin ]; if let ast::MetaItemKind::NameValue(spanned) = a.meta().unwrap().node { diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 20caad70f2b5..b7b17a84aa76 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -837,7 +837,7 @@ impl<'a> CrateLoader<'a> { let mut uses_std = false; self.cstore.iter_crate_data(|_, data| { - if data.name == "std" { + if data.name == sym::std { uses_std = true; } }); diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index dfeaeca323f8..087256a97105 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -31,7 +31,7 @@ use syntax::source_map; use syntax::edition::Edition; use syntax::parse::source_file_to_stream; use syntax::parse::parser::emit_unclosed_delims; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax_pos::{Span, NO_EXPANSION, FileName}; use rustc_data_structures::bit_set::BitSet; @@ -432,7 +432,7 @@ impl cstore::CStore { let data = self.get_crate_data(id.krate); if let Some(ref proc_macros) = data.proc_macros { return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone()); - } else if data.name == "proc_macro" && data.item_name(id.index) == "quote" { + } else if data.name == sym::proc_macro && data.item_name(id.index) == "quote" { use syntax::ext::base::SyntaxExtension; use syntax_ext::proc_macro_impl::BangProcMacro; diff --git a/src/librustc_metadata/link_args.rs b/src/librustc_metadata/link_args.rs index cd5951f0e0e3..f4682465a659 100644 --- a/src/librustc_metadata/link_args.rs +++ b/src/librustc_metadata/link_args.rs @@ -11,7 +11,7 @@ pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec { tcx.hir().krate().visit_all_item_likes(&mut collector); for attr in tcx.hir().krate().attrs.iter() { - if attr.path == "link_args" { + if attr.path == sym::link_args { if let Some(linkarg) = attr.value_str() { collector.add_link_args(&linkarg.as_str()); } diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 116042c53fb9..7d7dd1061a95 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -225,7 +225,7 @@ use rustc::session::search_paths::PathKind; use rustc::util::nodemap::FxHashMap; use errors::DiagnosticBuilder; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax::struct_span_err; use syntax_pos::Span; use rustc_target::spec::{Target, TargetTriple}; @@ -408,7 +408,7 @@ impl<'a> Context<'a> { self.ident, add); - if (self.ident == "std" || self.ident == "core") + if (self.ident == sym::std || self.ident == sym::core) && self.triple != TargetTriple::from_triple(config::host_triple()) { err.note(&format!("the `{}` target may not be installed", self.triple)); } diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index 3e7e740a15c0..fee08f421549 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -181,7 +181,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> { let any_duplicate = self.libs .iter() .filter_map(|lib| lib.name.as_ref()) - .any(|n| n == name); + .any(|n| n.as_str() == *name); if new_name.is_empty() { self.tcx.sess.err( &format!("an empty renaming target was specified for library `{}`",name)); @@ -212,7 +212,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> { // can move them to the end of the list below. let mut existing = self.libs.drain_filter(|lib| { if let Some(lib_name) = lib.name { - if lib_name == name as &str { + if lib_name.as_str() == *name { if let Some(k) = kind { lib.kind = k; } diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 913657b2934e..c2d1d5fa65af 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -7,7 +7,7 @@ use rustc::util::nodemap::FxHashMap; use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT, IdentTT}; use syntax::ext::base::MacroExpanderFn; use syntax::ext::hygiene; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax::ast; use syntax::feature_gate::AttributeType; use syntax_pos::Span; @@ -86,7 +86,7 @@ impl<'a> Registry<'a> { /// /// This is the most general hook into `libsyntax`'s expansion behavior. pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) { - if name == "macro_rules" { + if name == sym::macro_rules { panic!("user-defined macros may not be named `macro_rules`"); } self.syntax_exts.push((name, match extension { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index cf09e31bb628..f70ca6f859b9 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -369,7 +369,7 @@ impl<'a> Resolver<'a> { }; self.populate_module_if_necessary(module); - if injected_crate_name().map_or(false, |name| ident.name == name) { + if injected_crate_name().map_or(false, |name| ident.name.as_str() == name) { self.injected_crate = Some(module); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0dd6f378730f..678f4c23d3e9 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1812,8 +1812,8 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { fn resolve_str_path( &mut self, span: Span, - crate_root: Option<&str>, - components: &[&str], + crate_root: Option, + components: &[Symbol], is_value: bool ) -> hir::Path { let root = if crate_root.is_some() { @@ -1825,7 +1825,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { .chain( crate_root.into_iter() .chain(components.iter().cloned()) - .map(Ident::from_str) + .map(Ident::with_empty_ctxt) ).map(|i| self.new_ast_path_segment(i)).collect::>(); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 62f2768888ad..9f3e1c308f63 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -982,7 +982,7 @@ impl<'a> Resolver<'a> { let msg = format!("cannot find {} `{}{}` in this scope", kind.descr(), ident, bang); let mut err = self.session.struct_span_err(ident.span, &msg); - self.suggest_macro_name(&ident.as_str(), kind, &mut err, ident.span); + self.suggest_macro_name(ident.name, kind, &mut err, ident.span); err.emit(); } } @@ -1010,11 +1010,12 @@ impl<'a> Resolver<'a> { } } - fn suggest_macro_name(&mut self, name: &str, kind: MacroKind, + fn suggest_macro_name(&mut self, name: Symbol, kind: MacroKind, err: &mut DiagnosticBuilder<'a>, span: Span) { // First check if this is a locally-defined bang macro. let suggestion = if let MacroKind::Bang = kind { - find_best_match_for_name(self.macro_names.iter().map(|ident| &ident.name), name, None) + find_best_match_for_name( + self.macro_names.iter().map(|ident| &ident.name), &name.as_str(), None) } else { None // Then check global macros. @@ -1023,7 +1024,7 @@ impl<'a> Resolver<'a> { .filter_map(|(name, binding)| { if binding.macro_kind() == Some(kind) { Some(name) } else { None } }); - find_best_match_for_name(names, name, None) + find_best_match_for_name(names, &name.as_str(), None) // Then check modules. }).or_else(|| { let is_macro = |res| { @@ -1033,7 +1034,7 @@ impl<'a> Resolver<'a> { false } }; - let ident = Ident::new(Symbol::intern(name), span); + let ident = Ident::new(name, span); self.lookup_typo_candidate(&[Segment::from_ident(ident)], MacroNS, is_macro, span) .map(|suggestion| suggestion.candidate) }); @@ -1092,7 +1093,7 @@ impl<'a> Resolver<'a> { current_legacy_scope: &mut LegacyScope<'a>) { self.local_macro_def_scopes.insert(item.id, self.current_module); let ident = item.ident; - if ident.name == "macro_rules" { + if ident.name == sym::macro_rules { self.session.span_err(item.span, "user-defined macros may not be named `macro_rules`"); } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 9e6b8d035458..4058f0bce0f9 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -29,7 +29,7 @@ use rustc::{bug, span_bug}; use syntax::ast::{self, Ident, Name, NodeId, CRATE_NODE_ID}; use syntax::ext::base::Determinacy::{self, Determined, Undetermined}; use syntax::ext::hygiene::Mark; -use syntax::symbol::keywords; +use syntax::symbol::{keywords, sym}; use syntax::util::lev_distance::find_best_match_for_name; use syntax::{struct_span_err, unwrap_or}; use syntax_pos::{MultiSpan, Span}; @@ -496,7 +496,8 @@ impl<'a> Resolver<'a> { // Reserve some names that are not quite covered by the general check // performed on `Resolver::builtin_attrs`. if ns == MacroNS && - (ident.name == "cfg" || ident.name == "cfg_attr" || ident.name == "derive") { + (ident.name == sym::cfg || ident.name == sym::cfg_attr || + ident.name == sym::derive) { self.session.span_err(ident.span, &format!("name `{}` is reserved in macro namespace", ident)); } @@ -706,7 +707,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { has_errors = true; if let SingleImport { source, ref source_bindings, .. } = import.subclass { - if source.name == "self" { + if source.name == keywords::SelfLower.name() { // Silence `unresolved import` error if E0429 is already emitted if let Err(Determined) = source_bindings.value_ns.get() { continue; @@ -1041,7 +1042,8 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { let initial_res = source_bindings[ns].get().map(|initial_binding| { all_ns_err = false; if let Some(target_binding) = target_bindings[ns].get() { - if target.name == "_" && + // Note that as_str() de-gensyms the Symbol + if target.name.as_str() == "_" && initial_binding.is_extern_crate() && !initial_binding.is_import() { this.record_use(ident, ns, target_binding, directive.module_path.is_empty()); @@ -1392,7 +1394,8 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { // (e.g. implicitly injected `std`) cannot be properly encoded in metadata, // so they can cause name conflict errors downstream. let is_good_import = binding.is_import() && !binding.is_ambiguity() && - !(ident.name.is_gensymed() && ident.name != "_"); + // Note that as_str() de-gensyms the Symbol + !(ident.name.is_gensymed() && ident.name.as_str() != "_"); if is_good_import || binding.is_macro_def() { let res = binding.res(); if res != Res::Err { diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index cb2454aa4b56..e03da2ed608b 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -1197,7 +1197,7 @@ fn null_id() -> rls_data::Id { fn lower_attributes(attrs: Vec, scx: &SaveContext<'_, '_>) -> Vec { attrs.into_iter() // Only retain real attributes. Doc comments are lowered separately. - .filter(|attr| attr.path != "doc") + .filter(|attr| attr.path != sym::doc) .map(|mut attr| { // Remove the surrounding '#[..]' or '#![..]' of the pretty printed // attribute. First normalize all inner attribute (#![..]) to outer diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a184a2daeb6a..362b6f0504d9 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4197,7 +4197,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // ... except when we try to 'break rust;'. // ICE this expression in particular (see #43162). if let ExprKind::Path(QPath::Resolved(_, ref path)) = e.node { - if path.segments.len() == 1 && path.segments[0].ident.name == "rust" { + if path.segments.len() == 1 && + path.segments[0].ident.name == sym::rust { fatally_break_rust(self.tcx.sess); } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 29b470894095..ffba9403743a 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2594,7 +2594,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen } codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| { - if attr.path != "inline" { + if attr.path != sym::inline { return ia; } match attr.meta().map(|i| i.node) { @@ -2634,7 +2634,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen }); codegen_fn_attrs.optimize = attrs.iter().fold(OptimizeAttr::None, |ia, attr| { - if attr.path != "optimize" { + if attr.path != sym::optimize { return ia; } let err = |sp, s| span_err!(tcx.sess.diagnostic(), sp, E0722, "{}", s); diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index b96ac19c1ea6..c795b2dcd7a4 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -7,7 +7,7 @@ use std::mem; use std::fmt::{self, Write}; use std::ops; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax::ast::{MetaItem, MetaItemKind, NestedMetaItem, LitKind}; use syntax::parse::ParseSess; use syntax::feature_gate::Features; @@ -186,7 +186,7 @@ impl Cfg { fn should_use_with_in_description(&self) -> bool { match *self { - Cfg::Cfg(ref name, _) if name == &"target_feature" => true, + Cfg::Cfg(name, _) if name == sym::target_feature => true, _ => false, } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6790b13dbf8d..f9a43ccfbace 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4383,7 +4383,7 @@ where // Start of code copied from rust-clippy -pub fn path_to_def_local(tcx: TyCtxt<'_, '_, '_>, path: &[&str]) -> Option { +pub fn path_to_def_local(tcx: TyCtxt<'_, '_, '_>, path: &[Symbol]) -> Option { let krate = tcx.hir().krate(); let mut items = krate.module.item_ids.clone(); let mut path_it = path.iter().peekable(); @@ -4408,7 +4408,7 @@ pub fn path_to_def_local(tcx: TyCtxt<'_, '_, '_>, path: &[&str]) -> Option, path: &[&str]) -> Option { +pub fn path_to_def(tcx: TyCtxt<'_, '_, '_>, path: &[Symbol]) -> Option { let crates = tcx.crates(); let krate = crates diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 1b099fbd91d1..bc87086e1061 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -368,9 +368,9 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt }; let send_trait = if crate_name == Some("core".to_string()) { - clean::path_to_def_local(tcx, &["marker", "Send"]) + clean::path_to_def_local(tcx, &[sym::marker, sym::Send]) } else { - clean::path_to_def(tcx, &["core", "marker", "Send"]) + clean::path_to_def(tcx, &[sym::core, sym::marker, sym::Send]) }; let mut renderinfo = RenderInfo::default(); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index abf19a0a5efa..9e108e605c8b 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -99,7 +99,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // Try looking for methods and associated items. let mut split = path_str.rsplitn(2, "::"); let item_name = if let Some(first) = split.next() { - first + Symbol::intern(first) } else { return Err(()) }; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index aa176c892588..d12240655e62 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -81,12 +81,6 @@ impl PartialEq for Path { } } -impl<'a> PartialEq<&'a str> for Path { - fn eq(&self, string: &&'a str) -> bool { - self.segments.len() == 1 && self.segments[0].ident.name == *string - } -} - impl fmt::Debug for Path { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "path({})", pprust::path_to_string(self)) diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index a8310c48b962..43de3f74e4a2 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -185,12 +185,12 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, 'outer: for attr in attrs_iter { if ![ - "rustc_deprecated", - "rustc_const_unstable", - "unstable", - "stable", - "rustc_promotable", - "rustc_allow_const_fn_ptr", + sym::rustc_deprecated, + sym::rustc_const_unstable, + sym::unstable, + sym::stable, + sym::rustc_promotable, + sym::rustc_allow_const_fn_ptr, ].iter().any(|&s| attr.path == s) { continue // not a stability level } @@ -199,10 +199,10 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, let meta = attr.meta(); - if attr.path == "rustc_promotable" { + if attr.path == sym::rustc_promotable { promotable = true; } - if attr.path == "rustc_allow_const_fn_ptr" { + if attr.path == sym::rustc_allow_const_fn_ptr { allow_const_fn_ptr = true; } // attributes with data @@ -721,7 +721,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec { let mut acc = Vec::new(); let diagnostic = &sess.span_diagnostic; - if attr.path == "repr" { + if attr.path == sym::repr { if let Some(items) = attr.meta_item_list() { mark_used(attr); for item in items { @@ -770,14 +770,14 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec { }; let mut literal_error = None; - if name == "align" { + if name == sym::align { recognised = true; match parse_alignment(&value.node) { Ok(literal) => acc.push(ReprAlign(literal)), Err(message) => literal_error = Some(message) }; } - else if name == "packed" { + else if name == sym::packed { recognised = true; match parse_alignment(&value.node) { Ok(literal) => acc.push(ReprPacked(literal)), diff --git a/src/libsyntax/entry.rs b/src/libsyntax/entry.rs index 267f863ce35e..0b6cf30bd27d 100644 --- a/src/libsyntax/entry.rs +++ b/src/libsyntax/entry.rs @@ -19,7 +19,7 @@ pub fn entry_point_type(item: &Item, depth: usize) -> EntryPointType { EntryPointType::Start } else if attr::contains_name(&item.attrs, sym::main) { EntryPointType::MainAttr - } else if item.ident.name == "main" { + } else if item.ident.name == sym::main { if depth == 1 { // This is a top-level function so can be 'main' EntryPointType::MainNamed diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index cc19acb61adc..0a88d2f8824d 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -10,7 +10,7 @@ use crate::mut_visit::{self, MutVisitor}; use crate::parse::{self, parser, DirectoryOwnership}; use crate::parse::token; use crate::ptr::P; -use crate::symbol::{keywords, Ident, Symbol}; +use crate::symbol::{keywords, Ident, Symbol, sym}; use crate::ThinVec; use crate::tokenstream::{self, TokenStream}; @@ -871,7 +871,7 @@ impl<'a> ExtCtxt<'a> { let mut last_macro = None; loop { if ctxt.outer().expn_info().map_or(None, |info| { - if info.format.name() == "include" { + if info.format.name() == sym::include { // Stop going up the backtrace once include! is encountered return None; } diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs index 6df369133d01..a24e09f127ea 100644 --- a/src/libsyntax/ext/derive.rs +++ b/src/libsyntax/ext/derive.rs @@ -4,7 +4,7 @@ use crate::source_map::{hygiene, ExpnInfo, ExpnFormat}; use crate::ext::base::ExtCtxt; use crate::ext::build::AstBuilder; use crate::parse::parser::PathStyle; -use crate::symbol::Symbol; +use crate::symbol::{Symbol, sym}; use syntax_pos::Span; @@ -13,7 +13,7 @@ use rustc_data_structures::fx::FxHashSet; pub fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec) -> Vec { let mut result = Vec::new(); attrs.retain(|attr| { - if attr.path != "derive" { + if attr.path != sym::derive { return true; } if !attr.is_meta_item_list() { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 7ebfcfd176ad..a286fd83e3c2 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -376,7 +376,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } let mut item = self.fully_configure(item); - item.visit_attrs(|attrs| attrs.retain(|a| a.path != "derive")); + item.visit_attrs(|attrs| attrs.retain(|a| a.path != sym::derive)); let mut item_with_markers = item.clone(); add_derived_markers(&mut self.cx, item.span(), &traits, &mut item_with_markers); let derives = derives.entry(invoc.expansion_data.mark).or_default(); @@ -1109,7 +1109,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { -> Option { let attr = attrs.iter() .position(|a| { - if a.path == "derive" { + if a.path == sym::derive { *after_derive = true; } !attr::is_known(a) && !is_builtin_attr(a) @@ -1117,7 +1117,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { .map(|i| attrs.remove(i)); if let Some(attr) = &attr { if !self.cx.ecfg.enable_custom_inner_attributes() && - attr.style == ast::AttrStyle::Inner && attr.path != "test" { + attr.style == ast::AttrStyle::Inner && attr.path != sym::test { emit_feature_err(&self.cx.parse_sess, sym::custom_inner_attributes, attr.span, GateIssue::Language, "non-builtin inner attributes are unstable"); @@ -1167,7 +1167,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { self.check_attribute_inner(attr, features); // macros are expanded before any lint passes so this warning has to be hardcoded - if attr.path == "derive" { + if attr.path == sym::derive { self.cx.struct_span_warn(attr.span, "`#[derive]` does nothing on macro invocations") .note("this may become a hard error in a future release") .emit(); diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 555962100936..06651750de74 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -13,7 +13,7 @@ use crate::parse::{Directory, ParseSess}; use crate::parse::parser::Parser; use crate::parse::token::{self, NtTT}; use crate::parse::token::Token::*; -use crate::symbol::{Symbol, sym}; +use crate::symbol::{Symbol, keywords, sym}; use crate::tokenstream::{DelimSpan, TokenStream, TokenTree}; use errors::FatalError; @@ -467,7 +467,7 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[quoted::TokenTree]) -> bool { TokenTree::Sequence(span, ref seq) => { if seq.separator.is_none() && seq.tts.iter().all(|seq_tt| { match *seq_tt { - TokenTree::MetaVarDecl(_, _, id) => id.name == "vis", + TokenTree::MetaVarDecl(_, _, id) => id.name == sym::vis, TokenTree::Sequence(_, ref sub_seq) => sub_seq.op == quoted::KleeneOp::ZeroOrMore || sub_seq.op == quoted::KleeneOp::ZeroOrOne, @@ -1046,7 +1046,8 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> IsInFollow { match *tok { TokenTree::Token(_, ref tok) => match *tok { FatArrow | Comma | Eq | BinOp(token::Or) => IsInFollow::Yes, - Ident(i, false) if i.name == "if" || i.name == "in" => IsInFollow::Yes, + Ident(i, false) if i.name == keywords::If.name() || + i.name == keywords::In.name() => IsInFollow::Yes, _ => IsInFollow::No(tokens), }, _ => IsInFollow::No(tokens), @@ -1063,10 +1064,12 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> IsInFollow { OpenDelim(token::DelimToken::Bracket) | Comma | FatArrow | Colon | Eq | Gt | BinOp(token::Shr) | Semi | BinOp(token::Or) => IsInFollow::Yes, - Ident(i, false) if i.name == "as" || i.name == "where" => IsInFollow::Yes, + Ident(i, false) if i.name == keywords::As.name() || + i.name == keywords::Where.name() => IsInFollow::Yes, _ => IsInFollow::No(tokens), }, - TokenTree::MetaVarDecl(_, _, frag) if frag.name == "block" => IsInFollow::Yes, + TokenTree::MetaVarDecl(_, _, frag) if frag.name == sym::block => + IsInFollow::Yes, _ => IsInFollow::No(tokens), } }, @@ -1089,16 +1092,18 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> IsInFollow { match *tok { TokenTree::Token(_, ref tok) => match *tok { Comma => IsInFollow::Yes, - Ident(i, is_raw) if is_raw || i.name != "priv" => IsInFollow::Yes, + Ident(i, is_raw) if is_raw || i.name != keywords::Priv.name() => + IsInFollow::Yes, ref tok => if tok.can_begin_type() { IsInFollow::Yes } else { IsInFollow::No(tokens) } }, - TokenTree::MetaVarDecl(_, _, frag) if frag.name == "ident" - || frag.name == "ty" - || frag.name == "path" => IsInFollow::Yes, + TokenTree::MetaVarDecl(_, _, frag) if frag.name == sym::ident + || frag.name == sym::ty + || frag.name == sym::path => + IsInFollow::Yes, _ => IsInFollow::No(tokens), } }, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 53ecb0762ab4..e7740f1835bc 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -22,13 +22,13 @@ use crate::source_map::Spanned; use crate::edition::{ALL_EDITIONS, Edition}; use crate::visit::{self, FnKind, Visitor}; use crate::parse::{token, ParseSess}; -use crate::symbol::Symbol; +use crate::symbol::{Symbol, keywords, sym}; use crate::tokenstream::TokenTree; use errors::{DiagnosticBuilder, Handler}; use rustc_data_structures::fx::FxHashMap; use rustc_target::spec::abi::Abi; -use syntax_pos::{Span, DUMMY_SP, sym}; +use syntax_pos::{Span, DUMMY_SP}; use log::debug; use lazy_static::lazy_static; @@ -562,9 +562,9 @@ declare_features! ( // Some features are known to be incomplete and using them is likely to have // unanticipated results, such as compiler crashes. We warn the user about these // to alert them. -const INCOMPLETE_FEATURES: &[&str] = &[ - "generic_associated_types", - "const_generics" +const INCOMPLETE_FEATURES: &[Symbol] = &[ + sym::generic_associated_types, + sym::const_generics ]; declare_features! ( @@ -1947,7 +1947,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_item(&mut self, i: &'a ast::Item) { match i.node { ast::ItemKind::Const(_,_) => { - if i.ident.name == "_" { + if i.ident.name == keywords::Underscore.name() { gate_feature_post!(&self, underscore_const_names, i.span, "naming constants with `_` is unstable"); } @@ -2304,7 +2304,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], if edition <= crate_edition { // The `crate_edition` implies its respective umbrella feature-gate // (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX). - edition_enabled_features.insert(Symbol::intern(edition.feature_name()), edition); + edition_enabled_features.insert(edition.feature_name(), edition); } } @@ -2335,7 +2335,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], } let name = mi.name_or_empty(); - if INCOMPLETE_FEATURES.iter().any(|f| name == *f) { + if INCOMPLETE_FEATURES.iter().any(|f| name == f.as_str()) { span_handler.struct_span_warn( mi.span(), &format!( @@ -2345,7 +2345,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], ).emit(); } - if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) { + if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name().as_str()) { if *edition <= crate_edition { continue; } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 64f3704e8083..655baafcd2d5 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -391,6 +391,8 @@ mod tests { #[test] fn string_to_tts_macro () { with_globals(|| { + use crate::symbol::sym; + let tts: Vec<_> = string_to_stream("macro_rules! zip (($a)=>($a))".to_string()).trees().collect(); let tts: &[TokenTree] = &tts[..]; @@ -403,8 +405,8 @@ mod tests { Some(&TokenTree::Token(_, token::Ident(name_zip, false))), Some(&TokenTree::Delimited(_, macro_delim, ref macro_tts)), ) - if name_macro_rules.name == "macro_rules" - && name_zip.name == "zip" => { + if name_macro_rules.name == sym::macro_rules + && name_zip.name.as_str() == "zip" => { let tts = ¯o_tts.trees().collect::>(); match (tts.len(), tts.get(0), tts.get(1), tts.get(2)) { ( @@ -421,7 +423,7 @@ mod tests { Some(&TokenTree::Token(_, token::Dollar)), Some(&TokenTree::Token(_, token::Ident(ident, false))), ) - if first_delim == token::Paren && ident.name == "a" => {}, + if first_delim == token::Paren && ident.name.as_str() == "a" => {}, _ => panic!("value 3: {:?} {:?}", first_delim, first_tts), } let tts = &second_tts.trees().collect::>(); @@ -431,7 +433,7 @@ mod tests { Some(&TokenTree::Token(_, token::Dollar)), Some(&TokenTree::Token(_, token::Ident(ident, false))), ) - if second_delim == token::Paren && ident.name == "a" => {}, + if second_delim == token::Paren && ident.name.as_str() == "a" => {}, _ => panic!("value 4: {:?} {:?}", second_delim, second_tts), } }, @@ -584,13 +586,13 @@ mod tests { let item = parse_item_from_source_str(name_1, source, &sess) .unwrap().unwrap(); let doc = first_attr_value_str_by_name(&item.attrs, sym::doc).unwrap(); - assert_eq!(doc, "/// doc comment"); + assert_eq!(doc.as_str(), "/// doc comment"); let name_2 = FileName::Custom("crlf_source_2".to_string()); let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string(); let item = parse_item_from_source_str(name_2, source, &sess) .unwrap().unwrap(); - let docs = item.attrs.iter().filter(|a| a.path == "doc") + let docs = item.attrs.iter().filter(|a| a.path == sym::doc) .map(|a| a.value_str().unwrap().to_string()).collect::>(); let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()]; assert_eq!(&docs[..], b); @@ -599,7 +601,7 @@ mod tests { let source = "/** doc comment\r\n * with CRLF */\r\nfn foo() {}".to_string(); let item = parse_item_from_source_str(name_3, source, &sess).unwrap().unwrap(); let doc = first_attr_value_str_by_name(&item.attrs, sym::doc).unwrap(); - assert_eq!(doc, "/** doc comment\n * with CRLF */"); + assert_eq!(doc.as_str(), "/** doc comment\n * with CRLF */"); }); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d3dd6bb1e01a..c0f3c358e98f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5099,7 +5099,7 @@ impl<'a> Parser<'a> { (ident, ast::MacroDef { tokens: tokens.into(), legacy: false }) } - token::Ident(ident, _) if ident.name == "macro_rules" && + token::Ident(ident, _) if ident.name == sym::macro_rules && self.look_ahead(1, |t| *t == token::Not) => { let prev_span = self.prev_span; self.complain_if_pub_macro(&vis.node, prev_span); diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 42ca8b7c23cb..f08fdcc6fb53 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -35,6 +35,9 @@ pub fn injected_crate_name() -> Option<&'static str> { } thread_local! { + // A `Symbol` might make more sense here, but it doesn't work, probably for + // reasons relating to the use of thread-local storage for the Symbol + // interner. static INJECTED_CRATE_NAME: Cell> = Cell::new(None); } diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 8e5e594ce9aa..21bc236d00e6 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -272,7 +272,8 @@ fn generate_test_harness(sess: &ParseSess, test_cases: Vec::new(), reexport_test_harness_main, // N.B., doesn't consider the value of `--crate-name` passed on the command line. - is_libtest: attr::find_crate_name(&krate.attrs).map(|s| s == "test").unwrap_or(false), + is_libtest: attr::find_crate_name(&krate.attrs) + .map(|s| s == sym::test).unwrap_or(false), toplevel_reexport: None, ctxt: SyntaxContext::empty().apply_mark(mark), features, diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs index 6213736ed5f4..b8e89c3ecf87 100644 --- a/src/libsyntax_ext/asm.rs +++ b/src/libsyntax_ext/asm.rs @@ -39,7 +39,7 @@ impl State { } } -const OPTIONS: &[&str] = &["volatile", "alignstack", "intel"]; +const OPTIONS: &[Symbol] = &[sym::volatile, sym::alignstack, sym::intel]; pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, @@ -233,13 +233,13 @@ fn parse_inline_asm<'a>( Options => { let (option, _) = p.parse_str()?; - if option == "volatile" { + if option == sym::volatile { // Indicates that the inline assembly has side effects // and must not be optimized out along with its outputs. volatile = true; - } else if option == "alignstack" { + } else if option == sym::alignstack { alignstack = true; - } else if option == "intel" { + } else if option == sym::intel { dialect = AsmDialect::Intel; } else { cx.span_warn(p.prev_span, "unrecognized option"); diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index fff54814a38c..c27de692d887 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -6,7 +6,7 @@ use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension, Resolver}; use syntax::ext::build::AstBuilder; use syntax::ext::hygiene::{Mark, SyntaxContext}; use syntax::ptr::P; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax_pos::Span; macro path_local($x:ident) { @@ -139,7 +139,7 @@ fn call_intrinsic(cx: &ExtCtxt<'_>, let intrinsic_allowed_via_allow_internal_unstable = cx .current_expansion.mark.expn_info().unwrap() .allow_internal_unstable.map_or(false, |features| features.iter().any(|&s| - s == "core_intrinsics" + s == sym::core_intrinsics )); if intrinsic_allowed_via_allow_internal_unstable { span = span.with_ctxt(cx.backtrace()); diff --git a/src/libsyntax_pos/edition.rs b/src/libsyntax_pos/edition.rs index a0b0052f26da..00cd00f28378 100644 --- a/src/libsyntax_pos/edition.rs +++ b/src/libsyntax_pos/edition.rs @@ -1,3 +1,4 @@ +use crate::symbol::{Symbol, sym}; use std::fmt; use std::str::FromStr; @@ -44,10 +45,10 @@ impl Edition { } } - pub fn feature_name(&self) -> &'static str { + pub fn feature_name(&self) -> Symbol { match *self { - Edition::Edition2015 => "rust_2015_preview", - Edition::Edition2018 => "rust_2018_preview", + Edition::Edition2015 => sym::rust_2015_preview, + Edition::Edition2018 => sym::rust_2018_preview, } } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index c5d6da74eb61..39859f25f97f 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -393,7 +393,7 @@ impl Span { Some(info) => info .allow_internal_unstable .map_or(false, |features| features.iter().any(|&f| - f == feature || f == "allow_internal_unstable_backcompat_hack" + f == feature || f == sym::allow_internal_unstable_backcompat_hack )), None => false, } diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index ac3f999c5379..ec0ce4253fa2 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -822,12 +822,6 @@ impl Decodable for Symbol { } } -impl> PartialEq for Symbol { - fn eq(&self, other: &T) -> bool { - self.as_str() == other.deref() - } -} - // The `&'static str`s in this type actually point into the arena. // // Note that normal symbols are indexed upward from 0, and gensyms are indexed diff --git a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs index 1d204e7bfcff..0deb1bf09150 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs @@ -20,7 +20,7 @@ declare_lint_pass!(Pass => [TEST_LINT]); impl EarlyLintPass for Pass { fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) { - if it.ident.name == "lintme" { + if it.ident.name.as_str() == "lintme" { cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'"); } } diff --git a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs index 182d2899da18..64664377cd94 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs @@ -23,10 +23,10 @@ declare_lint_pass!(Pass => [TEST_LINT, TEST_GROUP]); impl EarlyLintPass for Pass { fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) { - if it.ident.name == "lintme" { + if it.ident.name.as_str() == "lintme" { cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'"); } - if it.ident.name == "lintmetoo" { + if it.ident.name.as_str() == "lintmetoo" { cx.span_lint(TEST_GROUP, it.span, "item is named 'lintmetoo'"); } } From ea9fac5687c24abad493caf4ec5042af47458af9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 May 2019 14:33:06 +1000 Subject: [PATCH 119/239] Return a `Symbol` from `name_or_empty` functions. --- src/librustc/hir/check_attr.rs | 18 ++--- src/librustc/lint/levels.rs | 2 +- src/librustc/lint/mod.rs | 15 ++++- src/librustc/middle/lib_features.rs | 6 +- src/librustc/middle/stability.rs | 2 +- src/librustc_lint/unused.rs | 2 +- src/librustc_metadata/creader.rs | 3 +- src/librustc_passes/layout_test.rs | 10 +-- src/librustc_plugin/load.rs | 10 +-- src/librustdoc/core.rs | 10 +-- src/librustdoc/html/render.rs | 34 +++++----- src/libsyntax/attr/builtin.rs | 81 +++++++++++------------ src/libsyntax/attr/mod.rs | 14 ++-- src/libsyntax/feature_gate.rs | 6 +- src/libsyntax_ext/deriving/generic/mod.rs | 4 +- 15 files changed, 112 insertions(+), 105 deletions(-) diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 23c8a671ec5b..b199eee6dad8 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -178,9 +178,9 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { let mut is_transparent = false; for hint in &hints { - let (article, allowed_targets) = match hint.name_or_empty().get() { - name @ "C" | name @ "align" => { - is_c |= name == "C"; + let (article, allowed_targets) = match hint.name_or_empty() { + name @ sym::C | name @ sym::align => { + is_c |= name == sym::C; if target != Target::Struct && target != Target::Union && target != Target::Enum { @@ -189,7 +189,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { continue } } - "packed" => { + sym::packed => { if target != Target::Struct && target != Target::Union { ("a", "struct or union") @@ -197,7 +197,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { continue } } - "simd" => { + sym::simd => { is_simd = true; if target != Target::Struct { ("a", "struct") @@ -205,7 +205,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { continue } } - "transparent" => { + sym::transparent => { is_transparent = true; if target != Target::Struct { ("a", "struct") @@ -213,9 +213,9 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { continue } } - "i8" | "u8" | "i16" | "u16" | - "i32" | "u32" | "i64" | "u64" | - "isize" | "usize" => { + sym::i8 | sym::u8 | sym::i16 | sym::u16 | + sym::i32 | sym::u32 | sym::i64 | sym::u64 | + sym::isize | sym::usize => { int_reprs += 1; if target != Target::Enum { ("an", "enum") diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index 6481f9af00b8..9c926dff325b 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -194,7 +194,7 @@ impl<'a> LintLevelsBuilder<'a> { struct_span_err!(sess, span, E0452, "malformed lint attribute") }; for attr in attrs { - let level = match Level::from_str(&attr.name_or_empty()) { + let level = match Level::from_symbol(attr.name_or_empty()) { None => continue, Some(lvl) => lvl, }; diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 6613440ee7c9..68b65f9b4a1c 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -38,7 +38,7 @@ use syntax::ast; use syntax::source_map::{MultiSpan, ExpnFormat}; use syntax::early_buffered_lints::BufferedEarlyLintId; use syntax::edition::Edition; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, sym}; use syntax_pos::Span; pub use crate::lint::context::{LateContext, EarlyContext, LintContext, LintStore, @@ -570,6 +570,17 @@ impl Level { _ => None, } } + + /// Converts a symbol to a level. + pub fn from_symbol(x: Symbol) -> Option { + match x { + sym::allow => Some(Allow), + sym::warn => Some(Warn), + sym::deny => Some(Deny), + sym::forbid => Some(Forbid), + _ => None, + } + } } /// How a lint level was set. @@ -752,7 +763,7 @@ pub fn struct_lint_level<'a>(sess: &'a Session, pub fn maybe_lint_level_root(tcx: TyCtxt<'_, '_, '_>, id: hir::HirId) -> bool { let attrs = tcx.hir().attrs_by_hir_id(id); - attrs.iter().any(|attr| Level::from_str(&attr.name_or_empty()).is_some()) + attrs.iter().any(|attr| Level::from_symbol(attr.name_or_empty()).is_some()) } fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum) diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs index 8696e2af8c2b..76934ddd69b1 100644 --- a/src/librustc/middle/lib_features.rs +++ b/src/librustc/middle/lib_features.rs @@ -65,9 +65,9 @@ impl<'a, 'tcx> LibFeatureCollector<'a, 'tcx> { for meta in metas { if let Some(mi) = meta.meta_item() { // Find the `feature = ".."` meta-item. - match (mi.name_or_empty().get(), mi.value_str()) { - ("feature", val) => feature = val, - ("since", val) => since = val, + match (mi.name_or_empty(), mi.value_str()) { + (sym::feature, val) => feature = val, + (sym::since, val) => since = val, _ => {} } } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index d9a44714d7d0..abcf164cda6d 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -195,7 +195,7 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> { // Emit errors for non-staged-api crates. for attr in attrs { let name = attr.name_or_empty(); - if ["unstable", "stable", "rustc_deprecated"].contains(&name.get()) { + if [sym::unstable, sym::stable, sym::rustc_deprecated].contains(&name) { attr::mark_used(attr); self.tcx.sess.span_err(attr.span, "stability attributes may not be used \ outside of the standard library"); diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 93af7a1cd8f2..c3dfd44ad857 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -262,7 +262,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes { // Has a plugin registered this attribute as one that must be used at // the crate level? let plugin_crate = plugin_attributes.iter() - .find(|&&(ref x, t)| name == x.as_str() && AttributeType::CrateLevel == t) + .find(|&&(x, t)| name == x && AttributeType::CrateLevel == t) .is_some(); if known_crate || plugin_crate { let msg = match attr.style { diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index b7b17a84aa76..7f2a1c0b4b1d 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -650,9 +650,8 @@ impl<'a> CrateLoader<'a> { /// SVH and DefIndex of the registrar function. pub fn find_plugin_registrar(&mut self, span: Span, - name: &str) + name: Symbol) -> Option<(PathBuf, CrateDisambiguator)> { - let name = Symbol::intern(name); let ekrate = self.read_extension_crate(span, name, name); if ekrate.target_only { diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs index c865845b5e36..dea5774aa6eb 100644 --- a/src/librustc_passes/layout_test.rs +++ b/src/librustc_passes/layout_test.rs @@ -55,26 +55,26 @@ impl<'a, 'tcx> VarianceTest<'a, 'tcx> { // The `..` are the names of fields to dump. let meta_items = attr.meta_item_list().unwrap_or_default(); for meta_item in meta_items { - match meta_item.name_or_empty().get() { - "abi" => { + match meta_item.name_or_empty() { + sym::abi => { self.tcx .sess .span_err(item.span, &format!("abi: {:?}", ty_layout.abi)); } - "align" => { + sym::align => { self.tcx .sess .span_err(item.span, &format!("align: {:?}", ty_layout.align)); } - "size" => { + sym::size => { self.tcx .sess .span_err(item.span, &format!("size: {:?}", ty_layout.size)); } - "homogeneous_aggregate" => { + sym::homogeneous_aggregate => { self.tcx.sess.span_err( item.span, &format!( diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs index 43eddbb653fe..680bdcc4bbe9 100644 --- a/src/librustc_plugin/load.rs +++ b/src/librustc_plugin/load.rs @@ -11,7 +11,7 @@ use std::mem; use std::path::PathBuf; use syntax::ast; use syntax::span_err; -use syntax::symbol::sym; +use syntax::symbol::{Symbol, keywords, sym}; use syntax_pos::{Span, DUMMY_SP}; /// Pointer to a registrar function. @@ -58,9 +58,9 @@ pub fn load_plugins(sess: &Session, for plugin in plugins { // plugins must have a name and can't be key = value let name = plugin.name_or_empty(); - if !name.is_empty() && !plugin.is_value_str() { + if name != keywords::Invalid.name() && !plugin.is_value_str() { let args = plugin.meta_item_list().map(ToOwned::to_owned); - loader.load_plugin(plugin.span(), &name, args.unwrap_or_default()); + loader.load_plugin(plugin.span(), name, args.unwrap_or_default()); } else { call_malformed_plugin_attribute(sess, attr.span); } @@ -70,7 +70,7 @@ pub fn load_plugins(sess: &Session, if let Some(plugins) = addl_plugins { for plugin in plugins { - loader.load_plugin(DUMMY_SP, &plugin, vec![]); + loader.load_plugin(DUMMY_SP, Symbol::intern(&plugin), vec![]); } } @@ -86,7 +86,7 @@ impl<'a> PluginLoader<'a> { } } - fn load_plugin(&mut self, span: Span, name: &str, args: Vec) { + fn load_plugin(&mut self, span: Span, name: Symbol, args: Vec) { let registrar = self.reader.find_plugin_registrar(span, name); if let Some((lib, disambiguator)) = registrar { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index bc87086e1061..428f4f328b90 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -421,19 +421,19 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt let name = attr.name_or_empty(); if attr.is_word() { - if name == "no_default_passes" { + if name == sym::no_default_passes { report_deprecated_attr("no_default_passes", diag); if default_passes == passes::DefaultPassOption::Default { default_passes = passes::DefaultPassOption::None; } } } else if let Some(value) = attr.value_str() { - let sink = match name.get() { - "passes" => { + let sink = match name { + sym::passes => { report_deprecated_attr("passes = \"...\"", diag); &mut manual_passes }, - "plugins" => { + sym::plugins => { report_deprecated_attr("plugins = \"...\"", diag); eprintln!("WARNING: #![doc(plugins = \"...\")] no longer functions; \ see CVE-2018-1000622"); @@ -446,7 +446,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt } } - if attr.is_word() && name == "document_private_items" { + if attr.is_word() && name == sym::document_private_items { if default_passes == passes::DefaultPassOption::Default { default_passes = passes::DefaultPassOption::Private; } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index cbaa911eccca..0207fcda9e88 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -50,7 +50,7 @@ use syntax::ast; use syntax::ext::base::MacroKind; use syntax::source_map::FileName; use syntax::feature_gate::UnstableFeatures; -use syntax::symbol::sym; +use syntax::symbol::{Symbol, sym}; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId}; use rustc::middle::privacy::AccessLevels; use rustc::middle::stability; @@ -573,23 +573,23 @@ pub fn run(mut krate: clean::Crate, // going to emit HTML if let Some(attrs) = krate.module.as_ref().map(|m| &m.attrs) { for attr in attrs.lists(sym::doc) { - match (attr.name_or_empty().get(), attr.value_str()) { - ("html_favicon_url", Some(s)) => { + match (attr.name_or_empty(), attr.value_str()) { + (sym::html_favicon_url, Some(s)) => { scx.layout.favicon = s.to_string(); } - ("html_logo_url", Some(s)) => { + (sym::html_logo_url, Some(s)) => { scx.layout.logo = s.to_string(); } - ("html_playground_url", Some(s)) => { + (sym::html_playground_url, Some(s)) => { markdown::PLAYGROUND.with(|slot| { let name = krate.name.clone(); *slot.borrow_mut() = Some((Some(name), s.to_string())); }); } - ("issue_tracker_base_url", Some(s)) => { + (sym::issue_tracker_base_url, Some(s)) => { scx.issue_tracker_base_url = Some(s.to_string()); } - ("html_no_source", None) if attr.is_word() => { + (sym::html_no_source, None) if attr.is_word() => { scx.include_sources = false; } _ => {} @@ -3762,22 +3762,22 @@ fn render_attribute(attr: &ast::MetaItem) -> Option { } } -const ATTRIBUTE_WHITELIST: &'static [&'static str] = &[ - "export_name", - "lang", - "link_section", - "must_use", - "no_mangle", - "repr", - "unsafe_destructor_blind_to_params", - "non_exhaustive" +const ATTRIBUTE_WHITELIST: &'static [Symbol] = &[ + sym::export_name, + sym::lang, + sym::link_section, + sym::must_use, + sym::no_mangle, + sym::repr, + sym::unsafe_destructor_blind_to_params, + sym::non_exhaustive ]; fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item) -> fmt::Result { let mut attrs = String::new(); for attr in &it.attrs.other_attrs { - if !ATTRIBUTE_WHITELIST.contains(&attr.name_or_empty().get()) { + if !ATTRIBUTE_WHITELIST.contains(&attr.name_or_empty()) { continue; } if let Some(s) = render_attribute(&attr.meta().unwrap()) { diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 43de3f74e4a2..65ca96afab12 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -229,10 +229,9 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, )+ for meta in metas { if let Some(mi) = meta.meta_item() { - match mi.name_or_empty().get() { + match mi.name_or_empty() { $( - stringify!($name) - => if !get(mi, &mut $name) { continue 'outer }, + sym::$name => if !get(mi, &mut $name) { continue 'outer }, )+ _ => { let expected = &[ $( stringify!($name) ),+ ]; @@ -259,8 +258,8 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, } } - match meta.name_or_empty().get() { - "rustc_deprecated" => { + match meta.name_or_empty() { + sym::rustc_deprecated => { if rustc_depr.is_some() { span_err!(diagnostic, item_sp, E0540, "multiple rustc_deprecated attributes"); @@ -287,7 +286,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, } } } - "rustc_const_unstable" => { + sym::rustc_const_unstable => { if rustc_const_unstable.is_some() { span_err!(diagnostic, item_sp, E0553, "multiple rustc_const_unstable attributes"); @@ -302,7 +301,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, continue } } - "unstable" => { + sym::unstable => { if stab.is_some() { handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels); break @@ -313,10 +312,10 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, let mut issue = None; for meta in metas { if let Some(mi) = meta.meta_item() { - match mi.name_or_empty().get() { - "feature" => if !get(mi, &mut feature) { continue 'outer }, - "reason" => if !get(mi, &mut reason) { continue 'outer }, - "issue" => if !get(mi, &mut issue) { continue 'outer }, + match mi.name_or_empty() { + sym::feature => if !get(mi, &mut feature) { continue 'outer }, + sym::reason => if !get(mi, &mut reason) { continue 'outer }, + sym::issue => if !get(mi, &mut issue) { continue 'outer }, _ => { handle_errors( sess, @@ -374,7 +373,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, } } } - "stable" => { + sym::stable => { if stab.is_some() { handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels); break @@ -385,11 +384,9 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, for meta in metas { match meta { NestedMetaItem::MetaItem(mi) => { - match mi.name_or_empty().get() { - "feature" => - if !get(mi, &mut feature) { continue 'outer }, - "since" => - if !get(mi, &mut since) { continue 'outer }, + match mi.name_or_empty() { + sym::feature => if !get(mi, &mut feature) { continue 'outer }, + sym::since => if !get(mi, &mut since) { continue 'outer }, _ => { handle_errors( sess, @@ -542,14 +539,14 @@ pub fn eval_condition(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F) // The unwraps below may look dangerous, but we've already asserted // that they won't fail with the loop above. - match cfg.name_or_empty().get() { - "any" => mis.iter().any(|mi| { + match cfg.name_or_empty() { + sym::any => mis.iter().any(|mi| { eval_condition(mi.meta_item().unwrap(), sess, eval) }), - "all" => mis.iter().all(|mi| { + sym::all => mis.iter().all(|mi| { eval_condition(mi.meta_item().unwrap(), sess, eval) }), - "not" => { + sym::not => { if mis.len() != 1 { span_err!(sess.span_diagnostic, cfg.span, E0536, "expected 1 cfg-pattern"); return false; @@ -645,9 +642,9 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess, for meta in list { match meta { NestedMetaItem::MetaItem(mi) => { - match mi.name_or_empty().get() { - "since" => if !get(mi, &mut since) { continue 'outer }, - "note" => if !get(mi, &mut note) { continue 'outer }, + match mi.name_or_empty() { + sym::since => if !get(mi, &mut since) { continue 'outer }, + sym::note => if !get(mi, &mut note) { continue 'outer }, _ => { handle_errors( sess, @@ -739,11 +736,11 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec { let mut recognised = false; if item.is_word() { - let hint = match item.name_or_empty().get() { - "C" => Some(ReprC), - "packed" => Some(ReprPacked(1)), - "simd" => Some(ReprSimd), - "transparent" => Some(ReprTransparent), + let hint = match item.name_or_empty() { + sym::C => Some(ReprC), + sym::packed => Some(ReprPacked(1)), + sym::simd => Some(ReprSimd), + sym::transparent => Some(ReprTransparent), name => int_type_of_word(name).map(ReprInt), }; @@ -830,22 +827,22 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec { acc } -fn int_type_of_word(s: &str) -> Option { +fn int_type_of_word(s: Symbol) -> Option { use IntType::*; match s { - "i8" => Some(SignedInt(ast::IntTy::I8)), - "u8" => Some(UnsignedInt(ast::UintTy::U8)), - "i16" => Some(SignedInt(ast::IntTy::I16)), - "u16" => Some(UnsignedInt(ast::UintTy::U16)), - "i32" => Some(SignedInt(ast::IntTy::I32)), - "u32" => Some(UnsignedInt(ast::UintTy::U32)), - "i64" => Some(SignedInt(ast::IntTy::I64)), - "u64" => Some(UnsignedInt(ast::UintTy::U64)), - "i128" => Some(SignedInt(ast::IntTy::I128)), - "u128" => Some(UnsignedInt(ast::UintTy::U128)), - "isize" => Some(SignedInt(ast::IntTy::Isize)), - "usize" => Some(UnsignedInt(ast::UintTy::Usize)), + sym::i8 => Some(SignedInt(ast::IntTy::I8)), + sym::u8 => Some(UnsignedInt(ast::UintTy::U8)), + sym::i16 => Some(SignedInt(ast::IntTy::I16)), + sym::u16 => Some(UnsignedInt(ast::UintTy::U16)), + sym::i32 => Some(SignedInt(ast::IntTy::I32)), + sym::u32 => Some(UnsignedInt(ast::UintTy::U32)), + sym::i64 => Some(SignedInt(ast::IntTy::I64)), + sym::u64 => Some(UnsignedInt(ast::UintTy::U64)), + sym::i128 => Some(SignedInt(ast::IntTy::I128)), + sym::u128 => Some(UnsignedInt(ast::UintTy::U128)), + sym::isize => Some(SignedInt(ast::IntTy::Isize)), + sym::usize => Some(UnsignedInt(ast::UintTy::Usize)), _ => None } } diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index c0defa1c6e01..d94a3165b0f1 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -22,7 +22,7 @@ use crate::parse::parser::Parser; use crate::parse::{self, ParseSess, PResult}; use crate::parse::token::{self, Token}; use crate::ptr::P; -use crate::symbol::{keywords, LocalInternedString, Symbol}; +use crate::symbol::{keywords, Symbol}; use crate::ThinVec; use crate::tokenstream::{TokenStream, TokenTree, DelimSpan}; use crate::GLOBALS; @@ -89,8 +89,8 @@ impl NestedMetaItem { pub fn ident(&self) -> Option { self.meta_item().and_then(|meta_item| meta_item.ident()) } - pub fn name_or_empty(&self) -> LocalInternedString { - self.ident().unwrap_or(keywords::Invalid.ident()).name.as_str() + pub fn name_or_empty(&self) -> Symbol { + self.ident().unwrap_or(keywords::Invalid.ident()).name } /// Gets the string value if self is a MetaItem and the MetaItem is a @@ -167,8 +167,8 @@ impl Attribute { None } } - pub fn name_or_empty(&self) -> LocalInternedString { - self.ident().unwrap_or(keywords::Invalid.ident()).name.as_str() + pub fn name_or_empty(&self) -> Symbol { + self.ident().unwrap_or(keywords::Invalid.ident()).name } pub fn value_str(&self) -> Option { @@ -205,8 +205,8 @@ impl MetaItem { None } } - pub fn name_or_empty(&self) -> LocalInternedString { - self.ident().unwrap_or(keywords::Invalid.ident()).name.as_str() + pub fn name_or_empty(&self) -> Symbol { + self.ident().unwrap_or(keywords::Invalid.ident()).name } // #[attribute(name = "value")] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e7740f1835bc..a49926158de1 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1605,7 +1605,7 @@ impl<'a> Context<'a> { } } if !attr::is_known(attr) { - if attr.name_or_empty().starts_with("rustc_") { + if attr.name_or_empty().as_str().starts_with("rustc_") { let msg = "unless otherwise specified, attributes with the prefix `rustc_` \ are reserved for internal compiler diagnostics"; gate_feature!(self, rustc_attrs, attr.span, msg); @@ -2335,7 +2335,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], } let name = mi.name_or_empty(); - if INCOMPLETE_FEATURES.iter().any(|f| name == f.as_str()) { + if INCOMPLETE_FEATURES.iter().any(|f| name == *f) { span_handler.struct_span_warn( mi.span(), &format!( @@ -2345,7 +2345,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], ).emit(); } - if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name().as_str()) { + if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) { if *edition <= crate_edition { continue; } diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 228862c830fd..a13dc07085f8 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -464,8 +464,8 @@ impl<'a> TraitDef<'a> { attrs.extend(item.attrs .iter() .filter(|a| { - ["allow", "warn", "deny", "forbid", "stable", "unstable"] - .contains(&a.name_or_empty().get()) + [sym::allow, sym::warn, sym::deny, sym::forbid, sym::stable, sym::unstable] + .contains(&a.name_or_empty()) }) .cloned()); push(Annotatable::Item(P(ast::Item { attrs: attrs, ..(*newitem).clone() }))) From cc314b066a2f1d688ec2f5dec1fa5cb01ca1ebb0 Mon Sep 17 00:00:00 2001 From: Marcel Hellwig Date: Mon, 13 May 2019 09:13:07 +0200 Subject: [PATCH 120/239] Remove bitrig support from rust --- src/bootstrap/bootstrap.py | 1 - src/build_helper/lib.rs | 2 +- src/librustc_data_structures/flock.rs | 1 - src/librustc_target/spec/bitrig_base.rs | 16 -- src/librustc_target/spec/mod.rs | 3 - .../spec/x86_64_unknown_bitrig.rs | 23 --- src/librustdoc/clean/cfg.rs | 1 - src/libstd/build.rs | 3 +- src/libstd/env.rs | 1 - src/libstd/net/addr.rs | 4 +- src/libstd/net/tcp.rs | 4 +- src/libstd/net/udp.rs | 4 +- src/libstd/os/bitrig/fs.rs | 138 ------------------ src/libstd/os/bitrig/mod.rs | 6 - src/libstd/os/bitrig/raw.rs | 71 --------- src/libstd/os/mod.rs | 1 - src/libstd/sys/unix/args.rs | 1 - src/libstd/sys/unix/env.rs | 11 -- src/libstd/sys/unix/ext/net.rs | 4 +- src/libstd/sys/unix/fs.rs | 10 +- src/libstd/sys/unix/mod.rs | 1 - src/libstd/sys/unix/os.rs | 5 +- src/libstd/sys/unix/stack_overflow.rs | 3 - src/libstd/sys/unix/thread.rs | 9 +- src/libstd/sys_common/net.rs | 4 +- src/libtest/lib.rs | 1 - src/libunwind/build.rs | 2 - src/test/codegen/dllimports/main.rs | 1 - src/test/codegen/panic-abort-windows.rs | 1 - .../run-make-fulldeps/issue-14500/Makefile | 4 - src/test/run-make-fulldeps/tools.mk | 5 - .../use-extern-for-plugins/Makefile | 1 - src/test/run-pass/backtrace-debuginfo.rs | 1 - src/test/run-pass/dupe-first-attr.rc | 3 - .../parallel-codegen-closures.rs | 1 - .../intrinsics/intrinsic-alignment.rs | 12 -- src/test/run-pass/sepcomp/sepcomp-cci.rs | 1 - src/test/run-pass/sepcomp/sepcomp-extern.rs | 1 - .../run-pass/sepcomp/sepcomp-fns-backwards.rs | 1 - src/test/run-pass/sepcomp/sepcomp-fns.rs | 1 - src/test/run-pass/sepcomp/sepcomp-statics.rs | 1 - src/test/run-pass/sepcomp/sepcomp-unwind.rs | 1 - .../run-pass/structs-enums/rec-align-u64.rs | 9 -- src/test/run-pass/tcp-stress.rs | 1 - src/test/run-pass/x86stdcall.rs | 1 - src/tools/compiletest/src/runtest.rs | 7 +- src/tools/compiletest/src/util.rs | 1 - 47 files changed, 21 insertions(+), 363 deletions(-) delete mode 100644 src/librustc_target/spec/bitrig_base.rs delete mode 100644 src/librustc_target/spec/x86_64_unknown_bitrig.rs delete mode 100644 src/libstd/os/bitrig/fs.rs delete mode 100644 src/libstd/os/bitrig/mod.rs delete mode 100644 src/libstd/os/bitrig/raw.rs diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 86c82adffa9b..1c2b882f6659 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -177,7 +177,6 @@ def default_build_triple(): # The goal here is to come up with the same triple as LLVM would, # at least for the subset of platforms we're willing to target. ostype_mapper = { - 'Bitrig': 'unknown-bitrig', 'Darwin': 'apple-darwin', 'DragonFly': 'unknown-dragonfly', 'FreeBSD': 'unknown-freebsd', diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index bd99dc118e66..60911d917899 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -113,7 +113,7 @@ pub fn gnu_target(target: &str) -> &str { } pub fn make(host: &str) -> PathBuf { - if host.contains("bitrig") || host.contains("dragonfly") || host.contains("freebsd") + if host.contains("dragonfly") || host.contains("freebsd") || host.contains("netbsd") || host.contains("openbsd") { PathBuf::from("gmake") diff --git a/src/librustc_data_structures/flock.rs b/src/librustc_data_structures/flock.rs index 255c5fd7fe7e..b63701dbc096 100644 --- a/src/librustc_data_structures/flock.rs +++ b/src/librustc_data_structures/flock.rs @@ -44,7 +44,6 @@ cfg_if! { } #[cfg(any(target_os = "dragonfly", - target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"))] mod os { diff --git a/src/librustc_target/spec/bitrig_base.rs b/src/librustc_target/spec/bitrig_base.rs deleted file mode 100644 index 9b34119fc00c..000000000000 --- a/src/librustc_target/spec/bitrig_base.rs +++ /dev/null @@ -1,16 +0,0 @@ -use crate::spec::{TargetOptions, RelroLevel}; -use std::default::Default; - -pub fn opts() -> TargetOptions { - TargetOptions { - dynamic_linking: true, - executables: true, - target_family: Some("unix".to_string()), - linker_is_gnu: true, - has_rpath: true, - position_independent_executables: true, - relro_level: RelroLevel::Full, - - .. Default::default() - } -} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index b30a4fe76a2d..844edbb946a5 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -47,7 +47,6 @@ mod android_base; mod apple_base; mod apple_ios_base; mod arm_base; -mod bitrig_base; mod cloudabi_base; mod dragonfly_base; mod freebsd_base; @@ -390,8 +389,6 @@ supported_targets! { ("i686-unknown-dragonfly", i686_unknown_dragonfly), ("x86_64-unknown-dragonfly", x86_64_unknown_dragonfly), - ("x86_64-unknown-bitrig", x86_64_unknown_bitrig), - ("aarch64-unknown-openbsd", aarch64_unknown_openbsd), ("i686-unknown-openbsd", i686_unknown_openbsd), ("x86_64-unknown-openbsd", x86_64_unknown_openbsd), diff --git a/src/librustc_target/spec/x86_64_unknown_bitrig.rs b/src/librustc_target/spec/x86_64_unknown_bitrig.rs deleted file mode 100644 index 999d93a7e609..000000000000 --- a/src/librustc_target/spec/x86_64_unknown_bitrig.rs +++ /dev/null @@ -1,23 +0,0 @@ -use crate::spec::{LinkerFlavor, Target, TargetResult}; - -pub fn target() -> TargetResult { - let mut base = super::bitrig_base::opts(); - base.cpu = "x86-64".to_string(); - base.max_atomic_width = Some(64); - base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]); - base.stack_probes = true; - - Ok(Target { - llvm_target: "x86_64-unknown-bitrig".to_string(), - target_endian: "little".to_string(), - target_pointer_width: "64".to_string(), - target_c_int_width: "32".to_string(), - data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), - arch: "x86_64".to_string(), - target_os: "bitrig".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, - options: base, - }) -} diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index c795b2dcd7a4..61399e0568cb 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -338,7 +338,6 @@ impl<'a> fmt::Display for Html<'a> { ("debug_assertions", None) => "debug-assertions enabled", ("target_os", Some(os)) => match &*os.as_str() { "android" => "Android", - "bitrig" => "Bitrig", "dragonfly" => "DragonFly BSD", "emscripten" => "Emscripten", "freebsd" => "FreeBSD", diff --git a/src/libstd/build.rs b/src/libstd/build.rs index 726c27321538..7a6c97ebaa22 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -20,8 +20,7 @@ fn main() { } else if target.contains("netbsd") { println!("cargo:rustc-link-lib=pthread"); println!("cargo:rustc-link-lib=rt"); - } else if target.contains("dragonfly") || target.contains("bitrig") || - target.contains("openbsd") { + } else if target.contains("dragonfly") || target.contains("openbsd") { println!("cargo:rustc-link-lib=pthread"); } else if target.contains("solaris") { println!("cargo:rustc-link-lib=socket"); diff --git a/src/libstd/env.rs b/src/libstd/env.rs index c0d0c23e4696..9058ea93d6de 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -845,7 +845,6 @@ pub mod consts { /// - ios /// - freebsd /// - dragonfly - /// - bitrig /// - netbsd /// - openbsd /// - solaris diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index ec54d8a042a3..e7923e381f14 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -974,9 +974,9 @@ mod tests { // s has been moved into the tsa call } - // FIXME: figure out why this fails on openbsd and bitrig and fix it + // FIXME: figure out why this fails on openbsd and fix it #[test] - #[cfg(not(any(windows, target_os = "openbsd", target_os = "bitrig")))] + #[cfg(not(any(windows, target_os = "openbsd")))] fn to_socket_addr_str_bad() { assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err()); } diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 0460ac9d7535..cdffa390223a 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -1595,9 +1595,9 @@ mod tests { assert_eq!(format!("{:?}", stream), compare); } - // FIXME: re-enabled bitrig/openbsd tests once their socket timeout code + // FIXME: re-enabled openbsd tests once their socket timeout code // no longer has rounding errors. - #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"), ignore)] + #[cfg_attr(any(target_os = "netbsd", target_os = "openbsd"), ignore)] #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 #[test] fn timeouts() { diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index d4187d2932b1..61d9149952ee 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -1024,9 +1024,9 @@ mod tests { assert_eq!(format!("{:?}", udpsock), compare); } - // FIXME: re-enabled bitrig/openbsd/netbsd tests once their socket timeout code + // FIXME: re-enabled openbsd/netbsd tests once their socket timeout code // no longer has rounding errors. - #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"), ignore)] + #[cfg_attr(any(target_os = "netbsd", target_os = "openbsd"), ignore)] #[test] fn timeouts() { let addr = next_test_ip4(); diff --git a/src/libstd/os/bitrig/fs.rs b/src/libstd/os/bitrig/fs.rs deleted file mode 100644 index b5c6903c4104..000000000000 --- a/src/libstd/os/bitrig/fs.rs +++ /dev/null @@ -1,138 +0,0 @@ -#![stable(feature = "metadata_ext", since = "1.1.0")] - -use crate::fs::Metadata; -use crate::sys_common::AsInner; - -#[allow(deprecated)] -use crate::os::bitrig::raw; - -/// OS-specific extensions to [`fs::Metadata`]. -/// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html -#[stable(feature = "metadata_ext", since = "1.1.0")] -pub trait MetadataExt { - /// Gain a reference to the underlying `stat` structure which contains - /// the raw information returned by the OS. - /// - /// The contents of the returned `stat` are **not** consistent across - /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the - /// cross-Unix abstractions contained within the raw stat. - #[stable(feature = "metadata_ext", since = "1.1.0")] - #[rustc_deprecated(since = "1.8.0", - reason = "deprecated in favor of the accessor \ - methods of this trait")] - #[allow(deprecated)] - fn as_raw_stat(&self) -> &raw::stat; - - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_dev(&self) -> u64; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_ino(&self) -> u64; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_mode(&self) -> u32; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_nlink(&self) -> u64; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_uid(&self) -> u32; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_gid(&self) -> u32; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_rdev(&self) -> u64; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_size(&self) -> u64; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_atime(&self) -> i64; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_atime_nsec(&self) -> i64; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_mtime(&self) -> i64; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_mtime_nsec(&self) -> i64; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_ctime(&self) -> i64; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_ctime_nsec(&self) -> i64; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_birthtime(&self) -> i64; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_birthtime_nsec(&self) -> i64; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_blksize(&self) -> u64; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_blocks(&self) -> u64; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_flags(&self) -> u32; - #[stable(feature = "metadata_ext2", since = "1.8.0")] - fn st_gen(&self) -> u32; -} - -#[stable(feature = "metadata_ext", since = "1.1.0")] -impl MetadataExt for Metadata { - #[allow(deprecated)] - fn as_raw_stat(&self) -> &raw::stat { - unsafe { - &*(self.as_inner().as_inner() as *const libc::stat - as *const raw::stat) - } - } - fn st_dev(&self) -> u64 { - self.as_inner().as_inner().st_dev as u64 - } - fn st_ino(&self) -> u64 { - self.as_inner().as_inner().st_ino as u64 - } - fn st_mode(&self) -> u32 { - self.as_inner().as_inner().st_mode as u32 - } - fn st_nlink(&self) -> u64 { - self.as_inner().as_inner().st_nlink as u64 - } - fn st_uid(&self) -> u32 { - self.as_inner().as_inner().st_uid as u32 - } - fn st_gid(&self) -> u32 { - self.as_inner().as_inner().st_gid as u32 - } - fn st_rdev(&self) -> u64 { - self.as_inner().as_inner().st_rdev as u64 - } - fn st_size(&self) -> u64 { - self.as_inner().as_inner().st_size as u64 - } - fn st_atime(&self) -> i64 { - self.as_inner().as_inner().st_atime as i64 - } - fn st_atime_nsec(&self) -> i64 { - self.as_inner().as_inner().st_atime_nsec as i64 - } - fn st_mtime(&self) -> i64 { - self.as_inner().as_inner().st_mtime as i64 - } - fn st_mtime_nsec(&self) -> i64 { - self.as_inner().as_inner().st_mtime_nsec as i64 - } - fn st_ctime(&self) -> i64 { - self.as_inner().as_inner().st_ctime as i64 - } - fn st_ctime_nsec(&self) -> i64 { - self.as_inner().as_inner().st_ctime_nsec as i64 - } - fn st_birthtime(&self) -> i64 { - self.as_inner().as_inner().st_birthtime as i64 - } - fn st_birthtime_nsec(&self) -> i64 { - self.as_inner().as_inner().st_birthtime_nsec as i64 - } - fn st_blksize(&self) -> u64 { - self.as_inner().as_inner().st_blksize as u64 - } - fn st_blocks(&self) -> u64 { - self.as_inner().as_inner().st_blocks as u64 - } - fn st_gen(&self) -> u32 { - self.as_inner().as_inner().st_gen as u32 - } - fn st_flags(&self) -> u32 { - self.as_inner().as_inner().st_flags as u32 - } -} diff --git a/src/libstd/os/bitrig/mod.rs b/src/libstd/os/bitrig/mod.rs deleted file mode 100644 index 0bc105bb2b40..000000000000 --- a/src/libstd/os/bitrig/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -//! Bitrig-specific definitions - -#![stable(feature = "raw_ext", since = "1.1.0")] - -pub mod raw; -pub mod fs; diff --git a/src/libstd/os/bitrig/raw.rs b/src/libstd/os/bitrig/raw.rs deleted file mode 100644 index c966d5a8e5b4..000000000000 --- a/src/libstd/os/bitrig/raw.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! Bitrig-specific raw type definitions - -#![stable(feature = "raw_ext", since = "1.1.0")] -#![rustc_deprecated(since = "1.8.0", - reason = "these type aliases are no longer supported by \ - the standard library, the `libc` crate on \ - crates.io should be used instead for the correct \ - definitions")] -#![allow(deprecated)] - -use crate::os::raw::c_long; -use crate::os::unix::raw::{uid_t, gid_t}; - -#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; -#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; -#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64; -#[stable(feature = "raw_ext", since = "1.1.0")] pub type fflags_t = u32; -#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; -#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; -#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; -#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; -#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; - -#[stable(feature = "pthread_t", since = "1.8.0")] -pub type pthread_t = usize; - -#[repr(C)] -#[derive(Clone)] -#[stable(feature = "raw_ext", since = "1.1.0")] -pub struct stat { - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mode: u32, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_dev: i32, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ino: u64, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_nlink: u32, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_uid: u32, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_gid: u32, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_rdev: i32, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_atime: i64, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_atime_nsec: i64, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mtime: u64, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mtime_nsec: i64, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ctime: i64, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ctime_nsec: i64, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_size: i64, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_blocks: i64, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_blksize: u32, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_flags: u32, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_gen: u32, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_birthtime: i64, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_birthtime_nsec: i64, -} diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs index 7b56d6d62cf2..44cbc180b8b0 100644 --- a/src/libstd/os/mod.rs +++ b/src/libstd/os/mod.rs @@ -39,7 +39,6 @@ cfg_if! { } #[cfg(target_os = "android")] pub mod android; -#[cfg(target_os = "bitrig")] pub mod bitrig; #[cfg(target_os = "dragonfly")] pub mod dragonfly; #[cfg(target_os = "freebsd")] pub mod freebsd; #[cfg(target_os = "haiku")] pub mod haiku; diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs index 18de1096df2a..3b4de56f2c9b 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -49,7 +49,6 @@ impl DoubleEndedIterator for Args { target_os = "android", target_os = "freebsd", target_os = "dragonfly", - target_os = "bitrig", target_os = "netbsd", target_os = "openbsd", target_os = "solaris", diff --git a/src/libstd/sys/unix/env.rs b/src/libstd/sys/unix/env.rs index f9592d5c45f9..891013406a16 100644 --- a/src/libstd/sys/unix/env.rs +++ b/src/libstd/sys/unix/env.rs @@ -53,17 +53,6 @@ pub mod os { pub const EXE_EXTENSION: &str = ""; } -#[cfg(target_os = "bitrig")] -pub mod os { - pub const FAMILY: &str = "unix"; - pub const OS: &str = "bitrig"; - pub const DLL_PREFIX: &str = "lib"; - pub const DLL_SUFFIX: &str = ".so"; - pub const DLL_EXTENSION: &str = "so"; - pub const EXE_SUFFIX: &str = ""; - pub const EXE_EXTENSION: &str = ""; -} - #[cfg(target_os = "netbsd")] pub mod os { pub const FAMILY: &str = "unix"; diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs index 45a850aa4a85..3ccb0a1b1abc 100644 --- a/src/libstd/sys/unix/ext/net.rs +++ b/src/libstd/sys/unix/ext/net.rs @@ -32,12 +32,12 @@ use crate::sys_common::{self, AsInner, FromInner, IntoInner}; #[cfg(any(target_os = "linux", target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", - target_os = "haiku", target_os = "bitrig"))] + target_os = "haiku"))] use libc::MSG_NOSIGNAL; #[cfg(not(any(target_os = "linux", target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", - target_os = "haiku", target_os = "bitrig")))] + target_os = "haiku")))] const MSG_NOSIGNAL: libc::c_int = 0x0; fn sun_path_offset() -> usize { diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 22c05a72a91c..cc1f0790d433 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -147,8 +147,7 @@ impl FileAttr { })) } - #[cfg(any(target_os = "bitrig", - target_os = "freebsd", + #[cfg(any(target_os = "freebsd", target_os = "openbsd", target_os = "macos", target_os = "ios"))] @@ -159,8 +158,7 @@ impl FileAttr { })) } - #[cfg(not(any(target_os = "bitrig", - target_os = "freebsd", + #[cfg(not(any(target_os = "freebsd", target_os = "openbsd", target_os = "macos", target_os = "ios")))] @@ -355,7 +353,6 @@ impl DirEntry { #[cfg(any(target_os = "freebsd", target_os = "openbsd", - target_os = "bitrig", target_os = "netbsd", target_os = "dragonfly"))] pub fn ino(&self) -> u64 { @@ -367,8 +364,7 @@ impl DirEntry { target_os = "netbsd", target_os = "openbsd", target_os = "freebsd", - target_os = "dragonfly", - target_os = "bitrig"))] + target_os = "dragonfly"))] fn name_bytes(&self) -> &[u8] { use crate::slice; unsafe { diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 90e26449ae28..c2b264ff8de1 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -5,7 +5,6 @@ use crate::io::ErrorKind; #[cfg(any(rustdoc, target_os = "linux"))] pub use crate::os::linux as platform; #[cfg(all(not(rustdoc), target_os = "android"))] pub use crate::os::android as platform; -#[cfg(all(not(rustdoc), target_os = "bitrig"))] pub use crate::os::bitrig as platform; #[cfg(all(not(rustdoc), target_os = "dragonfly"))] pub use crate::os::dragonfly as platform; #[cfg(all(not(rustdoc), target_os = "freebsd"))] pub use crate::os::freebsd as platform; #[cfg(all(not(rustdoc), target_os = "haiku"))] pub use crate::os::haiku as platform; diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 726b17969b7c..dad19eabf7db 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -33,8 +33,7 @@ extern { target_os = "fuchsia", target_os = "l4re"), link_name = "__errno_location")] - #[cfg_attr(any(target_os = "bitrig", - target_os = "netbsd", + #[cfg_attr(any(target_os = "netbsd", target_os = "openbsd", target_os = "android", target_os = "hermit", @@ -257,7 +256,7 @@ pub fn current_exe() -> io::Result { sysctl().or_else(|_| procfs()) } -#[cfg(any(target_os = "bitrig", target_os = "openbsd"))] +#[cfg(target_os = "openbsd")] pub fn current_exe() -> io::Result { unsafe { let mut mib = [libc::CTL_KERN, diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs index 561279e82785..fe1095fa0c2f 100644 --- a/src/libstd/sys/unix/stack_overflow.rs +++ b/src/libstd/sys/unix/stack_overflow.rs @@ -25,7 +25,6 @@ impl Drop for Handler { #[cfg(any(target_os = "linux", target_os = "macos", - target_os = "bitrig", target_os = "dragonfly", target_os = "freebsd", target_os = "solaris", @@ -139,7 +138,6 @@ mod imp { #[cfg(any(target_os = "linux", target_os = "macos", - target_os = "bitrig", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd", @@ -185,7 +183,6 @@ mod imp { #[cfg(not(any(target_os = "linux", target_os = "macos", - target_os = "bitrig", target_os = "dragonfly", target_os = "freebsd", target_os = "solaris", diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index f7d604ac4c8c..f4a1783ce890 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -99,7 +99,6 @@ impl Thread { #[cfg(any(target_os = "freebsd", target_os = "dragonfly", - target_os = "bitrig", target_os = "openbsd"))] pub fn set_name(name: &CStr) { unsafe { @@ -189,7 +188,6 @@ impl Drop for Thread { #[cfg(all(not(all(target_os = "linux", not(target_env = "musl"))), not(target_os = "freebsd"), not(target_os = "macos"), - not(target_os = "bitrig"), not(all(target_os = "netbsd", not(target_vendor = "rumprun"))), not(target_os = "openbsd"), not(target_os = "solaris")))] @@ -205,7 +203,6 @@ pub mod guard { #[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "freebsd", target_os = "macos", - target_os = "bitrig", all(target_os = "netbsd", not(target_vendor = "rumprun")), target_os = "openbsd", target_os = "solaris"))] @@ -236,16 +233,15 @@ pub mod guard { Some(stackaddr as *mut libc::c_void) } - #[cfg(any(target_os = "openbsd", target_os = "bitrig"))] + #[cfg(target_os = "openbsd")] unsafe fn get_stack_start() -> Option<*mut libc::c_void> { let mut current_stack: libc::stack_t = crate::mem::zeroed(); assert_eq!(libc::pthread_stackseg_np(libc::pthread_self(), &mut current_stack), 0); - let extra = if cfg!(target_os = "bitrig") {3} else {1} * PAGE_SIZE; let stackaddr = if libc::pthread_main_np() == 1 { // main thread - current_stack.ss_sp as usize - current_stack.ss_size + extra + current_stack.ss_sp as usize - current_stack.ss_size + PAGE_SIZE } else { // new thread current_stack.ss_sp as usize - current_stack.ss_size @@ -343,7 +339,6 @@ pub mod guard { } #[cfg(any(target_os = "macos", - target_os = "bitrig", target_os = "openbsd", target_os = "solaris"))] pub unsafe fn current() -> Option { diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index cf1dc20b52fc..391f670346f2 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -37,12 +37,12 @@ use crate::sys::net::netc::IPV6_DROP_MEMBERSHIP; #[cfg(any(target_os = "linux", target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", - target_os = "haiku", target_os = "bitrig"))] + target_os = "haiku"))] use libc::MSG_NOSIGNAL; #[cfg(not(any(target_os = "linux", target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", - target_os = "haiku", target_os = "bitrig")))] + target_os = "haiku")))] const MSG_NOSIGNAL: c_int = 0x0; //////////////////////////////////////////////////////////////////////////////// diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 26612964c308..c6afa90e4ee6 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -1289,7 +1289,6 @@ fn get_concurrency() -> usize { #[cfg(any( target_os = "freebsd", target_os = "dragonfly", - target_os = "bitrig", target_os = "netbsd" ))] fn num_cpus() -> usize { diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs index f3fda9eaa75f..70f591e653ba 100644 --- a/src/libunwind/build.rs +++ b/src/libunwind/build.rs @@ -26,8 +26,6 @@ fn main() { println!("cargo:rustc-link-lib=c++abi"); } else if target.contains("solaris") { println!("cargo:rustc-link-lib=gcc_s"); - } else if target.contains("bitrig") { - println!("cargo:rustc-link-lib=c++abi"); } else if target.contains("dragonfly") { println!("cargo:rustc-link-lib=gcc_pic"); } else if target.contains("windows-gnu") { diff --git a/src/test/codegen/dllimports/main.rs b/src/test/codegen/dllimports/main.rs index 40bbd2821eff..52543297ead6 100644 --- a/src/test/codegen/dllimports/main.rs +++ b/src/test/codegen/dllimports/main.rs @@ -1,6 +1,5 @@ // This test is for *-windows-msvc only. // ignore-android -// ignore-bitrig // ignore-cloudabi // ignore-dragonfly // ignore-emscripten diff --git a/src/test/codegen/panic-abort-windows.rs b/src/test/codegen/panic-abort-windows.rs index bbe0d81de3d4..f2fd297dc70f 100644 --- a/src/test/codegen/panic-abort-windows.rs +++ b/src/test/codegen/panic-abort-windows.rs @@ -1,6 +1,5 @@ // This test is for *-windows-msvc only. // ignore-android -// ignore-bitrig // ignore-cloudabi // ignore-dragonfly // ignore-emscripten diff --git a/src/test/run-make-fulldeps/issue-14500/Makefile b/src/test/run-make-fulldeps/issue-14500/Makefile index bd94db095202..0c0e331da1d5 100644 --- a/src/test/run-make-fulldeps/issue-14500/Makefile +++ b/src/test/run-make-fulldeps/issue-14500/Makefile @@ -6,10 +6,6 @@ # is compiled with LTO, it shouldn't strip the symbol from `foo`, and that's the # only way that `foo.c` will successfully compile. -ifeq ($(UNAME),Bitrig) - EXTRACFLAGS := -lc $(EXTRACFLAGS) $(EXTRACXXFLAGS) -endif - all: $(RUSTC) foo.rs --crate-type=rlib $(RUSTC) bar.rs --crate-type=staticlib -C lto -L. -o $(TMPDIR)/libbar.a diff --git a/src/test/run-make-fulldeps/tools.mk b/src/test/run-make-fulldeps/tools.mk index 4b9ab0b7c23d..3b4df73cdfd6 100644 --- a/src/test/run-make-fulldeps/tools.mk +++ b/src/test/run-make-fulldeps/tools.mk @@ -88,10 +88,6 @@ else ifeq ($(UNAME),FreeBSD) EXTRACFLAGS := -lm -lpthread -lgcc_s else -ifeq ($(UNAME),Bitrig) - EXTRACFLAGS := -lm -lpthread - EXTRACXXFLAGS := -lc++ -lc++abi -else ifeq ($(UNAME),SunOS) EXTRACFLAGS := -lm -lpthread -lposix4 -lsocket -lresolv else @@ -106,7 +102,6 @@ endif endif endif endif -endif REMOVE_DYLIBS = rm $(TMPDIR)/$(call DYLIB_GLOB,$(1)) REMOVE_RLIBS = rm $(TMPDIR)/$(call RLIB_GLOB,$(1)) diff --git a/src/test/run-make-fulldeps/use-extern-for-plugins/Makefile b/src/test/run-make-fulldeps/use-extern-for-plugins/Makefile index 3976da311319..838b1a2719b9 100644 --- a/src/test/run-make-fulldeps/use-extern-for-plugins/Makefile +++ b/src/test/run-make-fulldeps/use-extern-for-plugins/Makefile @@ -2,7 +2,6 @@ # ignore-freebsd # ignore-openbsd -# ignore-bitrig # ignore-sunos HOST := $(shell $(RUSTC) -vV | grep 'host:' | sed 's/host: //') diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs index 7f038ddecc1f..279a30d6c2ee 100644 --- a/src/test/run-pass/backtrace-debuginfo.rs +++ b/src/test/run-pass/backtrace-debuginfo.rs @@ -32,7 +32,6 @@ macro_rules! dump_and_die { all(target_os = "linux", target_arch = "arm"), target_os = "freebsd", target_os = "dragonfly", - target_os = "bitrig", target_os = "openbsd")) { // skip these platforms as this support isn't implemented yet. } else { diff --git a/src/test/run-pass/dupe-first-attr.rc b/src/test/run-pass/dupe-first-attr.rc index cb6a82a15da1..8b7025b7be7d 100644 --- a/src/test/run-pass/dupe-first-attr.rc +++ b/src/test/run-pass/dupe-first-attr.rc @@ -18,9 +18,6 @@ mod hello; #[cfg(target_os = "dragonfly")] mod hello; -#[cfg(target_os = "bitrig")] -mod hello; - #[cfg(target_os = "android")] mod hello; diff --git a/src/test/run-pass/functions-closures/parallel-codegen-closures.rs b/src/test/run-pass/functions-closures/parallel-codegen-closures.rs index 921fbaf4942c..79759daba501 100644 --- a/src/test/run-pass/functions-closures/parallel-codegen-closures.rs +++ b/src/test/run-pass/functions-closures/parallel-codegen-closures.rs @@ -6,7 +6,6 @@ // Tests parallel codegen - this can fail if the symbol for the anonymous // closure in `sum` pollutes the second codegen unit from the first. -// ignore-bitrig // compile-flags: -C codegen_units=2 #![feature(iter_arith)] diff --git a/src/test/run-pass/intrinsics/intrinsic-alignment.rs b/src/test/run-pass/intrinsics/intrinsic-alignment.rs index 19e567106205..ac9fb94c3750 100644 --- a/src/test/run-pass/intrinsics/intrinsic-alignment.rs +++ b/src/test/run-pass/intrinsics/intrinsic-alignment.rs @@ -40,18 +40,6 @@ mod m { } } -#[cfg(target_os = "bitrig")] -mod m { - #[main] - #[cfg(target_arch = "x86_64")] - pub fn main() { - unsafe { - assert_eq!(::rusti::pref_align_of::(), 8); - assert_eq!(::rusti::min_align_of::(), 8); - } - } -} - #[cfg(target_os = "windows")] mod m { #[main] diff --git a/src/test/run-pass/sepcomp/sepcomp-cci.rs b/src/test/run-pass/sepcomp/sepcomp-cci.rs index f5c633d250b9..02bbab30e9c6 100644 --- a/src/test/run-pass/sepcomp/sepcomp-cci.rs +++ b/src/test/run-pass/sepcomp/sepcomp-cci.rs @@ -1,5 +1,4 @@ // run-pass -// ignore-bitrig // compile-flags: -C codegen-units=3 // aux-build:sepcomp_cci_lib.rs diff --git a/src/test/run-pass/sepcomp/sepcomp-extern.rs b/src/test/run-pass/sepcomp/sepcomp-extern.rs index 18af785c1bea..c4ccf23c47ab 100644 --- a/src/test/run-pass/sepcomp/sepcomp-extern.rs +++ b/src/test/run-pass/sepcomp/sepcomp-extern.rs @@ -1,5 +1,4 @@ // run-pass -// ignore-bitrig // compile-flags: -C codegen-units=3 // aux-build:sepcomp-extern-lib.rs diff --git a/src/test/run-pass/sepcomp/sepcomp-fns-backwards.rs b/src/test/run-pass/sepcomp/sepcomp-fns-backwards.rs index 96bcc260bdf5..f56769e2b8c6 100644 --- a/src/test/run-pass/sepcomp/sepcomp-fns-backwards.rs +++ b/src/test/run-pass/sepcomp/sepcomp-fns-backwards.rs @@ -1,6 +1,5 @@ // run-pass #![allow(dead_code)] -// ignore-bitrig // compile-flags: -C codegen-units=3 // Test references to items that haven't been codegened yet. diff --git a/src/test/run-pass/sepcomp/sepcomp-fns.rs b/src/test/run-pass/sepcomp/sepcomp-fns.rs index c4ea17225b44..a432c89606e3 100644 --- a/src/test/run-pass/sepcomp/sepcomp-fns.rs +++ b/src/test/run-pass/sepcomp/sepcomp-fns.rs @@ -1,5 +1,4 @@ // run-pass -// ignore-bitrig // compile-flags: -C codegen-units=3 // Test basic separate compilation functionality. The functions should be able diff --git a/src/test/run-pass/sepcomp/sepcomp-statics.rs b/src/test/run-pass/sepcomp/sepcomp-statics.rs index e0c6b268b177..5457c8a0ae97 100644 --- a/src/test/run-pass/sepcomp/sepcomp-statics.rs +++ b/src/test/run-pass/sepcomp/sepcomp-statics.rs @@ -1,6 +1,5 @@ // run-pass #![allow(dead_code)] -// ignore-bitrig // compile-flags: -C codegen-units=3 // Test references to static items across compilation units. diff --git a/src/test/run-pass/sepcomp/sepcomp-unwind.rs b/src/test/run-pass/sepcomp/sepcomp-unwind.rs index 01dbea08098b..50a4e043943f 100644 --- a/src/test/run-pass/sepcomp/sepcomp-unwind.rs +++ b/src/test/run-pass/sepcomp/sepcomp-unwind.rs @@ -1,6 +1,5 @@ // run-pass #![allow(dead_code)] -// ignore-bitrig // compile-flags: -C codegen-units=3 // ignore-emscripten no threads support diff --git a/src/test/run-pass/structs-enums/rec-align-u64.rs b/src/test/run-pass/structs-enums/rec-align-u64.rs index d211eed131e5..07e601140189 100644 --- a/src/test/run-pass/structs-enums/rec-align-u64.rs +++ b/src/test/run-pass/structs-enums/rec-align-u64.rs @@ -55,15 +55,6 @@ mod m { } } -#[cfg(target_os = "bitrig")] -mod m { - #[cfg(target_arch = "x86_64")] - pub mod m { - pub fn align() -> usize { 8 } - pub fn size() -> usize { 16 } - } -} - #[cfg(target_os = "windows")] mod m { #[cfg(target_arch = "x86")] diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs index c90f9024af14..d4476ab0a310 100644 --- a/src/test/run-pass/tcp-stress.rs +++ b/src/test/run-pass/tcp-stress.rs @@ -1,5 +1,4 @@ // ignore-android needs extra network permissions -// ignore-bitrig system ulimit (Too many open files) // ignore-cloudabi no global network namespace access // ignore-emscripten no threads or sockets support // ignore-netbsd system ulimit (Too many open files) diff --git a/src/test/run-pass/x86stdcall.rs b/src/test/run-pass/x86stdcall.rs index 11a45a58895d..1b6ffc4c2bfd 100644 --- a/src/test/run-pass/x86stdcall.rs +++ b/src/test/run-pass/x86stdcall.rs @@ -23,7 +23,6 @@ pub fn main() { } #[cfg(any(target_os = "android", - target_os = "bitrig", target_os = "cloudabi", target_os = "dragonfly", target_os = "emscripten", diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 10b8133326bb..b335fe3ae185 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2217,9 +2217,7 @@ impl<'test> TestCx<'test> { fn charset() -> &'static str { // FreeBSD 10.1 defaults to GDB 6.1.1 which doesn't support "auto" charset - if cfg!(target_os = "bitrig") { - "auto" - } else if cfg!(target_os = "freebsd") { + if cfg!(target_os = "freebsd") { "ISO-8859-1" } else { "UTF-8" @@ -2670,8 +2668,7 @@ impl<'test> TestCx<'test> { create_dir_all(&tmpdir).unwrap(); let host = &self.config.host; - let make = if host.contains("bitrig") - || host.contains("dragonfly") + let make = if host.contains("dragonfly") || host.contains("freebsd") || host.contains("netbsd") || host.contains("openbsd") diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index adc1224bcd36..8caf5ca00f50 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -9,7 +9,6 @@ use log::*; const OS_TABLE: &'static [(&'static str, &'static str)] = &[ ("android", "android"), ("androideabi", "android"), - ("bitrig", "bitrig"), ("cloudabi", "cloudabi"), ("cuda", "cuda"), ("darwin", "macos"), From 4cf2379f6176b704bb8648107beee9c896d1b133 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 13 May 2019 11:34:11 +0200 Subject: [PATCH 121/239] Revert "use SecRandomCopyBytes on macOS in Miri" This reverts commit 54aefc6a2d076b74921a8d78c5d8c68c13bfa4a7. --- src/libstd/sys/unix/rand.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs index e923b9aa29b0..77f1439e17b1 100644 --- a/src/libstd/sys/unix/rand.rs +++ b/src/libstd/sys/unix/rand.rs @@ -13,7 +13,6 @@ pub fn hashmap_random_keys() -> (u64, u64) { #[cfg(all(unix, not(target_os = "ios"), - not(all(target_os = "macos", miri)), not(target_os = "openbsd"), not(target_os = "freebsd"), not(target_os = "fuchsia")))] @@ -107,9 +106,7 @@ mod imp { // once per thread in `hashmap_random_keys`. Therefore `SecRandomCopyBytes` is // only used on iOS where direct access to `/dev/urandom` is blocked by the // sandbox. -// HACK: However, we do use this when running in Miri on macOS; intercepting this is much -// easier than intercepting accesses to /dev/urandom. -#[cfg(any(target_os = "ios", all(target_os = "macos", miri)))] +#[cfg(target_os = "ios")] mod imp { use crate::io; use crate::ptr; From decd6d366018823a8b1116b346bc778eb010accd Mon Sep 17 00:00:00 2001 From: Felix S Klock II Date: Mon, 13 May 2019 13:29:49 +0200 Subject: [PATCH 122/239] modify comment modify the comment on `in_cycle` to reflect changes requested by ariel and myself. --- src/librustc/traits/select.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 3c4d48b17b9f..b333f4b96514 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -173,10 +173,15 @@ struct TraitObligationStack<'prev, 'tcx: 'prev> { /// well as the second instance of `A: AutoTrait`) to supress /// caching. /// - /// This is a simple, targeted fix. The correct fix requires + /// This is a simple, targeted fix. A more-performant fix requires /// deeper changes, but would permit more caching: we could /// basically defer caching until we have fully evaluated the - /// tree, and then cache the entire tree at once. + /// tree, and then cache the entire tree at once. In any case, the + /// performance impact here shouldn't be so horrible: every time + /// this is hit, we do cache at least one trait, so we only + /// evaluate each member of a cycle up to N times, where N is the + /// length of the cycle. This means the performance impact is + /// bounded and we shouldn't have any terrible worst-cases. in_cycle: Cell, previous: TraitObligationStackList<'prev, 'tcx>, From d29f0d23c3624047a3f3671a8e352783e8796373 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 12 May 2019 19:55:16 +0300 Subject: [PATCH 123/239] Move token tree related lexer state to a separate struct We only used a bunch of fields when tokenizing into a token tree, so let's move them out of the base lexer --- src/libsyntax/parse/lexer/mod.rs | 14 +--- src/libsyntax/parse/lexer/tokentrees.rs | 96 +++++++++++++++++-------- src/libsyntax/parse/mod.rs | 9 +-- 3 files changed, 71 insertions(+), 48 deletions(-) diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 2882acb0e780..60494a6a2bdc 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -66,15 +66,7 @@ pub struct StringReader<'a> { span: Span, /// The raw source span which *does not* take `override_span` into account span_src_raw: Span, - /// Stack of open delimiters and their spans. Used for error message. - open_braces: Vec<(token::DelimToken, Span)>, - crate unmatched_braces: Vec, - /// The type and spans for all braces - /// - /// Used only for error recovery when arriving to EOF with mismatched braces. - matching_delim_spans: Vec<(token::DelimToken, Span, Span)>, - crate override_span: Option, - last_unclosed_found_span: Option, + override_span: Option, } impl<'a> StringReader<'a> { @@ -254,11 +246,7 @@ impl<'a> StringReader<'a> { token: token::Eof, span: syntax_pos::DUMMY_SP, span_src_raw: syntax_pos::DUMMY_SP, - open_braces: Vec::new(), - unmatched_braces: Vec::new(), - matching_delim_spans: Vec::new(), override_span, - last_unclosed_found_span: None, } } diff --git a/src/libsyntax/parse/lexer/tokentrees.rs b/src/libsyntax/parse/lexer/tokentrees.rs index 0db36c84cdfe..a6e176c02a09 100644 --- a/src/libsyntax/parse/lexer/tokentrees.rs +++ b/src/libsyntax/parse/lexer/tokentrees.rs @@ -1,14 +1,42 @@ +use syntax_pos::Span; + use crate::print::pprust::token_to_string; use crate::parse::lexer::{StringReader, UnmatchedBrace}; use crate::parse::{token, PResult}; use crate::tokenstream::{DelimSpan, IsJoint::*, TokenStream, TokenTree, TreeAndJoint}; impl<'a> StringReader<'a> { + crate fn into_token_trees(self) -> (PResult<'a, TokenStream>, Vec) { + let mut tt_reader = TokenTreesReader { + string_reader: self, + open_braces: Vec::new(), + unmatched_braces: Vec::new(), + matching_delim_spans: Vec::new(), + last_unclosed_found_span: None, + }; + let res = tt_reader.parse_all_token_trees(); + (res, tt_reader.unmatched_braces) + } +} + +struct TokenTreesReader<'a> { + string_reader: StringReader<'a>, + /// Stack of open delimiters and their spans. Used for error message. + open_braces: Vec<(token::DelimToken, Span)>, + unmatched_braces: Vec, + /// The type and spans for all braces + /// + /// Used only for error recovery when arriving to EOF with mismatched braces. + matching_delim_spans: Vec<(token::DelimToken, Span, Span)>, + last_unclosed_found_span: Option, +} + +impl<'a> TokenTreesReader<'a> { // Parse a stream of tokens into a list of `TokenTree`s, up to an `Eof`. - crate fn parse_all_token_trees(&mut self) -> PResult<'a, TokenStream> { + fn parse_all_token_trees(&mut self) -> PResult<'a, TokenStream> { let mut tts = Vec::new(); - while self.token != token::Eof { + while self.string_reader.token != token::Eof { tts.push(self.parse_token_tree()?); } @@ -19,7 +47,7 @@ impl<'a> StringReader<'a> { fn parse_token_trees_until_close_delim(&mut self) -> TokenStream { let mut tts = vec![]; loop { - if let token::CloseDelim(..) = self.token { + if let token::CloseDelim(..) = self.string_reader.token { return TokenStream::new(tts); } @@ -34,11 +62,12 @@ impl<'a> StringReader<'a> { } fn parse_token_tree(&mut self) -> PResult<'a, TreeAndJoint> { - let sm = self.sess.source_map(); - match self.token { + let sm = self.string_reader.sess.source_map(); + match self.string_reader.token { token::Eof => { let msg = "this file contains an un-closed delimiter"; - let mut err = self.sess.span_diagnostic.struct_span_err(self.span, msg); + let mut err = self.string_reader.sess.span_diagnostic + .struct_span_err(self.span(), msg); for &(_, sp) in &self.open_braces { err.span_label(sp, "un-closed delimiter"); } @@ -46,13 +75,12 @@ impl<'a> StringReader<'a> { if let Some((delim, _)) = self.open_braces.last() { if let Some((_, open_sp, close_sp)) = self.matching_delim_spans.iter() .filter(|(d, open_sp, close_sp)| { - - if let Some(close_padding) = sm.span_to_margin(*close_sp) { - if let Some(open_padding) = sm.span_to_margin(*open_sp) { - return delim == d && close_padding != open_padding; + if let Some(close_padding) = sm.span_to_margin(*close_sp) { + if let Some(open_padding) = sm.span_to_margin(*open_sp) { + return delim == d && close_padding != open_padding; + } } - } - false + false }).next() // these are in reverse order as they get inserted on close, but { // we want the last open/first close err.span_label( @@ -69,11 +97,11 @@ impl<'a> StringReader<'a> { }, token::OpenDelim(delim) => { // The span for beginning of the delimited section - let pre_span = self.span; + let pre_span = self.span(); // Parse the open delimiter. - self.open_braces.push((delim, self.span)); - self.real_token(); + self.open_braces.push((delim, self.span())); + self.string_reader.real_token(); // Parse the token trees within the delimiters. // We stop at any delimiter so we can try to recover if the user @@ -81,9 +109,9 @@ impl<'a> StringReader<'a> { let tts = self.parse_token_trees_until_close_delim(); // Expand to cover the entire delimited token tree - let delim_span = DelimSpan::from_pair(pre_span, self.span); + let delim_span = DelimSpan::from_pair(pre_span, self.span()); - match self.token { + match self.string_reader.token { // Correct delimiter. token::CloseDelim(d) if d == delim => { let (open_brace, open_brace_span) = self.open_braces.pop().unwrap(); @@ -93,26 +121,26 @@ impl<'a> StringReader<'a> { self.matching_delim_spans.clear(); } else { self.matching_delim_spans.push( - (open_brace, open_brace_span, self.span), + (open_brace, open_brace_span, self.span()), ); } // Parse the close delimiter. - self.real_token(); + self.string_reader.real_token(); } // Incorrect delimiter. token::CloseDelim(other) => { let mut unclosed_delimiter = None; let mut candidate = None; - if self.last_unclosed_found_span != Some(self.span) { + if self.last_unclosed_found_span != Some(self.span()) { // do not complain about the same unclosed delimiter multiple times - self.last_unclosed_found_span = Some(self.span); + self.last_unclosed_found_span = Some(self.span()); // This is a conservative error: only report the last unclosed // delimiter. The previous unclosed delimiters could actually be // closed! The parser just hasn't gotten to them yet. if let Some(&(_, sp)) = self.open_braces.last() { unclosed_delimiter = Some(sp); }; - if let Some(current_padding) = sm.span_to_margin(self.span) { + if let Some(current_padding) = sm.span_to_margin(self.span()) { for (brace, brace_span) in &self.open_braces { if let Some(padding) = sm.span_to_margin(*brace_span) { // high likelihood of these two corresponding @@ -126,7 +154,7 @@ impl<'a> StringReader<'a> { self.unmatched_braces.push(UnmatchedBrace { expected_delim: tok, found_delim: other, - found_span: self.span, + found_span: self.span(), unclosed_span: unclosed_delimiter, candidate_span: candidate, }); @@ -142,7 +170,7 @@ impl<'a> StringReader<'a> { // bar(baz( // } // Incorrect delimiter but matches the earlier `{` if !self.open_braces.iter().any(|&(b, _)| b == other) { - self.real_token(); + self.string_reader.real_token(); } } token::Eof => { @@ -162,22 +190,28 @@ impl<'a> StringReader<'a> { token::CloseDelim(_) => { // An unexpected closing delimiter (i.e., there is no // matching opening delimiter). - let token_str = token_to_string(&self.token); + let token_str = token_to_string(&self.string_reader.token); let msg = format!("unexpected close delimiter: `{}`", token_str); - let mut err = self.sess.span_diagnostic.struct_span_err(self.span, &msg); - err.span_label(self.span, "unexpected close delimiter"); + let mut err = self.string_reader.sess.span_diagnostic + .struct_span_err(self.span(), &msg); + err.span_label(self.span(), "unexpected close delimiter"); Err(err) }, _ => { - let tt = TokenTree::Token(self.span, self.token.clone()); + let tt = TokenTree::Token(self.span(), self.string_reader.token.clone()); // Note that testing for joint-ness here is done via the raw // source span as the joint-ness is a property of the raw source // rather than wanting to take `override_span` into account. - let raw = self.span_src_raw; - self.real_token(); - let is_joint = raw.hi() == self.span_src_raw.lo() && token::is_op(&self.token); + let raw = self.string_reader.span_src_raw; + self.string_reader.real_token(); + let is_joint = raw.hi() == self.string_reader.span_src_raw.lo() + && token::is_op(&self.string_reader.token); Ok((tt, if is_joint { Joint } else { NonJoint })) } } } + + fn span(&self) -> Span { + self.string_reader.span + } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index be44b964ba5a..1ddafb969c4b 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -295,7 +295,7 @@ pub fn source_file_to_stream( } /// Given a source file, produces a sequence of token trees. Returns any buffered errors from -/// parsing the token tream. +/// parsing the token stream. pub fn maybe_file_to_stream( sess: &ParseSess, source_file: Lrc, @@ -303,14 +303,15 @@ pub fn maybe_file_to_stream( ) -> Result<(TokenStream, Vec), Vec> { let mut srdr = lexer::StringReader::new_or_buffered_errs(sess, source_file, override_span)?; srdr.real_token(); + let (token_trees, unmatched_braces) = srdr.into_token_trees(); - match srdr.parse_all_token_trees() { - Ok(stream) => Ok((stream, srdr.unmatched_braces)), + match token_trees { + Ok(stream) => Ok((stream, unmatched_braces)), Err(err) => { let mut buffer = Vec::with_capacity(1); err.buffer(&mut buffer); // Not using `emit_unclosed_delims` to use `db.buffer` - for unmatched in srdr.unmatched_braces { + for unmatched in unmatched_braces { let mut db = sess.span_diagnostic.struct_span_err(unmatched.found_span, &format!( "incorrect close delimiter: `{}`", token_to_string(&token::Token::CloseDelim(unmatched.found_delim)), From b91e0a378690871fa744768f38d42bd90830bcd0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 13 May 2019 12:06:37 +0300 Subject: [PATCH 124/239] move span and token to tt reader --- src/libsyntax/parse/lexer/mod.rs | 12 ----- src/libsyntax/parse/lexer/tokentrees.rs | 60 ++++++++++++++----------- src/libsyntax/parse/mod.rs | 3 +- 3 files changed, 35 insertions(+), 40 deletions(-) diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 60494a6a2bdc..9caa9ea807c1 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -62,10 +62,6 @@ pub struct StringReader<'a> { // cache a direct reference to the source text, so that we don't have to // retrieve it via `self.source_file.src.as_ref().unwrap()` all the time. src: Lrc, - token: token::Token, - span: Span, - /// The raw source span which *does not* take `override_span` into account - span_src_raw: Span, override_span: Option, } @@ -113,8 +109,6 @@ impl<'a> StringReader<'a> { sp: self.peek_span, }; self.advance_token()?; - self.span_src_raw = self.peek_span_src_raw; - Ok(ret_val) } @@ -151,9 +145,6 @@ impl<'a> StringReader<'a> { } } - self.token = t.tok.clone(); - self.span = t.sp; - Ok(t) } @@ -243,9 +234,6 @@ impl<'a> StringReader<'a> { peek_span_src_raw: syntax_pos::DUMMY_SP, src, fatal_errs: Vec::new(), - token: token::Eof, - span: syntax_pos::DUMMY_SP, - span_src_raw: syntax_pos::DUMMY_SP, override_span, } } diff --git a/src/libsyntax/parse/lexer/tokentrees.rs b/src/libsyntax/parse/lexer/tokentrees.rs index a6e176c02a09..1070d6dcb1b3 100644 --- a/src/libsyntax/parse/lexer/tokentrees.rs +++ b/src/libsyntax/parse/lexer/tokentrees.rs @@ -9,6 +9,8 @@ impl<'a> StringReader<'a> { crate fn into_token_trees(self) -> (PResult<'a, TokenStream>, Vec) { let mut tt_reader = TokenTreesReader { string_reader: self, + token: token::Eof, + span: syntax_pos::DUMMY_SP, open_braces: Vec::new(), unmatched_braces: Vec::new(), matching_delim_spans: Vec::new(), @@ -21,6 +23,8 @@ impl<'a> StringReader<'a> { struct TokenTreesReader<'a> { string_reader: StringReader<'a>, + token: token::Token, + span: Span, /// Stack of open delimiters and their spans. Used for error message. open_braces: Vec<(token::DelimToken, Span)>, unmatched_braces: Vec, @@ -36,7 +40,8 @@ impl<'a> TokenTreesReader<'a> { fn parse_all_token_trees(&mut self) -> PResult<'a, TokenStream> { let mut tts = Vec::new(); - while self.string_reader.token != token::Eof { + self.real_token(); + while self.token != token::Eof { tts.push(self.parse_token_tree()?); } @@ -47,7 +52,7 @@ impl<'a> TokenTreesReader<'a> { fn parse_token_trees_until_close_delim(&mut self) -> TokenStream { let mut tts = vec![]; loop { - if let token::CloseDelim(..) = self.string_reader.token { + if let token::CloseDelim(..) = self.token { return TokenStream::new(tts); } @@ -63,11 +68,11 @@ impl<'a> TokenTreesReader<'a> { fn parse_token_tree(&mut self) -> PResult<'a, TreeAndJoint> { let sm = self.string_reader.sess.source_map(); - match self.string_reader.token { + match self.token { token::Eof => { let msg = "this file contains an un-closed delimiter"; let mut err = self.string_reader.sess.span_diagnostic - .struct_span_err(self.span(), msg); + .struct_span_err(self.span, msg); for &(_, sp) in &self.open_braces { err.span_label(sp, "un-closed delimiter"); } @@ -97,11 +102,11 @@ impl<'a> TokenTreesReader<'a> { }, token::OpenDelim(delim) => { // The span for beginning of the delimited section - let pre_span = self.span(); + let pre_span = self.span; // Parse the open delimiter. - self.open_braces.push((delim, self.span())); - self.string_reader.real_token(); + self.open_braces.push((delim, self.span)); + self.real_token(); // Parse the token trees within the delimiters. // We stop at any delimiter so we can try to recover if the user @@ -109,9 +114,9 @@ impl<'a> TokenTreesReader<'a> { let tts = self.parse_token_trees_until_close_delim(); // Expand to cover the entire delimited token tree - let delim_span = DelimSpan::from_pair(pre_span, self.span()); + let delim_span = DelimSpan::from_pair(pre_span, self.span); - match self.string_reader.token { + match self.token { // Correct delimiter. token::CloseDelim(d) if d == delim => { let (open_brace, open_brace_span) = self.open_braces.pop().unwrap(); @@ -121,26 +126,26 @@ impl<'a> TokenTreesReader<'a> { self.matching_delim_spans.clear(); } else { self.matching_delim_spans.push( - (open_brace, open_brace_span, self.span()), + (open_brace, open_brace_span, self.span), ); } // Parse the close delimiter. - self.string_reader.real_token(); + self.real_token(); } // Incorrect delimiter. token::CloseDelim(other) => { let mut unclosed_delimiter = None; let mut candidate = None; - if self.last_unclosed_found_span != Some(self.span()) { + if self.last_unclosed_found_span != Some(self.span) { // do not complain about the same unclosed delimiter multiple times - self.last_unclosed_found_span = Some(self.span()); + self.last_unclosed_found_span = Some(self.span); // This is a conservative error: only report the last unclosed // delimiter. The previous unclosed delimiters could actually be // closed! The parser just hasn't gotten to them yet. if let Some(&(_, sp)) = self.open_braces.last() { unclosed_delimiter = Some(sp); }; - if let Some(current_padding) = sm.span_to_margin(self.span()) { + if let Some(current_padding) = sm.span_to_margin(self.span) { for (brace, brace_span) in &self.open_braces { if let Some(padding) = sm.span_to_margin(*brace_span) { // high likelihood of these two corresponding @@ -154,7 +159,7 @@ impl<'a> TokenTreesReader<'a> { self.unmatched_braces.push(UnmatchedBrace { expected_delim: tok, found_delim: other, - found_span: self.span(), + found_span: self.span, unclosed_span: unclosed_delimiter, candidate_span: candidate, }); @@ -170,7 +175,7 @@ impl<'a> TokenTreesReader<'a> { // bar(baz( // } // Incorrect delimiter but matches the earlier `{` if !self.open_braces.iter().any(|&(b, _)| b == other) { - self.string_reader.real_token(); + self.real_token(); } } token::Eof => { @@ -190,28 +195,31 @@ impl<'a> TokenTreesReader<'a> { token::CloseDelim(_) => { // An unexpected closing delimiter (i.e., there is no // matching opening delimiter). - let token_str = token_to_string(&self.string_reader.token); + let token_str = token_to_string(&self.token); let msg = format!("unexpected close delimiter: `{}`", token_str); let mut err = self.string_reader.sess.span_diagnostic - .struct_span_err(self.span(), &msg); - err.span_label(self.span(), "unexpected close delimiter"); + .struct_span_err(self.span, &msg); + err.span_label(self.span, "unexpected close delimiter"); Err(err) }, _ => { - let tt = TokenTree::Token(self.span(), self.string_reader.token.clone()); + let tt = TokenTree::Token(self.span, self.token.clone()); // Note that testing for joint-ness here is done via the raw // source span as the joint-ness is a property of the raw source // rather than wanting to take `override_span` into account. - let raw = self.string_reader.span_src_raw; - self.string_reader.real_token(); - let is_joint = raw.hi() == self.string_reader.span_src_raw.lo() - && token::is_op(&self.string_reader.token); + let raw = self.string_reader.peek_span_src_raw; + self.real_token(); + let is_joint = raw.hi() == self.string_reader.peek_span_src_raw.lo() + && token::is_op(&self.token); Ok((tt, if is_joint { Joint } else { NonJoint })) } } } - fn span(&self) -> Span { - self.string_reader.span + fn real_token(&mut self) { + let t = self.string_reader.real_token(); + self.token = t.tok; + self.span = t.sp; } } + diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 1ddafb969c4b..4a9a7aec6add 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -301,8 +301,7 @@ pub fn maybe_file_to_stream( source_file: Lrc, override_span: Option, ) -> Result<(TokenStream, Vec), Vec> { - let mut srdr = lexer::StringReader::new_or_buffered_errs(sess, source_file, override_span)?; - srdr.real_token(); + let srdr = lexer::StringReader::new_or_buffered_errs(sess, source_file, override_span)?; let (token_trees, unmatched_braces) = srdr.into_token_trees(); match token_trees { From e249f2e526cca687b78a766769c481cfb638f02e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 13 May 2019 14:30:18 +0300 Subject: [PATCH 125/239] move raw span to tt reader See https://github.com/rust-lang/rust/pull/50838/files#r283296243 for explanation how jointness checking works with *next* pair --- src/libsyntax/parse/lexer/tokentrees.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/parse/lexer/tokentrees.rs b/src/libsyntax/parse/lexer/tokentrees.rs index 1070d6dcb1b3..4bfc5bb16c0b 100644 --- a/src/libsyntax/parse/lexer/tokentrees.rs +++ b/src/libsyntax/parse/lexer/tokentrees.rs @@ -207,6 +207,8 @@ impl<'a> TokenTreesReader<'a> { // Note that testing for joint-ness here is done via the raw // source span as the joint-ness is a property of the raw source // rather than wanting to take `override_span` into account. + // Additionally, we actually check if the *next* pair of tokens + // is joint, but this is equivalent to checking the current pair. let raw = self.string_reader.peek_span_src_raw; self.real_token(); let is_joint = raw.hi() == self.string_reader.peek_span_src_raw.lo() @@ -222,4 +224,3 @@ impl<'a> TokenTreesReader<'a> { self.span = t.sp; } } - From c47e2ef8d49f0140086d187ee3528a50454be394 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 13 May 2019 08:14:02 -0700 Subject: [PATCH 126/239] Destabilize the `Error::type_id` function This commit destabilizes the `Error::type_id` function in the standard library. This does so by effectively reverting #58048, restoring the `#[unstable]` attribute. The security mailing list has recently been notified of a vulnerability relating to the stabilization of this function. First stabilized in Rust 1.34.0, a stable function here allows users to implement a custom return value for this function: struct MyType; impl Error for MyType { fn type_id(&self) -> TypeId { // Enable safe casting to `String` by accident. TypeId::of::() } } This, when combined with the `Error::downcast` family of functions, allows safely casting a type to any other type, clearly a memory safety issue! A security announcement will be shortly posted to the security mailing list as well as the Rust Blog, and when those links are available they'll be filled in for this PR as well. This commit simply destabilizes the `Error::type_id` which, although breaking for users since Rust 1.34.0, is hoped to have little impact and has been deemed sufficient to mitigate this issue for the stable channel. The long-term fate of the `Error::type_id` API will be discussed at #60784. --- src/libstd/error.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 081fff0562b1..7cb830e751a7 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -197,7 +197,10 @@ pub trait Error: Debug + Display { fn source(&self) -> Option<&(dyn Error + 'static)> { None } /// Gets the `TypeId` of `self` - #[stable(feature = "error_type_id", since = "1.34.0")] + #[doc(hidden)] + #[unstable(feature = "error_type_id", + reason = "this is memory unsafe to override in user code", + issue = "60784")] fn type_id(&self) -> TypeId where Self: 'static { TypeId::of::() } From 3db667a81944c14f0933522560822fc20809c63f Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 13 May 2019 17:30:14 +0200 Subject: [PATCH 127/239] add release notes for rust 1.34.2 --- RELEASES.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 3b4f4182702d..48bd13105bbe 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,11 @@ +Version 1.34.2 (2019-05-14) +=========================== + +* [Destabilize the `Error::type_id` function due to a security + vulnerability][60785] + +[60785]: https://github.com/rust-lang/rust/pull/60785 + Version 1.34.1 (2019-04-25) =========================== From ea956e3ae9e0089861934062544aa44588052e2a Mon Sep 17 00:00:00 2001 From: Pulkit Goyal <7895pulkit@gmail.com> Date: Mon, 13 May 2019 00:37:05 +0300 Subject: [PATCH 128/239] add impl_trait_in_bindings to INCOMPLETE_FEATURES impl_trait_in_bindings is not yet complete and can lead to compiler crashes. Fixes #60764. --- src/libsyntax/feature_gate.rs | 1 + src/test/run-pass/impl-trait-in-bindings.rs | 1 + src/test/run-pass/impl-trait-in-bindings.stderr | 6 ++++++ src/test/ui/impl-trait/bindings-opaque.rs | 1 + src/test/ui/impl-trait/bindings-opaque.stderr | 12 +++++++++--- src/test/ui/impl-trait/bindings.rs | 1 + src/test/ui/impl-trait/bindings.stderr | 14 ++++++++++---- 7 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 src/test/run-pass/impl-trait-in-bindings.stderr diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index a49926158de1..8a066f3f4a09 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -563,6 +563,7 @@ declare_features! ( // unanticipated results, such as compiler crashes. We warn the user about these // to alert them. const INCOMPLETE_FEATURES: &[Symbol] = &[ + sym::impl_trait_in_bindings, sym::generic_associated_types, sym::const_generics ]; diff --git a/src/test/run-pass/impl-trait-in-bindings.rs b/src/test/run-pass/impl-trait-in-bindings.rs index 9a1f53b48933..1e3a641b7cf9 100644 --- a/src/test/run-pass/impl-trait-in-bindings.rs +++ b/src/test/run-pass/impl-trait-in-bindings.rs @@ -1,4 +1,5 @@ #![feature(impl_trait_in_bindings)] +//~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash use std::fmt::Debug; diff --git a/src/test/run-pass/impl-trait-in-bindings.stderr b/src/test/run-pass/impl-trait-in-bindings.stderr new file mode 100644 index 000000000000..4896deb9d5c9 --- /dev/null +++ b/src/test/run-pass/impl-trait-in-bindings.stderr @@ -0,0 +1,6 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/impl-trait-in-bindings.rs:1:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/src/test/ui/impl-trait/bindings-opaque.rs b/src/test/ui/impl-trait/bindings-opaque.rs index 5f623321943a..d4eef29ed320 100644 --- a/src/test/ui/impl-trait/bindings-opaque.rs +++ b/src/test/ui/impl-trait/bindings-opaque.rs @@ -1,4 +1,5 @@ #![feature(impl_trait_in_bindings)] +//~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash const FOO: impl Copy = 42; diff --git a/src/test/ui/impl-trait/bindings-opaque.stderr b/src/test/ui/impl-trait/bindings-opaque.stderr index 8b2514c05014..d0a6a4ee578f 100644 --- a/src/test/ui/impl-trait/bindings-opaque.stderr +++ b/src/test/ui/impl-trait/bindings-opaque.stderr @@ -1,17 +1,23 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/bindings-opaque.rs:1:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope - --> $DIR/bindings-opaque.rs:10:17 + --> $DIR/bindings-opaque.rs:11:17 | LL | let _ = FOO.count_ones(); | ^^^^^^^^^^ error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope - --> $DIR/bindings-opaque.rs:12:17 + --> $DIR/bindings-opaque.rs:13:17 | LL | let _ = BAR.count_ones(); | ^^^^^^^^^^ error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope - --> $DIR/bindings-opaque.rs:14:17 + --> $DIR/bindings-opaque.rs:15:17 | LL | let _ = foo.count_ones(); | ^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/bindings.rs b/src/test/ui/impl-trait/bindings.rs index 91d092634a90..104a44d65662 100644 --- a/src/test/ui/impl-trait/bindings.rs +++ b/src/test/ui/impl-trait/bindings.rs @@ -1,4 +1,5 @@ #![feature(impl_trait_in_bindings)] +//~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash fn a(x: T) { const foo: impl Clone = x; diff --git a/src/test/ui/impl-trait/bindings.stderr b/src/test/ui/impl-trait/bindings.stderr index a5bf583afeaf..c66836ab8e5a 100644 --- a/src/test/ui/impl-trait/bindings.stderr +++ b/src/test/ui/impl-trait/bindings.stderr @@ -1,23 +1,29 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/bindings.rs:1:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/bindings.rs:4:29 + --> $DIR/bindings.rs:5:29 | LL | const foo: impl Clone = x; | ^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/bindings.rs:10:33 + --> $DIR/bindings.rs:11:33 | LL | const foo: impl Clone = x; | ^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/bindings.rs:17:33 + --> $DIR/bindings.rs:18:33 | LL | const foo: impl Clone = x; | ^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/bindings.rs:24:33 + --> $DIR/bindings.rs:25:33 | LL | const foo: impl Clone = x; | ^ non-constant value From 43207cada264796fe9307ded77e63751c1e0646a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 13 May 2019 11:39:30 +0200 Subject: [PATCH 129/239] update miri --- src/tools/miri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri b/src/tools/miri index 053aa694990a..bc0c76d861a1 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 053aa694990a212ad8942dd72101ede23597c0e9 +Subproject commit bc0c76d861a178911f3f506196a7404eda1e690d From 36fd00e81cd4af2c83839f0c0b96dc20663710c5 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Mon, 13 May 2019 21:57:20 +0100 Subject: [PATCH 130/239] Allow late bound regions in existential types --- src/librustc_typeck/check/writeback.rs | 7 +++-- .../issue-60655-latebound-regions.rs | 30 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/existential_types/issue-60655-latebound-regions.rs diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index ecb8e09ec246..13baf667808f 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -466,6 +466,8 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { let hir_id = self.tcx().hir().as_local_hir_id(def_id).unwrap(); let instantiated_ty = self.resolve(&opaque_defn.concrete_ty, &hir_id); + debug_assert!(!instantiated_ty.has_escaping_bound_vars()); + let generics = self.tcx().generics_of(def_id); let definition_ty = if generics.parent.is_some() { @@ -524,8 +526,9 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { }, lt_op: |region| { match region { - // ignore static regions - ty::ReStatic => region, + // Skip static and bound regions: they don't + // require substitution. + ty::ReStatic | ty::ReLateBound(..) => region, _ => { trace!("checking {:?}", region); for (subst, p) in opaque_defn.substs.iter().zip(&generics.params) { diff --git a/src/test/ui/existential_types/issue-60655-latebound-regions.rs b/src/test/ui/existential_types/issue-60655-latebound-regions.rs new file mode 100644 index 000000000000..a4fe86501299 --- /dev/null +++ b/src/test/ui/existential_types/issue-60655-latebound-regions.rs @@ -0,0 +1,30 @@ +// Test that existential types are allowed to contain late-bound regions. + +// compile-pass +// edition:2018 + +#![feature(async_await, existential_type)] + +use std::future::Future; + +pub existential type Func: Sized; + +// Late bound region should be allowed to escape the function, since it's bound +// in the type. +fn null_function_ptr() -> Func { + None:: fn(&'a ())> +} + +async fn async_nop(_: &u8) {} + +pub existential type ServeFut: Future; + +// Late bound regions occur in the generator witness type here. +fn serve() -> ServeFut { + async move { + let x = 5; + async_nop(&x).await + } +} + +fn main() {} From 7e94f9c72ee5eb33f2e373e91ce6dbd36ae30cf8 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Mon, 13 May 2019 11:03:48 -0400 Subject: [PATCH 131/239] default to $ARCH-apple-macosx10.7.0 LLVM triple for darwin targets Over in #60378, we made `rustc` switch LLVM target triples dynamically based on the `MACOSX_DEPLOYMENT_TARGET` environment variable. This change was made to align with `clang`'s behavior, and therefore make cross-language LTO feasible on OS X. Otherwise, `rustc` would produce LLVM bitcode files with a target triple of `x86_64-apple-darwin`, `clang` would produce LLVM bitcode files with a target triple of `x86_64-apple-macosx$VERSION`, and the linker would complain. This change worked fine, except for one corner case: if you didn't have `MACOSX_DEPLOYMENT_TARGET` set, and you wanted to do LTO on just Rust code, you'd get warning messages similar to: ``` warning: Linking two modules of different target triples: ' is 'x86_64-apple-macosx10.7.0' whereas 'main.7rcbfp3g-cgu.4' is 'x86_64-apple-darwin' ``` This message occurs because libstd is compiled with `MACOSX_DEPLOYMENT_TARGET` set to 10.7. The LLVM bitcode distributed in libstd's rlibs, then, is tagged with the target triple of `x86_64-apple-macosx10.7.0`, while the bitcode `rustc` produces for "user" code is tagged with the target triple of `x86_64-apple-darwin`. It's not good to have LTO on just Rust code (probably much more common than cross-language LTO) warn by default. These warnings also break Cargo's testsuite. This change defaults to acting as though `MACOSX_DEPLOYMENT_TARGET` was set to 10.7. "user" code will then be given a target triple that is equivalent to the target triple libstd bitcode is already using. The above warning will therefore go away. `rustc` already assumes that compiling without `MACOSX_DEPLOYMENT_TARGET` means that we're compiling for a target compatible with OS X 10.7 (e.g. that things like TLS work properly). So this change is really just making things conform more closely to the status quo. (It's also worth noting that before and after this patch, compiling with `MACOSX_DEPLOYMENT_TARGET` set to, say, 10.9, works just fine: target triples with an "apple" version ignore OS versions when checking compatibility, so bitcode with a `x86_64-apple-macosx10.7.0` triple works just fine with bitcode with a `x86_64-apple-macosx10.9.0` triple.) --- src/librustc_target/spec/apple_base.rs | 17 +++++------------ .../codegen/i686-no-macosx-deployment-target.rs | 2 +- .../x86_64-no-macosx-deployment-target.rs | 2 +- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/librustc_target/spec/apple_base.rs b/src/librustc_target/spec/apple_base.rs index 9dd343b6c8de..53364e72bfe3 100644 --- a/src/librustc_target/spec/apple_base.rs +++ b/src/librustc_target/spec/apple_base.rs @@ -14,7 +14,7 @@ pub fn opts() -> TargetOptions { // // Here we detect what version is being requested, defaulting to 10.7. ELF // TLS is flagged as enabled if it looks to be supported. - let version = macos_deployment_target().unwrap_or((10, 7)); + let version = macos_deployment_target(); TargetOptions { // macOS has -dead_strip, which doesn't rely on function_sections @@ -35,7 +35,7 @@ pub fn opts() -> TargetOptions { } } -fn macos_deployment_target() -> Option<(u32, u32)> { +fn macos_deployment_target() -> (u32, u32) { let deployment_target = env::var("MACOSX_DEPLOYMENT_TARGET").ok(); let version = deployment_target.as_ref().and_then(|s| { let mut i = s.splitn(2, '.'); @@ -44,17 +44,10 @@ fn macos_deployment_target() -> Option<(u32, u32)> { a.parse::().and_then(|a| b.parse::().map(|b| (a, b))).ok() }); - version + version.unwrap_or((10, 7)) } pub fn macos_llvm_target(arch: &str) -> String { - let version = macos_deployment_target(); - let llvm_target = match version { - Some((major, minor)) => { - format!("{}-apple-macosx{}.{}.0", arch, major, minor) - }, - None => format!("{}-apple-darwin", arch) - }; - - llvm_target + let (major, minor) = macos_deployment_target(); + format!("{}-apple-macosx{}.{}.0", arch, major, minor) } diff --git a/src/test/codegen/i686-no-macosx-deployment-target.rs b/src/test/codegen/i686-no-macosx-deployment-target.rs index eb826590523b..1cebc49236fe 100644 --- a/src/test/codegen/i686-no-macosx-deployment-target.rs +++ b/src/test/codegen/i686-no-macosx-deployment-target.rs @@ -19,7 +19,7 @@ pub struct Bool { b: bool, } -// CHECK: target triple = "i686-apple-darwin" +// CHECK: target triple = "i686-apple-macosx10.7.0" #[no_mangle] pub extern "C" fn structbool() -> Bool { Bool { b: true } diff --git a/src/test/codegen/x86_64-no-macosx-deployment-target.rs b/src/test/codegen/x86_64-no-macosx-deployment-target.rs index 58a11d1095bb..c5ac73b54e18 100644 --- a/src/test/codegen/x86_64-no-macosx-deployment-target.rs +++ b/src/test/codegen/x86_64-no-macosx-deployment-target.rs @@ -19,7 +19,7 @@ pub struct Bool { b: bool, } -// CHECK: target triple = "x86_64-apple-darwin" +// CHECK: target triple = "x86_64-apple-macosx10.7.0" #[no_mangle] pub extern "C" fn structbool() -> Bool { Bool { b: true } From 01bc58c5eecd0ed993ee37993f24c63780082e76 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Mon, 13 May 2019 17:42:55 -0400 Subject: [PATCH 132/239] remove compiletest's dependency on `filetime` --- Cargo.lock | 1 - src/tools/compiletest/Cargo.toml | 1 - src/tools/compiletest/src/main.rs | 27 ++++++++++++++++----------- src/tools/compiletest/src/runtest.rs | 3 +-- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 982070a243ee..b6dc3bdb89bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -459,7 +459,6 @@ version = "0.0.0" dependencies = [ "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index 336d7e32024b..e759ad1f35dd 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -7,7 +7,6 @@ edition = "2018" [dependencies] diff = "0.1.10" env_logger = { version = "0.5", default-features = false } -filetime = "0.2" getopts = "0.2" log = "0.4" regex = "1.0" diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index e253934e566a..442e58bfd74e 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -9,7 +9,6 @@ use crate::common::CompareMode; use crate::common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS}; use crate::common::{Config, TestPaths}; use crate::common::{DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Mode, Pretty}; -use filetime::FileTime; use getopts::Options; use std::env; use std::ffi::OsString; @@ -17,6 +16,7 @@ use std::fs; use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; use std::process::Command; +use std::time::SystemTime; use test::ColorConfig; use crate::util::logv; use walkdir::WalkDir; @@ -752,31 +752,36 @@ fn up_to_date( #[derive(Debug, PartialEq, PartialOrd, Ord, Eq)] struct Stamp { - time: FileTime, + time: SystemTime, file: PathBuf, } impl Stamp { fn from_path(p: &Path) -> Self { + let time = fs::metadata(p) + .and_then(|metadata| metadata.modified()) + .unwrap_or(SystemTime::UNIX_EPOCH); + Stamp { - time: mtime(&p), + time, file: p.into(), } } - fn from_dir(path: &Path) -> impl Iterator { + fn from_dir(path: &Path) -> impl Iterator { WalkDir::new(path) .into_iter() .map(|entry| entry.unwrap()) .filter(|entry| entry.file_type().is_file()) - .map(|entry| Stamp::from_path(entry.path())) - } -} + .map(|entry| { + let time = (|| -> io::Result<_> { entry.metadata()?.modified() })(); -fn mtime(path: &Path) -> FileTime { - fs::metadata(path) - .map(|f| FileTime::from_last_modification_time(&f)) - .unwrap_or_else(|_| FileTime::zero()) + Stamp { + time: time.unwrap_or(SystemTime::UNIX_EPOCH), + file: entry.path().into(), + } + }) + } } fn make_test_name( diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 10b8133326bb..22c2f0a05379 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -9,7 +9,6 @@ use crate::common::{Config, TestPaths}; use crate::common::{Incremental, MirOpt, RunMake, Ui, JsDocTest, Assembly}; use diff; use crate::errors::{self, Error, ErrorKind}; -use filetime::FileTime; use crate::header::TestProps; use crate::json; use regex::{Captures, Regex}; @@ -3032,7 +3031,7 @@ impl<'test> TestCx<'test> { } fn check_mir_test_timestamp(&self, test_name: &str, output_file: &Path) { - let t = |file| FileTime::from_last_modification_time(&fs::metadata(file).unwrap()); + let t = |file| fs::metadata(file).unwrap().modified().unwrap(); let source_file = &self.testpaths.file; let output_time = t(output_file); let source_time = t(source_file); From 58c6a94f00110a08725182a8519cedee16819c71 Mon Sep 17 00:00:00 2001 From: Benjamin Schultzer Date: Mon, 13 May 2019 15:13:17 -0700 Subject: [PATCH 133/239] Improve the "must use" lint for `Future` Co-Authored-By: Mazdak Farrokhzad --- src/libcore/future/future.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs index 504330a023b3..3f76ac20192b 100644 --- a/src/libcore/future/future.rs +++ b/src/libcore/future/future.rs @@ -23,7 +23,7 @@ use crate::task::{Context, Poll}; /// When using a future, you generally won't call `poll` directly, but instead /// `await!` the value. #[doc(spotlight)] -#[must_use = "futures do nothing unless polled"] +#[must_use = "futures do nothing unless you `.await` or poll them"] #[stable(feature = "futures_api", since = "1.36.0")] pub trait Future { /// The type of value produced on completion. From ea93215576ff04cab3bdb78c0d16ea7253488f40 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Mon, 13 May 2019 22:15:55 -0400 Subject: [PATCH 134/239] Bump measureme dependency to 0.3 measureme@0.3 adds a version header to the binary file format which will help reduce tool breakage in the future. --- Cargo.lock | 6 +++--- src/librustc/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 982070a243ee..4417c25abcb4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1481,7 +1481,7 @@ dependencies = [ [[package]] name = "measureme" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2346,7 +2346,7 @@ dependencies = [ "jobserver 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "measureme 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "measureme 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "polonius-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4174,7 +4174,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum mdbook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "90b5a8d7e341ceee5db3882a06078d42661ddcfa2b3687319cc5da76ec4e782f" "checksum mdbook 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba0d44cb4089c741b9a91f3e5218298a40699c2f3a070a85014eed290c60819" -"checksum measureme 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "36bb2b263a6795d352035024d6b30ce465bb79a5e5280d74c3b5f8464c657bcc" +"checksum measureme 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d09de7dafa3aa334bc806447c7e4de69419723312f4b88b80b561dea66601ce8" "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 2468de99d60a..4d50e80d4cf6 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -36,7 +36,7 @@ byteorder = { version = "1.1", features = ["i128"]} chalk-engine = { version = "0.9.0", default-features=false } rustc_fs_util = { path = "../librustc_fs_util" } smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } -measureme = "0.2.1" +measureme = "0.3" # Note that these dependencies are a lie, they're just here to get linkage to # work. From 7171bd1f69fb1c1a999b8e968fc693da325f3cc4 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Mon, 13 May 2019 21:54:47 -0700 Subject: [PATCH 135/239] README: Mention MSVC 2017+, not 2013(!) LLVM will soon require 2017+ [1] (and our in-tree version just rejected the version of 2015 I was using), so update the mention and provide a link. [1]: https://llvm.org/docs/GettingStarted.html#host-c-toolchain-both-compiler-and-standard-library --- README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f6f796911b8f..75d7823490a2 100644 --- a/README.md +++ b/README.md @@ -128,9 +128,15 @@ build. #### MSVC [windows-msvc]: #windows-msvc -MSVC builds of Rust additionally require an installation of Visual Studio 2013 -(or later) so `rustc` can use its linker. Make sure to check the “C++ tools” -option. +MSVC builds of Rust additionally require an installation of Visual Studio 2017 +(or later) so `rustc` can use its linker. The simplest way is to get the +[Visual Studio Build Tools] and check the “C++ build tools” workload. + +[Visual Studio Build Tools]: https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019 + +At last check (cmake 3.14.3 and msvc 16.0.3) using the 2019 tools fails to +build the in-tree LLVM build with a CMake error, so use 2017 instead by +including the “MSVC v141 – VS 2017 C++ x64/x86 build tools (v14.16)” component. With these dependencies installed, you can build the compiler in a `cmd.exe` shell with: From a7a05203f18eac663ebf2751b77621c453dc280c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Wiedenh=C3=B6ft?= Date: Mon, 29 Apr 2019 15:49:43 +0200 Subject: [PATCH 136/239] Mark core::alloc::Layout::from_size_align_unchecked const --- src/libcore/alloc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index c124457118cb..302a9d89e585 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -99,7 +99,7 @@ impl Layout { /// [`Layout::from_size_align`](#method.from_size_align). #[stable(feature = "alloc_layout", since = "1.28.0")] #[inline] - pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self { + pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self { Layout { size_: size, align_: NonZeroUsize::new_unchecked(align) } } From 07e8d844795628ce90415c1dec3536f3e75cc71c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Wiedenh=C3=B6ft?= Date: Tue, 30 Apr 2019 08:23:14 +0200 Subject: [PATCH 137/239] Add const_unchecked_layout test to libcore/tests --- src/libcore/tests/alloc.rs | 10 ++++++++++ src/libcore/tests/lib.rs | 2 ++ 2 files changed, 12 insertions(+) create mode 100644 src/libcore/tests/alloc.rs diff --git a/src/libcore/tests/alloc.rs b/src/libcore/tests/alloc.rs new file mode 100644 index 000000000000..63537ba23d84 --- /dev/null +++ b/src/libcore/tests/alloc.rs @@ -0,0 +1,10 @@ +use core::alloc::Layout; + +#[test] +fn const_unchecked_layout() { + const SIZE: usize = 0x2000; + const ALIGN: usize = 0x1000; + const LAYOUT: Layout = unsafe { Layout::from_size_align_unchecked(SIZE, ALIGN) }; + assert_eq!(LAYOUT.size(), SIZE); + assert_eq!(LAYOUT.align(), ALIGN); +} diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index b8075ef2942e..c617596aba80 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -31,10 +31,12 @@ #![feature(slice_partition_dedup)] #![feature(copy_within)] #![feature(int_error_matching)] +#![feature(const_fn)] #![warn(rust_2018_idioms)] extern crate test; +mod alloc; mod any; mod array; mod ascii; From c0b6d3c975915e740548f0ec7bcf5963e7a3b218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Wiedenh=C3=B6ft?= Date: Tue, 30 Apr 2019 12:56:38 +0200 Subject: [PATCH 138/239] Add ui test for const Layout::from_size_align_unchecked --- src/test/ui/consts/std/alloc.rs | 10 ++++++++++ src/test/ui/consts/std/alloc.stderr | 11 +++++++++++ 2 files changed, 21 insertions(+) create mode 100644 src/test/ui/consts/std/alloc.rs create mode 100644 src/test/ui/consts/std/alloc.stderr diff --git a/src/test/ui/consts/std/alloc.rs b/src/test/ui/consts/std/alloc.rs new file mode 100644 index 000000000000..65ac7e44926d --- /dev/null +++ b/src/test/ui/consts/std/alloc.rs @@ -0,0 +1,10 @@ +use std::alloc::Layout; + +// ok +const LAYOUT_VALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x08) }; + +// not ok, since alignment needs to be non-zero. +const LAYOUT_INVALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) }; +//~^ ERROR it is undefined behavior to use this value + +fn main() {} diff --git a/src/test/ui/consts/std/alloc.stderr b/src/test/ui/consts/std/alloc.stderr new file mode 100644 index 000000000000..74a8f3daf6aa --- /dev/null +++ b/src/test/ui/consts/std/alloc.stderr @@ -0,0 +1,11 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/alloc.rs:7:1 + | +LL | const LAYOUT_INVALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0 at .align_, but expected something greater or equal to 1 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. From b470d48c8a58a6cd91a14e5ba6387f424da6c5db Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 14 May 2019 09:42:32 +0100 Subject: [PATCH 139/239] Add comment --- src/bootstrap/test.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 3847a2a1e464..f1bb318651a3 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1186,6 +1186,12 @@ impl Step for Compiletest { }) .filter(|p| p.starts_with(suite_path) && (p.is_dir() || p.is_file())) .filter_map(|p| { + // Since test suite paths are themselves directories, if we don't + // specify a directory or file, we'll get an empty string here + // (the result of the test suite directory without its suite prefix). + // Therefore, we need to filter these out, as only the first --test-args + // flag is respected, so providing an empty --test-args conflicts with + // any following it. match p.strip_prefix(suite_path).ok().and_then(|p| p.to_str()) { Some(s) if s != "" => Some(s), _ => None, From 30317050092cc7a469f0815d40d400a812749564 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Tue, 14 May 2019 14:14:12 +0530 Subject: [PATCH 140/239] some more refactor of FnType. Things build now --- src/librustc/ty/layout.rs | 186 ++++++++++------- src/librustc_codegen_llvm/abi.rs | 297 ++++++++++++++++++++++++++- src/librustc_codegen_llvm/declare.rs | 6 +- src/librustc_codegen_llvm/type_of.rs | 4 +- 4 files changed, 409 insertions(+), 84 deletions(-) diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 58d27d4c5dbe..6d7b0926c7ae 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -19,9 +19,9 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; pub use rustc_target::abi::*; -use rustc_target::spec::HasTargetSpec; +use rustc_target::spec::{HasTargetSpec, abi::Abi as SpecAbi}; use rustc_target::abi::call::{ - ArgAttribute, ArgAttributes, ArgType, Conv, FnType, IgnoreMode, PassMode + ArgAttribute, ArgAttributes, ArgType, Conv, FnType, IgnoreMode, PassMode, Reg, RegKind }; @@ -2266,53 +2266,35 @@ impl<'a, 'gcx> HashStable> for LayoutError<'gcx> } } -pub trait FnTypeExt<'tcx, C> { - fn of_instance(cx: &C, instance: &ty::Instance<'tcx>) -> Self - where - C: LayoutOf, TyLayout = TyLayout<'tcx>> - + HasDataLayout - + HasTargetSpec - + HasTyCtxt<'tcx> - + HasParamEnv<'tcx>; - fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self - where - C: LayoutOf, TyLayout = TyLayout<'tcx>> - + HasDataLayout - + HasTargetSpec - + HasTyCtxt<'tcx> - + HasParamEnv<'tcx>; - fn new_vtable(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self - where - C: LayoutOf, TyLayout = TyLayout<'tcx>> - + HasDataLayout - + HasTargetSpec - + HasTyCtxt<'tcx> - + HasParamEnv<'tcx>; +pub trait FnTypeExt<'tcx, C> +where + C: LayoutOf, TyLayout = TyLayout<'tcx>> + + HasDataLayout + + HasTargetSpec + + HasTyCtxt<'tcx> + + HasParamEnv<'tcx>, +{ + fn of_instance(cx: &C, instance: &ty::Instance<'tcx>) -> Self; + fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self; + fn new_vtable(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self; fn new_internal( cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>], mk_arg_type: impl Fn(Ty<'tcx>, Option) -> ArgType<'tcx, Ty<'tcx>>, - ) -> Self - where - C: LayoutOf, TyLayout = TyLayout<'tcx>> - + HasDataLayout - + HasTargetSpec - + HasTyCtxt<'tcx> - + HasParamEnv<'tcx>; + ) -> Self; + fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi); } - -impl<'tcx, C> FnTypeExt<'tcx, C> for call::FnType<'tcx, Ty<'tcx>> { - fn of_instance(cx: &C, instance: &ty::Instance<'tcx>) -> Self - where - C: LayoutOf, TyLayout = TyLayout<'tcx>> - + HasDataLayout - + HasTargetSpec - + HasTargetSpec - + HasTyCtxt<'tcx> - + HasParamEnv<'tcx>, - { +impl<'tcx, C> FnTypeExt<'tcx, C> for call::FnType<'tcx, Ty<'tcx>> +where + C: LayoutOf, TyLayout = TyLayout<'tcx>> + + HasDataLayout + + HasTargetSpec + + HasTyCtxt<'tcx> + + HasParamEnv<'tcx>, +{ + fn of_instance(cx: &C, instance: &ty::Instance<'tcx>) -> Self { let sig = instance.fn_sig(cx.tcx()); let sig = cx .tcx() @@ -2320,27 +2302,12 @@ impl<'tcx, C> FnTypeExt<'tcx, C> for call::FnType<'tcx, Ty<'tcx>> { call::FnType::new(cx, sig, &[]) } - fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self - where - C: LayoutOf, TyLayout = TyLayout<'tcx>> - + HasDataLayout - + HasTargetSpec - + HasTyCtxt<'tcx> - + HasParamEnv<'tcx>, - { + fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self { call::FnType::new_internal(cx, sig, extra_args, |ty, _| ArgType::new(cx.layout_of(ty))) } - - fn new_vtable(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self - where - C: LayoutOf, TyLayout = TyLayout<'tcx>> - + HasDataLayout - + HasTargetSpec - + HasTyCtxt<'tcx> - + HasParamEnv<'tcx>, - { - FnType::new_internal(cx, sig, extra_args, |ty, arg_idx| { + fn new_vtable(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self { + FnTypeExt::new_internal(cx, sig, extra_args, |ty, arg_idx| { let mut layout = cx.layout_of(ty); // Don't pass the vtable, it's not an argument of the virtual fn. // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait` @@ -2395,19 +2362,11 @@ impl<'tcx, C> FnTypeExt<'tcx, C> for call::FnType<'tcx, Ty<'tcx>> { } fn new_internal( - cx: &C, - sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>], - mk_arg_type: impl Fn(Ty<'tcx>, Option) -> ArgType<'tcx, Ty<'tcx>>, - ) -> Self - where - C: LayoutOf, TyLayout = TyLayout<'tcx>> - + HasDataLayout - + HasTargetSpec - + HasTargetSpec - + HasTyCtxt<'tcx> - + HasParamEnv<'tcx>, - { + cx: &C, + sig: ty::FnSig<'tcx>, + extra_args: &[Ty<'tcx>], + mk_arg_type: impl Fn(Ty<'tcx>, Option) -> ArgType<'tcx, Ty<'tcx>>, + ) -> Self { debug!("FnType::new_internal({:?}, {:?})", sig, extra_args); use rustc_target::spec::abi::Abi::*; @@ -2591,7 +2550,7 @@ impl<'tcx, C> FnTypeExt<'tcx, C> for call::FnType<'tcx, Ty<'tcx>> { arg }; - let fn_ty = FnType { + let mut fn_ty = FnType { ret: arg_of(sig.output(), None), args: inputs .iter() @@ -2603,8 +2562,83 @@ impl<'tcx, C> FnTypeExt<'tcx, C> for call::FnType<'tcx, Ty<'tcx>> { c_variadic: sig.c_variadic, conv, }; - // FIXME: uncomment this after figuring out wwhere should adjust_for_abi reside. - //fn_ty.adjust_for_abi(cx, sig.abi); + fn_ty.adjust_for_abi(cx, sig.abi); fn_ty } + + fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi) { + if abi == SpecAbi::Unadjusted { + return; + } + + if abi == SpecAbi::Rust + || abi == SpecAbi::RustCall + || abi == SpecAbi::RustIntrinsic + || abi == SpecAbi::PlatformIntrinsic + { + let fixup = |arg: &mut ArgType<'tcx, Ty<'tcx>>| { + if arg.is_ignore() { + return; + } + + match arg.layout.abi { + Abi::Aggregate { .. } => {} + + // This is a fun case! The gist of what this is doing is + // that we want callers and callees to always agree on the + // ABI of how they pass SIMD arguments. If we were to *not* + // make these arguments indirect then they'd be immediates + // in LLVM, which means that they'd used whatever the + // appropriate ABI is for the callee and the caller. That + // means, for example, if the caller doesn't have AVX + // enabled but the callee does, then passing an AVX argument + // across this boundary would cause corrupt data to show up. + // + // This problem is fixed by unconditionally passing SIMD + // arguments through memory between callers and callees + // which should get them all to agree on ABI regardless of + // target feature sets. Some more information about this + // issue can be found in #44367. + // + // Note that the platform intrinsic ABI is exempt here as + // that's how we connect up to LLVM and it's unstable + // anyway, we control all calls to it in libstd. + Abi::Vector { .. } + if abi != SpecAbi::PlatformIntrinsic + && cx.tcx().sess.target.target.options.simd_types_indirect => + { + arg.make_indirect(); + return; + } + + _ => return, + } + + let size = arg.layout.size; + if arg.layout.is_unsized() || size > Pointer.size(cx) { + arg.make_indirect(); + } else { + // We want to pass small aggregates as immediates, but using + // a LLVM aggregate type for this leads to bad optimizations, + // so we pick an appropriately sized integer type instead. + arg.cast_to(Reg { + kind: RegKind::Integer, + size, + }); + } + }; + fixup(&mut self.ret); + for arg in &mut self.args { + fixup(arg); + } + if let PassMode::Indirect(ref mut attrs, _) = self.ret.mode { + attrs.set(ArgAttribute::StructRet); + } + return; + } + + if let Err(msg) = self.adjust_for_cabi(cx, abi) { + cx.tcx().sess.fatal(&msg); + } + } } diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index cf4a523d9caa..00e17ff990d9 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -295,6 +295,19 @@ impl ArgTypeMethods<'tcx> for Builder<'a, 'll, 'tcx> { } pub trait FnTypeExt<'tcx> { + fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>) -> Self; + fn new(cx: &CodegenCx<'ll, 'tcx>, + sig: ty::FnSig<'tcx>, + extra_args: &[Ty<'tcx>]) -> Self; + fn new_vtable(cx: &CodegenCx<'ll, 'tcx>, + sig: ty::FnSig<'tcx>, + extra_args: &[Ty<'tcx>]) -> Self; + fn new_internal( + cx: &CodegenCx<'ll, 'tcx>, + sig: ty::FnSig<'tcx>, + extra_args: &[Ty<'tcx>], + mk_arg_type: impl Fn(Ty<'tcx>, Option) -> ArgType<'tcx, Ty<'tcx>>, + ) -> Self; fn adjust_for_abi(&mut self, cx: &CodegenCx<'ll, 'tcx>, abi: Abi); @@ -306,6 +319,284 @@ pub trait FnTypeExt<'tcx> { } impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> { + fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>) -> Self { + let sig = instance.fn_sig(cx.tcx); + let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); + FnTypeExt::new(cx, sig, &[]) + } + + fn new(cx: &CodegenCx<'ll, 'tcx>, + sig: ty::FnSig<'tcx>, + extra_args: &[Ty<'tcx>]) -> Self { + FnTypeExt::new_internal(cx, sig, extra_args, |ty, _| { + ArgType::new(cx.layout_of(ty)) + }) + } + + fn new_vtable(cx: &CodegenCx<'ll, 'tcx>, + sig: ty::FnSig<'tcx>, + extra_args: &[Ty<'tcx>]) -> Self { + FnTypeExt::new_internal(cx, sig, extra_args, |ty, arg_idx| { + let mut layout = cx.layout_of(ty); + // Don't pass the vtable, it's not an argument of the virtual fn. + // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait` + // or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen + if arg_idx == Some(0) { + let fat_pointer_ty = if layout.is_unsized() { + // unsized `self` is passed as a pointer to `self` + // FIXME (mikeyhew) change this to use &own if it is ever added to the language + cx.tcx.mk_mut_ptr(layout.ty) + } else { + match layout.abi { + LayoutAbi::ScalarPair(..) => (), + _ => bug!("receiver type has unsupported layout: {:?}", layout) + } + + // In the case of Rc, we need to explicitly pass a *mut RcBox + // with a Scalar (not ScalarPair) ABI. This is a hack that is understood + // elsewhere in the compiler as a method on a `dyn Trait`. + // To get the type `*mut RcBox`, we just keep unwrapping newtypes until we + // get a built-in pointer type + let mut fat_pointer_layout = layout; + 'descend_newtypes: while !fat_pointer_layout.ty.is_unsafe_ptr() + && !fat_pointer_layout.ty.is_region_ptr() + { + 'iter_fields: for i in 0..fat_pointer_layout.fields.count() { + let field_layout = fat_pointer_layout.field(cx, i); + + if !field_layout.is_zst() { + fat_pointer_layout = field_layout; + continue 'descend_newtypes + } + } + + bug!("receiver has no non-zero-sized fields {:?}", fat_pointer_layout); + } + + fat_pointer_layout.ty + }; + + // we now have a type like `*mut RcBox` + // change its layout to that of `*mut ()`, a thin pointer, but keep the same type + // this is understood as a special case elsewhere in the compiler + let unit_pointer_ty = cx.tcx.mk_mut_ptr(cx.tcx.mk_unit()); + layout = cx.layout_of(unit_pointer_ty); + layout.ty = fat_pointer_ty; + } + ArgType::new(layout) + }) + } + + fn new_internal( + cx: &CodegenCx<'ll, 'tcx>, + sig: ty::FnSig<'tcx>, + extra_args: &[Ty<'tcx>], + mk_arg_type: impl Fn(Ty<'tcx>, Option) -> ArgType<'tcx, Ty<'tcx>>, + ) -> Self { + debug!("FnType::new_internal({:?}, {:?})", sig, extra_args); + + use self::Abi::*; + let conv = match cx.sess().target.target.adjust_abi(sig.abi) { + RustIntrinsic | PlatformIntrinsic | + Rust | RustCall => Conv::C, + + // It's the ABI's job to select this, not ours. + System => bug!("system abi should be selected elsewhere"), + + Stdcall => Conv::X86Stdcall, + Fastcall => Conv::X86Fastcall, + Vectorcall => Conv::X86VectorCall, + Thiscall => Conv::X86ThisCall, + C => Conv::C, + Unadjusted => Conv::C, + Win64 => Conv::X86_64Win64, + SysV64 => Conv::X86_64SysV, + Aapcs => Conv::ArmAapcs, + PtxKernel => Conv::PtxKernel, + Msp430Interrupt => Conv::Msp430Intr, + X86Interrupt => Conv::X86Intr, + AmdGpuKernel => Conv::AmdGpuKernel, + + // These API constants ought to be more specific... + Cdecl => Conv::C, + }; + + let mut inputs = sig.inputs(); + let extra_args = if sig.abi == RustCall { + assert!(!sig.c_variadic && extra_args.is_empty()); + + match sig.inputs().last().unwrap().sty { + ty::Tuple(tupled_arguments) => { + inputs = &sig.inputs()[0..sig.inputs().len() - 1]; + tupled_arguments.iter().map(|k| k.expect_ty()).collect() + } + _ => { + bug!("argument to function with \"rust-call\" ABI \ + is not a tuple"); + } + } + } else { + assert!(sig.c_variadic || extra_args.is_empty()); + extra_args.to_vec() + }; + + let target = &cx.sess().target.target; + let win_x64_gnu = target.target_os == "windows" + && target.arch == "x86_64" + && target.target_env == "gnu"; + let linux_s390x = target.target_os == "linux" + && target.arch == "s390x" + && target.target_env == "gnu"; + let linux_sparc64 = target.target_os == "linux" + && target.arch == "sparc64" + && target.target_env == "gnu"; + let rust_abi = match sig.abi { + RustIntrinsic | PlatformIntrinsic | Rust | RustCall => true, + _ => false + }; + + // Handle safe Rust thin and fat pointers. + let adjust_for_rust_scalar = |attrs: &mut ArgAttributes, + scalar: &layout::Scalar, + layout: TyLayout<'tcx, Ty<'tcx>>, + offset: Size, + is_return: bool| { + // Booleans are always an i1 that needs to be zero-extended. + if scalar.is_bool() { + attrs.set(ArgAttribute::ZExt); + return; + } + + // Only pointer types handled below. + if scalar.value != layout::Pointer { + return; + } + + if scalar.valid_range.start() < scalar.valid_range.end() { + if *scalar.valid_range.start() > 0 { + attrs.set(ArgAttribute::NonNull); + } + } + + if let Some(pointee) = layout.pointee_info_at(cx, offset) { + if let Some(kind) = pointee.safe { + attrs.pointee_size = pointee.size; + attrs.pointee_align = Some(pointee.align); + + // `Box` pointer parameters never alias because ownership is transferred + // `&mut` pointer parameters never alias other parameters, + // or mutable global data + // + // `&T` where `T` contains no `UnsafeCell` is immutable, + // and can be marked as both `readonly` and `noalias`, as + // LLVM's definition of `noalias` is based solely on memory + // dependencies rather than pointer equality + let no_alias = match kind { + PointerKind::Shared => false, + PointerKind::UniqueOwned => true, + PointerKind::Frozen | + PointerKind::UniqueBorrowed => !is_return + }; + if no_alias { + attrs.set(ArgAttribute::NoAlias); + } + + if kind == PointerKind::Frozen && !is_return { + attrs.set(ArgAttribute::ReadOnly); + } + } + } + }; + + // Store the index of the last argument. This is useful for working with + // C-compatible variadic arguments. + let last_arg_idx = if sig.inputs().is_empty() { + None + } else { + Some(sig.inputs().len() - 1) + }; + + let arg_of = |ty: Ty<'tcx>, arg_idx: Option| { + let is_return = arg_idx.is_none(); + let mut arg = mk_arg_type(ty, arg_idx); + if arg.layout.is_zst() { + // For some forsaken reason, x86_64-pc-windows-gnu + // doesn't ignore zero-sized struct arguments. + // The same is true for s390x-unknown-linux-gnu + // and sparc64-unknown-linux-gnu. + if is_return || rust_abi || (!win_x64_gnu && !linux_s390x && !linux_sparc64) { + arg.mode = PassMode::Ignore(IgnoreMode::Zst); + } + } + + // If this is a C-variadic function, this is not the return value, + // and there is one or more fixed arguments; ensure that the `VaList` + // is ignored as an argument. + if sig.c_variadic { + match (last_arg_idx, arg_idx) { + (Some(last_idx), Some(cur_idx)) if last_idx == cur_idx => { + let va_list_did = match cx.tcx.lang_items().va_list() { + Some(did) => did, + None => bug!("`va_list` lang item required for C-variadic functions"), + }; + match ty.sty { + ty::Adt(def, _) if def.did == va_list_did => { + // This is the "spoofed" `VaList`. Set the arguments mode + // so that it will be ignored. + arg.mode = PassMode::Ignore(IgnoreMode::CVarArgs); + }, + _ => (), + } + } + _ => {} + } + } + + // FIXME(eddyb) other ABIs don't have logic for scalar pairs. + if !is_return && rust_abi { + if let layout::Abi::ScalarPair(ref a, ref b) = arg.layout.abi { + let mut a_attrs = ArgAttributes::new(); + let mut b_attrs = ArgAttributes::new(); + adjust_for_rust_scalar(&mut a_attrs, + a, + arg.layout, + Size::ZERO, + false); + adjust_for_rust_scalar(&mut b_attrs, + b, + arg.layout, + a.value.size(cx).align_to(b.value.align(cx).abi), + false); + arg.mode = PassMode::Pair(a_attrs, b_attrs); + return arg; + } + } + + if let layout::Abi::Scalar(ref scalar) = arg.layout.abi { + if let PassMode::Direct(ref mut attrs) = arg.mode { + adjust_for_rust_scalar(attrs, + scalar, + arg.layout, + Size::ZERO, + is_return); + } + } + + arg + }; + + let mut fn_ty = FnType { + ret: arg_of(sig.output(), None), + args: inputs.iter().cloned().chain(extra_args).enumerate().map(|(i, ty)| { + arg_of(ty, Some(i)) + }).collect(), + c_variadic: sig.c_variadic, + conv, + }; + FnTypeExt::adjust_for_abi(&mut fn_ty, cx, sig.abi); + fn_ty + } + fn adjust_for_abi(&mut self, cx: &CodegenCx<'ll, 'tcx>, abi: Abi) { @@ -547,17 +838,17 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> { impl AbiMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn new_fn_type(&self, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> FnType<'tcx, Ty<'tcx>> { - FnType::new(&self, sig, extra_args) + FnTypeExt::new(&self, sig, extra_args) } fn new_vtable( &self, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>] ) -> FnType<'tcx, Ty<'tcx>> { - FnType::new_vtable(&self, sig, extra_args) + FnTypeExt::new_vtable(&self, sig, extra_args) } fn fn_type_of_instance(&self, instance: &Instance<'tcx>) -> FnType<'tcx, Ty<'tcx>> { - FnType::of_instance(&self, instance) + FnTypeExt::of_instance(&self, instance) } } diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index 3febcb019ce2..6b8a45da1803 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -18,8 +18,8 @@ use crate::attributes; use crate::context::CodegenCx; use crate::type_::Type; use crate::value::Value; -use rustc::ty::{self, PolyFnSig}; -use rustc::ty::layout::LayoutOf; +use rustc::ty::{self, PolyFnSig, Ty}; +use rustc::ty::layout::{FnTypeExt as FnTypeExt1, LayoutOf}; use rustc::session::config::Sanitizer; use rustc_data_structures::small_c_str::SmallCStr; use rustc_codegen_ssa::traits::*; @@ -100,7 +100,7 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> { let sig = self.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); debug!("declare_rust_fn (after region erasure) sig={:?}", sig); - let fty = FnType::new(self, sig, &[]); + let fty: FnType<'tcx, Ty<'tcx>> = FnTypeExt1::new(self, sig, &[]); let llfn = declare_raw_fn(self, name, fty.llvm_cconv(), fty.llvm_type(self)); if self.layout_of(sig.output()).abi.is_uninhabited() { diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs index ff25ed925661..800bf505125d 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/src/librustc_codegen_llvm/type_of.rs @@ -1,8 +1,8 @@ -use crate::abi::{FnType, FnTypeExt}; +use crate::abi::{FnType}; use crate::common::*; use crate::type_::Type; use rustc::ty::{self, Ty, TypeFoldable}; -use rustc::ty::layout::{self, Align, LayoutOf, PointeeInfo, Size, TyLayout}; +use rustc::ty::layout::{self, Align, LayoutOf, FnTypeExt, PointeeInfo, Size, TyLayout}; use rustc_target::abi::{FloatTy, TyLayoutMethods}; use rustc_mir::monomorphize::item::DefPathBasedNames; use rustc_codegen_ssa::traits::*; From 41184aa545c8ddf3e417dedbc23a6c8198d5de8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Tue, 14 May 2019 11:36:31 +0200 Subject: [PATCH 141/239] submodules: update clippy from 3710ec59 to ad3269c4 Changes: ```` Rustfmt all the things Clippy dogfood Update for compiletest changes Use symbols instead of strings Rustup to rustc 1.36.0-nightly (1764b2972 2019-05-12) Add regression test for identity_conversion FP UI test cleanup: Extract many_single_char_names tests Add tests for empty_loop lint Add in_macro again Rename in_macro to in_macro_or_desugar ```` --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index 3710ec599622..ad3269c4b510 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 3710ec59962295336ab4aed100267b584dd7df7d +Subproject commit ad3269c4b510b94b7c0082f4bb341bee6ed1eca4 From e1b3c79d5c9ff805a03b478e77b44f9b48d848f0 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Tue, 14 May 2019 15:20:29 +0530 Subject: [PATCH 142/239] refactor complete --- src/librustc_codegen_llvm/abi.rs | 379 +-------------------------- src/librustc_codegen_llvm/declare.rs | 8 +- src/librustc_codegen_llvm/type_.rs | 2 +- 3 files changed, 12 insertions(+), 377 deletions(-) diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 00e17ff990d9..16e5695c8319 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -11,9 +11,9 @@ use rustc_target::abi::call::ArgType; use rustc_codegen_ssa::traits::*; -use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TyLayout, Abi as LayoutAbi}; +use rustc_target::abi::{HasDataLayout, LayoutOf}; use rustc::ty::{self, Ty, Instance}; -use rustc::ty::layout::{self, PointerKind}; +use rustc::ty::layout::{self, FnTypeExt}; use libc::c_uint; @@ -294,23 +294,7 @@ impl ArgTypeMethods<'tcx> for Builder<'a, 'll, 'tcx> { } } -pub trait FnTypeExt<'tcx> { - fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>) -> Self; - fn new(cx: &CodegenCx<'ll, 'tcx>, - sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>]) -> Self; - fn new_vtable(cx: &CodegenCx<'ll, 'tcx>, - sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>]) -> Self; - fn new_internal( - cx: &CodegenCx<'ll, 'tcx>, - sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>], - mk_arg_type: impl Fn(Ty<'tcx>, Option) -> ArgType<'tcx, Ty<'tcx>>, - ) -> Self; - fn adjust_for_abi(&mut self, - cx: &CodegenCx<'ll, 'tcx>, - abi: Abi); +pub trait FnTypeLlvmExt<'tcx> { fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type; fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type; fn llvm_cconv(&self) -> llvm::CallConv; @@ -318,356 +302,7 @@ pub trait FnTypeExt<'tcx> { fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value); } -impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> { - fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>) -> Self { - let sig = instance.fn_sig(cx.tcx); - let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); - FnTypeExt::new(cx, sig, &[]) - } - - fn new(cx: &CodegenCx<'ll, 'tcx>, - sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>]) -> Self { - FnTypeExt::new_internal(cx, sig, extra_args, |ty, _| { - ArgType::new(cx.layout_of(ty)) - }) - } - - fn new_vtable(cx: &CodegenCx<'ll, 'tcx>, - sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>]) -> Self { - FnTypeExt::new_internal(cx, sig, extra_args, |ty, arg_idx| { - let mut layout = cx.layout_of(ty); - // Don't pass the vtable, it's not an argument of the virtual fn. - // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait` - // or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen - if arg_idx == Some(0) { - let fat_pointer_ty = if layout.is_unsized() { - // unsized `self` is passed as a pointer to `self` - // FIXME (mikeyhew) change this to use &own if it is ever added to the language - cx.tcx.mk_mut_ptr(layout.ty) - } else { - match layout.abi { - LayoutAbi::ScalarPair(..) => (), - _ => bug!("receiver type has unsupported layout: {:?}", layout) - } - - // In the case of Rc, we need to explicitly pass a *mut RcBox - // with a Scalar (not ScalarPair) ABI. This is a hack that is understood - // elsewhere in the compiler as a method on a `dyn Trait`. - // To get the type `*mut RcBox`, we just keep unwrapping newtypes until we - // get a built-in pointer type - let mut fat_pointer_layout = layout; - 'descend_newtypes: while !fat_pointer_layout.ty.is_unsafe_ptr() - && !fat_pointer_layout.ty.is_region_ptr() - { - 'iter_fields: for i in 0..fat_pointer_layout.fields.count() { - let field_layout = fat_pointer_layout.field(cx, i); - - if !field_layout.is_zst() { - fat_pointer_layout = field_layout; - continue 'descend_newtypes - } - } - - bug!("receiver has no non-zero-sized fields {:?}", fat_pointer_layout); - } - - fat_pointer_layout.ty - }; - - // we now have a type like `*mut RcBox` - // change its layout to that of `*mut ()`, a thin pointer, but keep the same type - // this is understood as a special case elsewhere in the compiler - let unit_pointer_ty = cx.tcx.mk_mut_ptr(cx.tcx.mk_unit()); - layout = cx.layout_of(unit_pointer_ty); - layout.ty = fat_pointer_ty; - } - ArgType::new(layout) - }) - } - - fn new_internal( - cx: &CodegenCx<'ll, 'tcx>, - sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>], - mk_arg_type: impl Fn(Ty<'tcx>, Option) -> ArgType<'tcx, Ty<'tcx>>, - ) -> Self { - debug!("FnType::new_internal({:?}, {:?})", sig, extra_args); - - use self::Abi::*; - let conv = match cx.sess().target.target.adjust_abi(sig.abi) { - RustIntrinsic | PlatformIntrinsic | - Rust | RustCall => Conv::C, - - // It's the ABI's job to select this, not ours. - System => bug!("system abi should be selected elsewhere"), - - Stdcall => Conv::X86Stdcall, - Fastcall => Conv::X86Fastcall, - Vectorcall => Conv::X86VectorCall, - Thiscall => Conv::X86ThisCall, - C => Conv::C, - Unadjusted => Conv::C, - Win64 => Conv::X86_64Win64, - SysV64 => Conv::X86_64SysV, - Aapcs => Conv::ArmAapcs, - PtxKernel => Conv::PtxKernel, - Msp430Interrupt => Conv::Msp430Intr, - X86Interrupt => Conv::X86Intr, - AmdGpuKernel => Conv::AmdGpuKernel, - - // These API constants ought to be more specific... - Cdecl => Conv::C, - }; - - let mut inputs = sig.inputs(); - let extra_args = if sig.abi == RustCall { - assert!(!sig.c_variadic && extra_args.is_empty()); - - match sig.inputs().last().unwrap().sty { - ty::Tuple(tupled_arguments) => { - inputs = &sig.inputs()[0..sig.inputs().len() - 1]; - tupled_arguments.iter().map(|k| k.expect_ty()).collect() - } - _ => { - bug!("argument to function with \"rust-call\" ABI \ - is not a tuple"); - } - } - } else { - assert!(sig.c_variadic || extra_args.is_empty()); - extra_args.to_vec() - }; - - let target = &cx.sess().target.target; - let win_x64_gnu = target.target_os == "windows" - && target.arch == "x86_64" - && target.target_env == "gnu"; - let linux_s390x = target.target_os == "linux" - && target.arch == "s390x" - && target.target_env == "gnu"; - let linux_sparc64 = target.target_os == "linux" - && target.arch == "sparc64" - && target.target_env == "gnu"; - let rust_abi = match sig.abi { - RustIntrinsic | PlatformIntrinsic | Rust | RustCall => true, - _ => false - }; - - // Handle safe Rust thin and fat pointers. - let adjust_for_rust_scalar = |attrs: &mut ArgAttributes, - scalar: &layout::Scalar, - layout: TyLayout<'tcx, Ty<'tcx>>, - offset: Size, - is_return: bool| { - // Booleans are always an i1 that needs to be zero-extended. - if scalar.is_bool() { - attrs.set(ArgAttribute::ZExt); - return; - } - - // Only pointer types handled below. - if scalar.value != layout::Pointer { - return; - } - - if scalar.valid_range.start() < scalar.valid_range.end() { - if *scalar.valid_range.start() > 0 { - attrs.set(ArgAttribute::NonNull); - } - } - - if let Some(pointee) = layout.pointee_info_at(cx, offset) { - if let Some(kind) = pointee.safe { - attrs.pointee_size = pointee.size; - attrs.pointee_align = Some(pointee.align); - - // `Box` pointer parameters never alias because ownership is transferred - // `&mut` pointer parameters never alias other parameters, - // or mutable global data - // - // `&T` where `T` contains no `UnsafeCell` is immutable, - // and can be marked as both `readonly` and `noalias`, as - // LLVM's definition of `noalias` is based solely on memory - // dependencies rather than pointer equality - let no_alias = match kind { - PointerKind::Shared => false, - PointerKind::UniqueOwned => true, - PointerKind::Frozen | - PointerKind::UniqueBorrowed => !is_return - }; - if no_alias { - attrs.set(ArgAttribute::NoAlias); - } - - if kind == PointerKind::Frozen && !is_return { - attrs.set(ArgAttribute::ReadOnly); - } - } - } - }; - - // Store the index of the last argument. This is useful for working with - // C-compatible variadic arguments. - let last_arg_idx = if sig.inputs().is_empty() { - None - } else { - Some(sig.inputs().len() - 1) - }; - - let arg_of = |ty: Ty<'tcx>, arg_idx: Option| { - let is_return = arg_idx.is_none(); - let mut arg = mk_arg_type(ty, arg_idx); - if arg.layout.is_zst() { - // For some forsaken reason, x86_64-pc-windows-gnu - // doesn't ignore zero-sized struct arguments. - // The same is true for s390x-unknown-linux-gnu - // and sparc64-unknown-linux-gnu. - if is_return || rust_abi || (!win_x64_gnu && !linux_s390x && !linux_sparc64) { - arg.mode = PassMode::Ignore(IgnoreMode::Zst); - } - } - - // If this is a C-variadic function, this is not the return value, - // and there is one or more fixed arguments; ensure that the `VaList` - // is ignored as an argument. - if sig.c_variadic { - match (last_arg_idx, arg_idx) { - (Some(last_idx), Some(cur_idx)) if last_idx == cur_idx => { - let va_list_did = match cx.tcx.lang_items().va_list() { - Some(did) => did, - None => bug!("`va_list` lang item required for C-variadic functions"), - }; - match ty.sty { - ty::Adt(def, _) if def.did == va_list_did => { - // This is the "spoofed" `VaList`. Set the arguments mode - // so that it will be ignored. - arg.mode = PassMode::Ignore(IgnoreMode::CVarArgs); - }, - _ => (), - } - } - _ => {} - } - } - - // FIXME(eddyb) other ABIs don't have logic for scalar pairs. - if !is_return && rust_abi { - if let layout::Abi::ScalarPair(ref a, ref b) = arg.layout.abi { - let mut a_attrs = ArgAttributes::new(); - let mut b_attrs = ArgAttributes::new(); - adjust_for_rust_scalar(&mut a_attrs, - a, - arg.layout, - Size::ZERO, - false); - adjust_for_rust_scalar(&mut b_attrs, - b, - arg.layout, - a.value.size(cx).align_to(b.value.align(cx).abi), - false); - arg.mode = PassMode::Pair(a_attrs, b_attrs); - return arg; - } - } - - if let layout::Abi::Scalar(ref scalar) = arg.layout.abi { - if let PassMode::Direct(ref mut attrs) = arg.mode { - adjust_for_rust_scalar(attrs, - scalar, - arg.layout, - Size::ZERO, - is_return); - } - } - - arg - }; - - let mut fn_ty = FnType { - ret: arg_of(sig.output(), None), - args: inputs.iter().cloned().chain(extra_args).enumerate().map(|(i, ty)| { - arg_of(ty, Some(i)) - }).collect(), - c_variadic: sig.c_variadic, - conv, - }; - FnTypeExt::adjust_for_abi(&mut fn_ty, cx, sig.abi); - fn_ty - } - - fn adjust_for_abi(&mut self, - cx: &CodegenCx<'ll, 'tcx>, - abi: Abi) { - if abi == Abi::Unadjusted { return } - - if abi == Abi::Rust || abi == Abi::RustCall || - abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic { - let fixup = |arg: &mut ArgType<'tcx, Ty<'tcx>>| { - if arg.is_ignore() { return; } - - match arg.layout.abi { - layout::Abi::Aggregate { .. } => {} - - // This is a fun case! The gist of what this is doing is - // that we want callers and callees to always agree on the - // ABI of how they pass SIMD arguments. If we were to *not* - // make these arguments indirect then they'd be immediates - // in LLVM, which means that they'd used whatever the - // appropriate ABI is for the callee and the caller. That - // means, for example, if the caller doesn't have AVX - // enabled but the callee does, then passing an AVX argument - // across this boundary would cause corrupt data to show up. - // - // This problem is fixed by unconditionally passing SIMD - // arguments through memory between callers and callees - // which should get them all to agree on ABI regardless of - // target feature sets. Some more information about this - // issue can be found in #44367. - // - // Note that the platform intrinsic ABI is exempt here as - // that's how we connect up to LLVM and it's unstable - // anyway, we control all calls to it in libstd. - layout::Abi::Vector { .. } - if abi != Abi::PlatformIntrinsic && - cx.sess().target.target.options.simd_types_indirect => - { - arg.make_indirect(); - return - } - - _ => return - } - - let size = arg.layout.size; - if arg.layout.is_unsized() || size > layout::Pointer.size(cx) { - arg.make_indirect(); - } else { - // We want to pass small aggregates as immediates, but using - // a LLVM aggregate type for this leads to bad optimizations, - // so we pick an appropriately sized integer type instead. - arg.cast_to(Reg { - kind: RegKind::Integer, - size - }); - } - }; - fixup(&mut self.ret); - for arg in &mut self.args { - fixup(arg); - } - if let PassMode::Indirect(ref mut attrs, _) = self.ret.mode { - attrs.set(ArgAttribute::StructRet); - } - return; - } - - if let Err(msg) = self.adjust_for_cabi(cx, abi) { - cx.sess().fatal(&msg); - } - } - +impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> { fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type { let args_capacity: usize = self.args.iter().map(|arg| if arg.pad.is_some() { 1 } else { 0 } + @@ -838,17 +473,17 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> { impl AbiMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn new_fn_type(&self, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> FnType<'tcx, Ty<'tcx>> { - FnTypeExt::new(&self, sig, extra_args) + FnType::new(self, sig, extra_args) } fn new_vtable( &self, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>] ) -> FnType<'tcx, Ty<'tcx>> { - FnTypeExt::new_vtable(&self, sig, extra_args) + FnType::new_vtable(self, sig, extra_args) } fn fn_type_of_instance(&self, instance: &Instance<'tcx>) -> FnType<'tcx, Ty<'tcx>> { - FnTypeExt::of_instance(&self, instance) + FnType::of_instance(self, instance) } } diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index 6b8a45da1803..89fdec076c6d 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -13,13 +13,13 @@ use crate::llvm; use crate::llvm::AttributePlace::Function; -use crate::abi::{FnType, FnTypeExt}; +use crate::abi::{FnType, FnTypeLlvmExt}; use crate::attributes; use crate::context::CodegenCx; use crate::type_::Type; use crate::value::Value; -use rustc::ty::{self, PolyFnSig, Ty}; -use rustc::ty::layout::{FnTypeExt as FnTypeExt1, LayoutOf}; +use rustc::ty::{self, PolyFnSig}; +use rustc::ty::layout::{FnTypeExt, LayoutOf}; use rustc::session::config::Sanitizer; use rustc_data_structures::small_c_str::SmallCStr; use rustc_codegen_ssa::traits::*; @@ -100,7 +100,7 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> { let sig = self.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); debug!("declare_rust_fn (after region erasure) sig={:?}", sig); - let fty: FnType<'tcx, Ty<'tcx>> = FnTypeExt1::new(self, sig, &[]); + let fty= FnType::new(self, sig, &[]); let llfn = declare_raw_fn(self, name, fty.llvm_cconv(), fty.llvm_type(self)); if self.layout_of(sig.output()).abi.is_uninhabited() { diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs index a5ed64a66a39..a3d3f0756a5f 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/src/librustc_codegen_llvm/type_.rs @@ -10,7 +10,7 @@ use rustc_codegen_ssa::traits::*; use crate::common; use crate::type_of::LayoutLlvmExt; -use crate::abi::{LlvmType, FnTypeExt}; +use crate::abi::{LlvmType, FnTypeLlvmExt}; use syntax::ast; use rustc::ty::Ty; use rustc::ty::layout::{self, Align, Size, TyLayout}; From 2adc6da7aa4f3f8cb646b8f7b7759e73c98ade12 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 14 May 2019 14:19:46 +0200 Subject: [PATCH 143/239] Fix incremental compilation of cdylib emitting spurious unused_attributes lint --- src/libsyntax/feature_gate.rs | 2 +- src/test/incremental/no_mangle.rs | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 src/test/incremental/no_mangle.rs diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 8a066f3f4a09..5b1a9bb739ff 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -998,7 +998,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ (sym::repr, Normal, template!(List: "C, packed, ..."), Ungated), (sym::path, Normal, template!(NameValueStr: "file"), Ungated), (sym::automatically_derived, Normal, template!(Word), Ungated), - (sym::no_mangle, Normal, template!(Word), Ungated), + (sym::no_mangle, Whitelisted, template!(Word), Ungated), (sym::no_link, Normal, template!(Word), Ungated), (sym::derive, Normal, template!(List: "Trait1, Trait2, ..."), Ungated), ( diff --git a/src/test/incremental/no_mangle.rs b/src/test/incremental/no_mangle.rs new file mode 100644 index 000000000000..1b17886a4f9b --- /dev/null +++ b/src/test/incremental/no_mangle.rs @@ -0,0 +1,10 @@ +// revisions:rpass1 rpass2 +// compile-flags: --crate-type cdylib +// skip-codegen + +#![deny(unused_attributes)] + +#[no_mangle] +pub extern "C" fn rust_no_mangle() -> i32 { + 42 +} From 180b859b265679cce46dac331b4b4bac47a0286d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 14 May 2019 14:28:32 +0200 Subject: [PATCH 144/239] Add comment to explain what is the top parameter --- src/librustdoc/html/render.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index a2e843828f7a..082dd7147528 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3789,6 +3789,14 @@ const ATTRIBUTE_WHITELIST: &'static [&'static str] = &[ "non_exhaustive" ]; +// The `top` parameter is used when generating the item declaration to ensure it doesn't have a +// left padding. For example: +// +// #[foo] <----- "top" attribute +// struct Foo { +// #[bar] <---- not "top" attribute +// bar: usize, +// } fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item, top: bool) -> fmt::Result { let mut attrs = String::new(); From e92d13ea2e84586ce17790946ae4241777a9778f Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 14 May 2019 15:46:43 +0200 Subject: [PATCH 145/239] Update ui tests --- .../ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs | 2 +- .../feature-gate/issue-43106-gating-of-builtin-attrs.stderr | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs index 0129a3f72b24..ca0a432d3396 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs @@ -52,7 +52,7 @@ //~^ WARN unused attribute #![path = "3800"] //~ WARN unused attribute #![automatically_derived] //~ WARN unused attribute -#![no_mangle] //~ WARN unused attribute +#![no_mangle] #![no_link] //~ WARN unused attribute // see issue-43106-gating-of-derive.rs #![should_panic] //~ WARN unused attribute diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index dcbe13a749f6..c7081205e148 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -1152,12 +1152,6 @@ warning: unused attribute LL | #![automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:55:1 - | -LL | #![no_mangle] - | ^^^^^^^^^^^^^ - warning: unused attribute --> $DIR/issue-43106-gating-of-builtin-attrs.rs:56:1 | From 44eb607d7665f09967403a1999d99f4559be1c21 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Tue, 14 May 2019 21:23:01 +0530 Subject: [PATCH 146/239] removes `AbiMethods` --- src/librustc_codegen_llvm/abi.rs | 20 ++------------------ src/librustc_codegen_llvm/builder.rs | 7 +++++++ src/librustc_codegen_llvm/declare.rs | 2 +- src/librustc_codegen_ssa/mir/block.rs | 14 +++++++------- src/librustc_codegen_ssa/mir/mod.rs | 4 ++-- src/librustc_codegen_ssa/traits/abi.rs | 8 +------- src/librustc_codegen_ssa/traits/builder.rs | 2 ++ src/librustc_codegen_ssa/traits/mod.rs | 11 +++++++---- 8 files changed, 29 insertions(+), 39 deletions(-) diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 16e5695c8319..38d4b7e3f9d8 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -12,8 +12,8 @@ use rustc_target::abi::call::ArgType; use rustc_codegen_ssa::traits::*; use rustc_target::abi::{HasDataLayout, LayoutOf}; -use rustc::ty::{self, Ty, Instance}; -use rustc::ty::layout::{self, FnTypeExt}; +use rustc::ty::{Ty}; +use rustc::ty::layout::{self}; use libc::c_uint; @@ -471,22 +471,6 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> { } } -impl AbiMethods<'tcx> for CodegenCx<'ll, 'tcx> { - fn new_fn_type(&self, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> FnType<'tcx, Ty<'tcx>> { - FnType::new(self, sig, extra_args) - } - fn new_vtable( - &self, - sig: ty::FnSig<'tcx>, - extra_args: &[Ty<'tcx>] - ) -> FnType<'tcx, Ty<'tcx>> { - FnType::new_vtable(self, sig, extra_args) - } - fn fn_type_of_instance(&self, instance: &Instance<'tcx>) -> FnType<'tcx, Ty<'tcx>> { - FnType::of_instance(self, instance) - } -} - impl AbiBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { fn apply_attrs_callsite( &mut self, diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index bc2bb97a19e5..48808eea3045 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -18,6 +18,7 @@ use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::base::to_immediate; use rustc_codegen_ssa::mir::operand::{OperandValue, OperandRef}; use rustc_codegen_ssa::mir::place::PlaceRef; +use rustc_target::spec::{HasTargetSpec, Target}; use std::borrow::Cow; use std::ops::{Deref, Range}; use std::ptr; @@ -72,6 +73,12 @@ impl ty::layout::HasParamEnv<'tcx> for Builder<'_, '_, 'tcx> { } } +impl HasTargetSpec for Builder<'_, '_, 'tcx> { + fn target_spec(&self) -> &Target { + &self.cx.target_spec() + } +} + impl ty::layout::LayoutOf for Builder<'_, '_, 'tcx> { type Ty = Ty<'tcx>; type TyLayout = TyLayout<'tcx>; diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index 89fdec076c6d..bcb14b8899ec 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -100,7 +100,7 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> { let sig = self.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); debug!("declare_rust_fn (after region erasure) sig={:?}", sig); - let fty= FnType::new(self, sig, &[]); + let fty = FnType::new(self, sig, &[]); let llfn = declare_raw_fn(self, name, fty.llvm_cconv(), fty.llvm_type(self)); if self.layout_of(sig.output()).abi.is_uninhabited() { diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index e64c847db651..96b8558c1d2c 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -1,6 +1,6 @@ use rustc::middle::lang_items; use rustc::ty::{self, Ty, TypeFoldable}; -use rustc::ty::layout::{self, LayoutOf, HasTyCtxt}; +use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, FnTypeExt}; use rustc::mir::{self, Place, PlaceBase, Static, StaticKind}; use rustc::mir::interpret::InterpError; use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode}; @@ -334,14 +334,14 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ty::ParamEnv::reveal_all(), &sig, ); - let fn_ty = bx.new_vtable(sig, &[]); + let fn_ty = FnType::new_vtable(&bx, sig, &[]); let vtable = args[1]; args = &args[..1]; (meth::DESTRUCTOR.get_fn(&mut bx, vtable, &fn_ty), fn_ty) } _ => { (bx.get_fn(drop_fn), - bx.fn_type_of_instance(&drop_fn)) + FnType::of_instance(&bx, &drop_fn)) } }; helper.do_call(self, &mut bx, fn_ty, drop_fn, args, @@ -439,7 +439,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Obtain the panic entry point. let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item); let instance = ty::Instance::mono(bx.tcx(), def_id); - let fn_ty = bx.fn_type_of_instance(&instance); + let fn_ty = FnType::of_instance(&bx, &instance); let llfn = bx.get_fn(instance); // Codegen the actual panic invoke/call. @@ -518,7 +518,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let fn_ty = match def { Some(ty::InstanceDef::Virtual(..)) => { - bx.new_vtable(sig, &extra_args) + FnType::new_vtable(&bx, sig, &extra_args) } Some(ty::InstanceDef::DropGlue(_, None)) => { // Empty drop glue; a no-op. @@ -526,7 +526,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { helper.funclet_br(self, &mut bx, target); return; } - _ => bx.new_fn_type(sig, &extra_args) + _ => FnType::new(&bx, sig, &extra_args) }; // Emit a panic or a no-op for `panic_if_uninhabited`. @@ -556,7 +556,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let def_id = common::langcall(bx.tcx(), Some(span), "", lang_items::PanicFnLangItem); let instance = ty::Instance::mono(bx.tcx(), def_id); - let fn_ty = bx.fn_type_of_instance(&instance); + let fn_ty = FnType::of_instance(&bx, &instance); let llfn = bx.get_fn(instance); // Codegen the actual panic invoke/call. diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index fcf099235aa1..060d7d18625f 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -1,5 +1,5 @@ use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts}; -use rustc::ty::layout::{TyLayout, HasTyCtxt}; +use rustc::ty::layout::{TyLayout, HasTyCtxt, FnTypeExt}; use rustc::mir::{self, Mir}; use rustc::session::config::DebugInfo; use rustc_mir::monomorphize::Instance; @@ -202,7 +202,7 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( ) { assert!(!instance.substs.needs_infer()); - let fn_ty = cx.new_fn_type(sig, &[]); + let fn_ty = FnType::new(cx, sig, &[]); debug!("fn_ty: {:?}", fn_ty); let mut debug_context = cx.create_function_debug_context(instance, sig, llfn, mir); diff --git a/src/librustc_codegen_ssa/traits/abi.rs b/src/librustc_codegen_ssa/traits/abi.rs index a8fd4e1d2c7c..509255c37be7 100644 --- a/src/librustc_codegen_ssa/traits/abi.rs +++ b/src/librustc_codegen_ssa/traits/abi.rs @@ -1,13 +1,7 @@ use super::BackendTypes; -use rustc::ty::{FnSig, Instance, Ty}; +use rustc::ty::{Ty}; use rustc_target::abi::call::FnType; -pub trait AbiMethods<'tcx> { - fn new_fn_type(&self, sig: FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> FnType<'tcx, Ty<'tcx>>; - fn new_vtable(&self, sig: FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> FnType<'tcx, Ty<'tcx>>; - fn fn_type_of_instance(&self, instance: &Instance<'tcx>) -> FnType<'tcx, Ty<'tcx>>; -} - pub trait AbiBuilderMethods<'tcx>: BackendTypes { fn apply_attrs_callsite(&mut self, ty: &FnType<'tcx, Ty<'tcx>>, callsite: Self::Value); fn get_param(&self, index: usize) -> Self::Value; diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index a3f99cd869e2..0c4c4547a795 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -11,6 +11,7 @@ use crate::mir::place::PlaceRef; use crate::MemFlags; use rustc::ty::Ty; use rustc::ty::layout::{Align, Size, HasParamEnv}; +use rustc_target::spec::{HasTargetSpec}; use std::ops::Range; use std::iter::TrustedLen; @@ -30,6 +31,7 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: + AsmBuilderMethods<'tcx> + StaticBuilderMethods<'tcx> + HasParamEnv<'tcx> + + HasTargetSpec { fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Value, name: &'b str) -> Self; diff --git a/src/librustc_codegen_ssa/traits/mod.rs b/src/librustc_codegen_ssa/traits/mod.rs index c237cd8bd264..2bb619e79f5e 100644 --- a/src/librustc_codegen_ssa/traits/mod.rs +++ b/src/librustc_codegen_ssa/traits/mod.rs @@ -27,7 +27,7 @@ mod statics; mod type_; mod write; -pub use self::abi::{AbiBuilderMethods, AbiMethods}; +pub use self::abi::{AbiBuilderMethods}; pub use self::asm::{AsmBuilderMethods, AsmMethods}; pub use self::backend::{Backend, BackendTypes, ExtraBackendMethods}; pub use self::builder::{BuilderMethods, OverflowOp}; @@ -41,7 +41,8 @@ pub use self::type_::{ ArgTypeMethods, BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods, TypeMethods, }; pub use self::write::{ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods}; -use rustc::ty::layout::{HasParamEnv}; +use rustc::ty::layout::{HasParamEnv, HasTyCtxt}; +use rustc_target::spec::{HasTargetSpec}; use std::fmt; @@ -56,11 +57,12 @@ pub trait CodegenMethods<'tcx>: + ConstMethods<'tcx> + StaticMethods + DebugInfoMethods<'tcx> - + AbiMethods<'tcx> + DeclareMethods<'tcx> + AsmMethods<'tcx> + PreDefineMethods<'tcx> + HasParamEnv<'tcx> + + HasTyCtxt<'tcx> + + HasTargetSpec { } @@ -71,11 +73,12 @@ impl<'tcx, T> CodegenMethods<'tcx> for T where + ConstMethods<'tcx> + StaticMethods + DebugInfoMethods<'tcx> - + AbiMethods<'tcx> + DeclareMethods<'tcx> + AsmMethods<'tcx> + PreDefineMethods<'tcx> + HasParamEnv<'tcx> + + HasTyCtxt<'tcx> + + HasTargetSpec { } From 441ca638cc131074481436c146e3d3aee1be75df Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 14 May 2019 10:55:55 -0700 Subject: [PATCH 147/239] Update LLVM to fix assertion when compiling to wasm More details can be found in #60540! Closes #60540 --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index 84abffda0e03..eb38a1888d1d 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 84abffda0e03b03c62bdfc3cfeda1c2cf1f88c85 +Subproject commit eb38a1888d1d29b2d2c6b31428a5201cd8fba0ff From 7c564fcc2b0d978d89ace7e049a92504cb8ddc71 Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Sat, 4 May 2019 16:42:06 +0200 Subject: [PATCH 148/239] Updated RELEASES.md for 1.35.0 --- RELEASES.md | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 48bd13105bbe..c50e5b2236fe 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,100 @@ +Version 1.35.0 (2019-05-23) +========================== + +Language +-------- +- [`FnOnce`, `FnMut`, and the `Fn` traits are now implemented for `Box`, + `Box`, and `Box` respectively.][59500] +- [You can now coerce closures into unsafe function pointers.][59580] e.g. + ```rust + unsafe fn call_unsafe(func: unsafe fn()) { + func() + } + + pub fn main() { + unsafe { call_unsafe(|| {}); } + } + ``` + + +Compiler +-------- +- [Added the `armv6-unknown-freebsd-gnueabihf` and + `armv7-unknown-freebsd-gnueabihf` targets.][58080] +- [Added the `wasm32-unknown-wasi` target.][59464] + + +Libraries +--------- +- [`Thread` will now show its ID in `Debug` output.][59460] +- [`StdinLock`, `StdoutLock`, and `StderrLock` now implement `AsRawFd`.][59512] +- [`alloc::System` now implements `Default`.][59451] +- [Expanded `Debug` output (`{:#?}`) for structs now has a trailing comma on the + last field.][59076] +- [`char::{ToLowercase, ToUppercase}` now + implement `ExactSizeIterator`.][58778] +- [All `NonZero` numeric types now implement `FromStr`.][58717] +- [Removed the `Read` trait bounds + on the `BufReader::{get_ref, get_mut, into_inner}` methods.][58423] +- [You can now call the `dbg!` macro without any parameters to print the file + and line where it is called.][57847] +- [In place ASCII case conversions are now up to 4× faster.][59283] + e.g. `str::make_ascii_lowercase` +- [`hash_map::{OccupiedEntry, VacantEntry}` now implement `Sync` + and `Send`.][58369] + +Stabilized APIs +--------------- +- [`f32::copysign`] +- [`f64::copysign`] +- [`RefCell::replace_with`] +- [`RefCell::map_split`] +- [`ptr::hash`] +- [`Range::contains`] +- [`RangeFrom::contains`] +- [`RangeTo::contains`] +- [`RangeInclusive::contains`] +- [`RangeToInclusive::contains`] +- [`Option::copied`] + +Cargo +----- +- [You can now set `cargo:rustc-cdylib-link-arg` at build time to pass custom + linker arguments when building a `cdylib`.][cargo/6298] Its usage is highly + platform specific. + +Misc +---- +- [The Rust toolchain is now available natively for musl based distros.][58575] + +[59460]: https://github.com/rust-lang/rust/pull/59460/ +[59464]: https://github.com/rust-lang/rust/pull/59464/ +[59500]: https://github.com/rust-lang/rust/pull/59500/ +[59512]: https://github.com/rust-lang/rust/pull/59512/ +[59580]: https://github.com/rust-lang/rust/pull/59580/ +[59283]: https://github.com/rust-lang/rust/pull/59283/ +[59451]: https://github.com/rust-lang/rust/pull/59451/ +[59076]: https://github.com/rust-lang/rust/pull/59076/ +[58778]: https://github.com/rust-lang/rust/pull/58778/ +[58717]: https://github.com/rust-lang/rust/pull/58717/ +[58369]: https://github.com/rust-lang/rust/pull/58369/ +[58423]: https://github.com/rust-lang/rust/pull/58423/ +[58080]: https://github.com/rust-lang/rust/pull/58080/ +[57847]: https://github.com/rust-lang/rust/pull/57847/ +[58575]: https://github.com/rust-lang/rust/pull/58575 +[cargo/6298]: https://github.com/rust-lang/cargo/pull/6298/ +[`f32::copysign`]: https://doc.rust-lang.org/stable/std/primitive.f32.html#method.copysign +[`f64::copysign`]: https://doc.rust-lang.org/stable/std/primitive.f64.html#method.copysign +[`RefCell::replace_with`]: https://doc.rust-lang.org/stable/std/cell/struct.RefCell.html#method.replace_with +[`RefCell::map_split`]: https://doc.rust-lang.org/stable/std/cell/struct.RefCell.html#method.map_split +[`ptr::hash`]: https://doc.rust-lang.org/stable/std/ptr/fn.hash.html +[`Range::contains`]: https://doc.rust-lang.org/std/ops/struct.Range.html#method.contains +[`RangeFrom::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeFrom.html#method.contains +[`RangeTo::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeTo.html#method.contains +[`RangeInclusive::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html#method.contains +[`RangeToInclusive::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeToInclusive.html#method.contains +[`Option::copied`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.copied + Version 1.34.2 (2019-05-14) =========================== From d1d819f797fd1a8c82246f6d7bf2d12e0b431d4c Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 14 May 2019 22:32:50 +0200 Subject: [PATCH 149/239] Add link to the 1.34.0 CVE --- RELEASES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index c50e5b2236fe..4185961187b3 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -99,9 +99,10 @@ Version 1.34.2 (2019-05-14) =========================== * [Destabilize the `Error::type_id` function due to a security - vulnerability][60785] + vulnerability][60785] ([CVE-2019-12083]) [60785]: https://github.com/rust-lang/rust/pull/60785 +[CVE-2019-12083]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12083 Version 1.34.1 (2019-04-25) =========================== From 3646b3c3d9f60c0632668943ca65beb259d035f9 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 14 May 2019 21:33:22 +0300 Subject: [PATCH 150/239] rustbuild/LLVM: Do not print installation messages for up-to-date files --- src/bootstrap/native.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 5777331b9bfd..da2e03a1a084 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -317,6 +317,10 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) { fn configure_cmake(builder: &Builder<'_>, target: Interned, cfg: &mut cmake::Config) { + // Do not print installation messages for up-to-date files. + // LLVM and LLD builds can produce a lot of those and hit CI limits on log size. + cfg.define("CMAKE_INSTALL_MESSAGE", "LAZY"); + if builder.config.ninja { cfg.generator("Ninja"); } From b5febe72bbe10e3a327fa983b06d64354a0954e0 Mon Sep 17 00:00:00 2001 From: chandde Date: Tue, 14 May 2019 17:00:48 -0700 Subject: [PATCH 151/239] Update lib.rs --- src/libtest/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 26612964c308..765ee12a1d67 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -37,12 +37,12 @@ extern crate libc; use term; // FIXME(#54291): rustc and/or LLVM don't yet support building with panic-unwind -// on aarch64-pc-windows-msvc, so we don't link libtest against +// on aarch64-pc-windows-msvc, or thumbv7a-pc-windows-msvc, so we don't link libtest against // libunwind (for the time being), even though it means that -// libtest won't be fully functional on this platform. +// libtest won't be fully functional on these platforms. // // See also: https://github.com/rust-lang/rust/issues/54190#issuecomment-422904437 -#[cfg(not(all(windows, target_arch = "aarch64")))] +#[cfg(not(any(all(windows, target_arch = "aarch64"), all(windows, target_arch = "arm"))))] extern crate panic_unwind; pub use self::ColorConfig::*; From 317daf77de8e3cc065982de7975647b4fb8fcc85 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sun, 28 Apr 2019 21:58:40 -0400 Subject: [PATCH 152/239] Do some simple constant propagation in the ConstProp pass --- src/librustc_mir/transform/const_prop.rs | 71 +++++++++++++++++++++--- 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 72af02782010..a6e01918529d 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -3,15 +3,17 @@ use rustc::hir::def::DefKind; use rustc::mir::{ - Constant, Location, Place, PlaceBase, Mir, Operand, Rvalue, Local, + AggregateKind, Constant, Location, Place, PlaceBase, Mir, Operand, Rvalue, Local, NullOp, UnOp, StatementKind, Statement, LocalKind, Static, StaticKind, TerminatorKind, Terminator, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem, SourceScope, SourceScopeLocalData, LocalDecl, Promoted, }; -use rustc::mir::visit::{Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext}; +use rustc::mir::visit::{ + Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext, +}; use rustc::mir::interpret::{InterpError, Scalar, GlobalId, EvalResult}; use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt}; -use syntax::source_map::DUMMY_SP; +use syntax_pos::{Span, DUMMY_SP}; use rustc::ty::subst::InternalSubsts; use rustc_data_structures::indexed_vec::IndexVec; use rustc::ty::layout::{ @@ -19,7 +21,7 @@ use rustc::ty::layout::{ HasTyCtxt, TargetDataLayout, HasDataLayout, }; -use crate::interpret::{InterpretCx, ScalarMaybeUndef, Immediate, OpTy, ImmTy, MemoryKind}; +use crate::interpret::{self, InterpretCx, ScalarMaybeUndef, Immediate, OpTy, ImmTy, MemoryKind}; use crate::const_eval::{ CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_eval_cx, }; @@ -497,6 +499,53 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { }, } } + + fn operand_from_scalar(&self, scalar: Scalar, ty: Ty<'tcx>, span: Span) -> Operand<'tcx> { + Operand::Constant(Box::new( + Constant { + span, + ty, + user_ty: None, + literal: self.tcx.mk_const(ty::Const::from_scalar( + scalar, + ty, + )) + } + )) + } + + fn replace_with_const(&self, rval: &mut Rvalue<'tcx>, value: Const<'tcx>, span: Span) { + self.ecx.validate_operand( + value, + vec![], + None, + true, + ).expect("value should already be a valid const"); + + if let interpret::Operand::Immediate(im) = *value { + match im { + interpret::Immediate::Scalar(ScalarMaybeUndef::Scalar(scalar)) => { + *rval = Rvalue::Use(self.operand_from_scalar(scalar, value.layout.ty, span)); + }, + Immediate::ScalarPair( + ScalarMaybeUndef::Scalar(one), + ScalarMaybeUndef::Scalar(two) + ) => { + let ty = &value.layout.ty.sty; + if let ty::Tuple(substs) = ty { + *rval = Rvalue::Aggregate( + Box::new(AggregateKind::Tuple), + vec![ + self.operand_from_scalar(one, substs[0].expect_ty(), span), + self.operand_from_scalar(two, substs[1].expect_ty(), span), + ], + ); + } + }, + _ => { } + } + } + } } fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -560,10 +609,10 @@ impl<'tcx> Visitor<'tcx> for CanConstProp { } } -impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> { +impl<'b, 'a, 'tcx> MutVisitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> { fn visit_constant( &mut self, - constant: &Constant<'tcx>, + constant: &mut Constant<'tcx>, location: Location, ) { trace!("visit_constant: {:?}", constant); @@ -573,11 +622,11 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> { fn visit_statement( &mut self, - statement: &Statement<'tcx>, + statement: &mut Statement<'tcx>, location: Location, ) { trace!("visit_statement: {:?}", statement); - if let StatementKind::Assign(ref place, ref rval) = statement.kind { + if let StatementKind::Assign(ref place, ref mut rval) = statement.kind { let place_ty: Ty<'tcx> = place .ty(&self.local_decls, self.tcx) .ty; @@ -589,6 +638,10 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> { trace!("storing {:?} to {:?}", value, local); assert!(self.places[local].is_none()); self.places[local] = Some(value); + + if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 3 { + self.replace_with_const(rval, value, statement.source_info.span); + } } } } @@ -599,7 +652,7 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> { fn visit_terminator( &mut self, - terminator: &Terminator<'tcx>, + terminator: &mut Terminator<'tcx>, location: Location, ) { self.super_terminator(terminator, location); From b1c4fb2c07b42d2f2ef0a2446e65a964f139862b Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Fri, 3 May 2019 21:58:16 -0400 Subject: [PATCH 153/239] Add some tests for constant propagation The results aren't ideal but they represent the current state. --- src/test/mir-opt/const_prop/array_index.rs | 33 +++++++++++++++++++ src/test/mir-opt/const_prop/checked_add.rs | 21 ++++++++++++ src/test/mir-opt/const_prop/slice_len.rs | 37 ++++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 src/test/mir-opt/const_prop/array_index.rs create mode 100644 src/test/mir-opt/const_prop/checked_add.rs create mode 100644 src/test/mir-opt/const_prop/slice_len.rs diff --git a/src/test/mir-opt/const_prop/array_index.rs b/src/test/mir-opt/const_prop/array_index.rs new file mode 100644 index 000000000000..4b97af68ff08 --- /dev/null +++ b/src/test/mir-opt/const_prop/array_index.rs @@ -0,0 +1,33 @@ +fn main() { + let x: u32 = [0, 1, 2, 3][2]; +} + +// END RUST SOURCE +// START rustc.main.ConstProp.before.mir +// bb0: { +// ... +// _2 = [const 0u32, const 1u32, const 2u32, const 3u32]; +// ... +// _3 = const 2usize; +// _4 = const 4usize; +// _5 = Lt(_3, _4); +// assert(move _5, "index out of bounds: the len is move _4 but the index is _3") -> bb1; +// } +// bb1: { +// _1 = _2[_3]; +// ... +// return; +// } +// END rustc.main.ConstProp.before.mir +// START rustc.main.ConstProp.after.mir +// bb0: { +// ... +// _5 = const true; +// assert(move _5, "index out of bounds: the len is move _4 but the index is _3") -> bb1; +// } +// bb1: { +// _1 = _2[_3]; +// ... +// return; +// } +// END rustc.main.ConstProp.after.mir diff --git a/src/test/mir-opt/const_prop/checked_add.rs b/src/test/mir-opt/const_prop/checked_add.rs new file mode 100644 index 000000000000..0718316307c5 --- /dev/null +++ b/src/test/mir-opt/const_prop/checked_add.rs @@ -0,0 +1,21 @@ +// compile-flags: -C overflow-checks=on + +fn main() { + let x: u32 = 1 + 1; +} + +// END RUST SOURCE +// START rustc.main.ConstProp.before.mir +// bb0: { +// ... +// _2 = CheckedAdd(const 1u32, const 1u32); +// assert(!move (_2.1: bool), "attempt to add with overflow") -> bb1; +// } +// END rustc.main.ConstProp.before.mir +// START rustc.main.ConstProp.after.mir +// bb0: { +// ... +// _2 = (const 2u32, const false); +// assert(!move (_2.1: bool), "attempt to add with overflow") -> bb1; +// } +// END rustc.main.ConstProp.after.mir diff --git a/src/test/mir-opt/const_prop/slice_len.rs b/src/test/mir-opt/const_prop/slice_len.rs new file mode 100644 index 000000000000..3435ca07f4cd --- /dev/null +++ b/src/test/mir-opt/const_prop/slice_len.rs @@ -0,0 +1,37 @@ +fn test() -> &'static [u32] { + &[1, 2] +} + +fn main() { + let x = test()[0]; +} + +// END RUST SOURCE +// START rustc.main.ConstProp.before.mir +// bb1: { +// ... +// _3 = const 0usize; +// _4 = Len((*_2)); +// _5 = Lt(_3, _4); +// assert(move _5, "index out of bounds: the len is move _4 but the index is _3") -> bb2; +// } +// bb2: { +// _1 = (*_2)[_3]; +// ... +// return; +// } +// END rustc.main.ConstProp.before.mir +// START rustc.main.ConstProp.after.mir +// bb0: { +// ... +// _3 = const 0usize; +// _4 = Len((*_2)); +// _5 = Lt(_3, _4); +// assert(move _5, "index out of bounds: the len is move _4 but the index is _3") -> bb2; +// } +// bb2: { +// _1 = (*_2)[_3]; +// ... +// return; +// } +// END rustc.main.ConstProp.after.mir From 45214edf9e46459010d9853fe370c9c1e2cd4f35 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Wed, 8 May 2019 06:42:41 -0400 Subject: [PATCH 154/239] Run const propagation at O2 --- src/librustc_mir/transform/const_prop.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index a6e01918529d..4e214c3c7253 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -639,7 +639,7 @@ impl<'b, 'a, 'tcx> MutVisitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> { assert!(self.places[local].is_none()); self.places[local] = Some(value); - if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 3 { + if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 { self.replace_with_const(rval, value, statement.source_info.span); } } From b17066dd5eaf3dabd403bd4caccfca193c7184db Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Wed, 15 May 2019 06:06:33 -0400 Subject: [PATCH 155/239] Add test to ensure const-prop fails gracefully --- .../const_prop/const_prop_fails_gracefully.rs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs new file mode 100644 index 000000000000..97d3abdcc6cb --- /dev/null +++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs @@ -0,0 +1,34 @@ +#[inline(never)] +fn read(_: usize) { } + +fn main() { + const FOO: &i32 = &1; + let x = FOO as *const i32 as usize; + read(x); +} + +// END RUST SOURCE +// START rustc.main.ConstProp.before.mir +// bb0: { +// ... +// _3 = _4; +// _2 = move _3 as *const i32 (Misc); +// ... +// _1 = move _2 as usize (Misc); +// ... +// _6 = _1; +// _5 = const read(move _6) -> bb1; +// } +// END rustc.main.ConstProp.before.mir +// START rustc.main.ConstProp.after.mir +// bb0: { +// ... +// _3 = _4; +// _2 = move _3 as *const i32 (Misc); +// ... +// _1 = move _2 as usize (Misc); +// ... +// _6 = _1; +// _5 = const read(move _6) -> bb1; +// } +// END rustc.main.ConstProp.after.mir From 65d09ea4682f4def84e890c9e42b5f24e6cc8443 Mon Sep 17 00:00:00 2001 From: Pulkit Goyal <7895pulkit@gmail.com> Date: Wed, 15 May 2019 16:22:39 +0300 Subject: [PATCH 156/239] Move `box` from the stable keyword to unstable keywords list Fixes #60849 --- src/libsyntax_pos/symbol.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index ec0ce4253fa2..c2a18c9df83b 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -30,7 +30,6 @@ symbols! { // Keywords that are used in stable Rust. As: "as", - Box: "box", Break: "break", Const: "const", Continue: "continue", @@ -69,6 +68,7 @@ symbols! { // Keywords that are used in unstable Rust or reserved for future use. Abstract: "abstract", Become: "become", + Box: "box", Do: "do", Final: "final", Macro: "macro", From 6d207f53a4ea28151233a49f3f52fd051d0d6d21 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 15 May 2019 21:24:18 +0200 Subject: [PATCH 157/239] Get ty from local_decls instead of using Place --- src/librustc_codegen_ssa/mir/analyze.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 8021d4b11d0c..06d7b6c78f14 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -243,9 +243,8 @@ impl<'mir, 'a: 'mir, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> } PlaceContext::MutatingUse(MutatingUseContext::Drop) => { - let ty = mir::Place::Base(mir::PlaceBase::Local(local)).ty(self.fx.mir, - self.fx.cx.tcx()); - let ty = self.fx.monomorphize(&ty.ty); + let ty = self.fx.mir.local_decls[local].ty; + let ty = self.fx.monomorphize(&ty); // Only need the place if we're actually dropping it. if self.fx.cx.type_needs_drop(ty) { From 66a3ce78b44faf317c6b3c69fc66b6a75f99743d Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 15 May 2019 15:56:47 -0700 Subject: [PATCH 158/239] Update books --- src/ci/docker/x86_64-gnu-tools/checktools.sh | 4 +++- src/doc/book | 2 +- src/doc/edition-guide | 2 +- src/doc/embedded-book | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/doc/rustc-guide | 2 +- 8 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index af0198705a2f..a0fe307cffcd 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -74,7 +74,9 @@ status_check() { check_dispatch $1 beta nomicon src/doc/nomicon check_dispatch $1 beta reference src/doc/reference check_dispatch $1 beta rust-by-example src/doc/rust-by-example - check_dispatch $1 beta edition-guide src/doc/edition-guide + # Temporarily disabled until + # https://github.com/rust-lang/rust/issues/60459 is fixed. + # check_dispatch $1 beta edition-guide src/doc/edition-guide check_dispatch $1 beta rls src/tools/rls check_dispatch $1 beta rustfmt src/tools/rustfmt check_dispatch $1 beta clippy-driver src/tools/clippy diff --git a/src/doc/book b/src/doc/book index db919bc6bb90..29fe982990e4 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit db919bc6bb9071566e9c4f05053672133eaac33e +Subproject commit 29fe982990e43b9367be0ff47abc82fb2123fd03 diff --git a/src/doc/edition-guide b/src/doc/edition-guide index c413d42a207b..581c6cccfaf9 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit c413d42a207bd082f801ec0137c31b71e4bfed4c +Subproject commit 581c6cccfaf995394ea9dcac362dc8e731c18558 diff --git a/src/doc/embedded-book b/src/doc/embedded-book index de3d55f521e6..9858872bd1b7 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit de3d55f521e657863df45260ebbca1b10527f662 +Subproject commit 9858872bd1b7dbba5ec27dc30d34eba00acd7ef9 diff --git a/src/doc/nomicon b/src/doc/nomicon index fb29b147be4d..c656171b749b 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit fb29b147be4d9a1f8e24aba753a7e1de537abf61 +Subproject commit c656171b749b7307f21371dd0d3278efee5573b8 diff --git a/src/doc/reference b/src/doc/reference index 2a2de9ce0959..862b669c3958 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 2a2de9ce095979978ad7b582daecf94e4070b916 +Subproject commit 862b669c395822bb0938781d74f860e5762ad4fb diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 1ff0f8e01883..811c697b232c 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 1ff0f8e018838a710ebc0cc1a7bf74ebe73ad9f1 +Subproject commit 811c697b232c611ed754d279ed20643a0c4096f6 diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide index 99e1b1d53656..3cb727b62b95 160000 --- a/src/doc/rustc-guide +++ b/src/doc/rustc-guide @@ -1 +1 @@ -Subproject commit 99e1b1d53656be08654df399fc200584aebb50e4 +Subproject commit 3cb727b62b953d59b4360d39aa68b6dc8f157655 From 6a09cfab0bf1770dfa4819f422e6bb9381c7d2e1 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 15 May 2019 22:27:39 -0700 Subject: [PATCH 159/239] Update cargo --- Cargo.lock | 128 ++++++++++-------- .../x86_64-gnu-tools/checkregression.py | 7 +- src/tools/cargo | 2 +- 3 files changed, 79 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4417c25abcb4..369c6c8ae474 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,6 +13,14 @@ dependencies = [ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "aho-corasick" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "alloc" version = "0.0.0" @@ -181,6 +189,14 @@ dependencies = [ "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "bstr" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bufstream" version = "0.1.4" @@ -246,7 +262,7 @@ dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "crates-io 0.25.0", - "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "curl 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)", "curl-sys 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)", @@ -261,7 +277,7 @@ dependencies = [ "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ignore 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ignore 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "im-rc 12.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "jobserver 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -373,7 +389,7 @@ dependencies = [ "compiletest_rs 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-workspace-hack 1.0.0", "rustc_tools_util 0.1.1", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -395,7 +411,7 @@ dependencies = [ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -465,7 +481,7 @@ dependencies = [ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustfix 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -484,7 +500,7 @@ dependencies = [ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustfix 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", @@ -551,13 +567,10 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.3.4" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -576,7 +589,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-epoch 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -600,7 +613,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -616,10 +629,11 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.6.2" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -747,7 +761,7 @@ version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -779,7 +793,7 @@ dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -791,7 +805,7 @@ dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1008,14 +1022,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "globset" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1032,7 +1046,7 @@ dependencies = [ "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1047,7 +1061,7 @@ dependencies = [ "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1133,19 +1147,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ignore" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "globset 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1469,7 +1483,7 @@ dependencies = [ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1972,7 +1986,7 @@ dependencies = [ "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "rusty-fork 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2180,12 +2194,12 @@ dependencies = [ [[package]] name = "regex" -version = "1.1.0" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2200,7 +2214,7 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.4" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2229,7 +2243,7 @@ dependencies = [ "cargo 0.37.0", "cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "clippy_lints 0.0.212", - "crossbeam-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2247,7 +2261,7 @@ dependencies = [ "racer 2.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "rls-analysis 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-blacklist 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rls-data 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3090,11 +3104,11 @@ dependencies = [ "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", - "ignore 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ignore 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-ap-rustc_target 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-ap-syntax 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-ap-syntax_pos 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3130,7 +3144,7 @@ name = "same-file" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3551,7 +3565,7 @@ dependencies = [ name = "tidy" version = "0.1.0" dependencies = [ - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3612,7 +3626,7 @@ name = "tokio-executor" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3656,7 +3670,7 @@ name = "tokio-reactor" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3702,9 +3716,9 @@ name = "tokio-threadpool" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3717,7 +3731,7 @@ name = "tokio-timer" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3790,7 +3804,7 @@ dependencies = [ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3955,7 +3969,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3984,7 +3998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi-util" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4001,7 +4015,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4037,6 +4051,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" "checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e" +"checksum aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c" "checksum ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4c682378117e4186a492b2252b9537990e1617f44aed9788b9a1149de45477" "checksum annotate-snippets 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e8bcdcd5b291ce85a78f2b9d082a8de9676c12b1840d386d67bc5eea6f9d2b4e" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" @@ -4053,6 +4068,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" "checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" +"checksum bstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "853b090ce0f45d0265902666bf88039ea3da825e33796716c511a1ec9c170036" "checksum bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8" "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" @@ -4079,13 +4095,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" "checksum crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192" -"checksum crossbeam-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5b2a9ea8f77c7f9efd317a8a5645f515d903a2d86ee14d2337a5facd1bd52c12" +"checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" "checksum crossbeam-epoch 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f10a4f8f409aaac4b16a5474fb233624238fcdeefb9ba50d5ea059aab63ba31c" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" -"checksum crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e07fc155212827475223f0bcfae57e945e694fc90950ddf3f6695bbfd5555c72" +"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" "checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4" "checksum curl 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)" = "a85f2f95f2bd277d316d1aa8a477687ab4a6942258c7db7c89c187534669979c" "checksum curl-sys 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)" = "9d91a0052d5b982887d8e829bee0faffc7218ea3c6ebd3d6c2c8f678a93c9a42" @@ -4129,7 +4145,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7339329bfa14a00223244311560d11f8f489b453fb90092af97f267a6090ab0" "checksum git2-curl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d58551e903ed7e2d6fe3a2f3c7efa3a784ec29b19d0fbb035aaf0497c183fbdd" "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" -"checksum globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4743617a7464bbda3c8aec8558ff2f9429047e025771037df561d383337ff865" +"checksum globset 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef4feaabe24a0a658fd9cf4a9acf6ed284f045c77df0f49020ba3245cfb7b454" "checksum handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d89ec99d1594f285d4590fc32bac5f75cdab383f1123d504d27862c644a807dd" "checksum handlebars 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d82e5750d8027a97b9640e3fefa66bbaf852a35228e1c90790efd13c4b09c166" "checksum hashbrown 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "570178d5e4952010d138b0f1d581271ff3a02406d990f887d1e87e3d6e43b0ac" @@ -4141,7 +4157,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4bac95d9aa0624e7b78187d6fb8ab012b41d9f6f54b1bcb61e61c4845f8357ec" -"checksum ignore 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ad03ca67dc12474ecd91fdb94d758cbd20cb4e7a78ebe831df26a9b7511e1162" +"checksum ignore 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8dc57fa12805f367736a38541ac1a9fc6a52812a0ca959b1d4d4b640a89eb002" "checksum im-rc 12.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9460397452f537fd51808056ff209f4c4c4c9d20d42ae952f517708726284972" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053" @@ -4247,9 +4263,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum redox_users 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "214a97e49be64fd2c86f568dd0cb2c757d2cc53de95b273b6ad0a1c908482f26" "checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" -"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f" +"checksum regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f0a0bcab2fd7d1d7c54fa9eae6f43eddeb9ce2e7352f8518a814a4f65d60c58" "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" -"checksum regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1" +"checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum rls-analysis 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d53d49a28f75da9d02790d9256fecf6c0481e0871374326023c7a33131295579" "checksum rls-blacklist 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ce1fdac03e138c4617ff87b194e1ff57a39bb985a044ccbd8673d30701e411" @@ -4363,7 +4379,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab" +"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/src/ci/docker/x86_64-gnu-tools/checkregression.py b/src/ci/docker/x86_64-gnu-tools/checkregression.py index 0cc0a6329e5b..8aa90319d661 100755 --- a/src/ci/docker/x86_64-gnu-tools/checkregression.py +++ b/src/ci/docker/x86_64-gnu-tools/checkregression.py @@ -21,7 +21,12 @@ if __name__ == '__main__': state = cur[os_name] new_state = toolstate.get(tool, '') if verb == 'regressed': - updated = new_state < state + if tool == 'rls': + # Temporary override until + # https://github.com/rust-lang/rust/issues/60848 is fixed. + updated = False + else: + updated = new_state < state elif verb == 'changed': updated = new_state != state else: diff --git a/src/tools/cargo b/src/tools/cargo index 759b6161a328..c4fcfb725b4b 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 759b6161a328db1d4863139e90875308ecd25a75 +Subproject commit c4fcfb725b4be00c72eb9cf30c7d8b095577c280 From 6f3c8cd481c24f7ec64164c6fef03f826a8a3e55 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 16 May 2019 12:11:32 -0700 Subject: [PATCH 160/239] Update clippy --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index ad3269c4b510..11194e3d050f 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit ad3269c4b510b94b7c0082f4bb341bee6ed1eca4 +Subproject commit 11194e3d050f45ff002a775f451ff6222fcd5b2c From 441ecb88e791cd156f1753a44c70d79f40315326 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 16 May 2019 22:22:18 +0200 Subject: [PATCH 161/239] Allow claiming issues with triagebot --- triagebot.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 6f60481600c2..0e703a3ab349 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -4,3 +4,5 @@ allow-unauthenticated = [ # I-* without I-nominated "I-compilemem", "I-compiletime", "I-crash", "I-hang", "I-ICE", "I-slow", ] + +[assign] From d763faf92198e3f0c851388c71d2bb8a2f04afd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 May 2019 19:47:18 -0700 Subject: [PATCH 162/239] Parse alternative incorrect uses of await and recover --- src/librustc/hir/lowering.rs | 19 +- src/libsyntax/parse/parser.rs | 113 +++++++++- ...018-edition-error-in-non-macro-position.rs | 4 +- ...edition-error-in-non-macro-position.stderr | 10 +- .../ui/await-keyword/2018-edition-error.rs | 4 +- .../await-keyword/2018-edition-error.stderr | 10 +- .../incorrect-syntax-suggestions.rs | 93 +++++++++ .../incorrect-syntax-suggestions.stderr | 196 ++++++++++++++++++ .../await-keyword/post_expansion_error.stderr | 4 +- src/test/ui/issues/issue-51719.rs | 2 + src/test/ui/issues/issue-51719.stderr | 5 +- src/test/ui/issues/issue-51751.stderr | 5 +- 12 files changed, 428 insertions(+), 37 deletions(-) create mode 100644 src/test/ui/await-keyword/incorrect-syntax-suggestions.rs create mode 100644 src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index dd0d13d8f5a6..12ccc79e4ab4 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -97,6 +97,10 @@ pub struct LoweringContext<'a> { is_generator: bool, is_async_body: bool, + /// Used to get the current `fn`'s def span to point to when using `await` + /// outside of an `async fn`. + current_item_id: Option, + catch_scopes: Vec, loop_scopes: Vec, is_in_loop_condition: bool, @@ -250,6 +254,7 @@ pub fn lower_crate( node_id_to_hir_id: IndexVec::new(), is_generator: false, is_async_body: false, + current_item_id: None, is_in_trait_impl: false, lifetimes_to_define: Vec::new(), is_collecting_in_band_lifetimes: false, @@ -3115,6 +3120,7 @@ impl<'a> LoweringContext<'a> { } ItemKind::Fn(ref decl, ref header, ref generics, ref body) => { let fn_def_id = self.resolver.definitions().local_def_id(id); + let hir_id = self.lower_node_id(id); self.with_new_scopes(|this| { let mut lower_fn = |decl: &FnDecl| { // Note: we don't need to change the return type from `T` to @@ -3153,6 +3159,7 @@ impl<'a> LoweringContext<'a> { } else { lower_fn(decl) }; + this.current_item_id = Some(hir_id); hir::ItemKind::Fn( fn_decl, @@ -5551,13 +5558,21 @@ impl<'a> LoweringContext<'a> { // } // } if !self.is_async_body { - span_err!( + let mut err = struct_span_err!( self.sess, await_span, E0728, "`await` is only allowed inside `async` functions and blocks" ); - self.sess.abort_if_errors(); + err.span_label(await_span, "only allowed inside `async` functions and blocks"); + if let Some(item_id) = self.current_item_id { + err.span_label( + self.sess.source_map().def_span(self.items[&item_id].span), + "this function is not `async`", + ); + } + err.emit(); + return hir::ExprKind::Err; } let span = self.sess.source_map().mark_span_with_reason( CompilerDesugaringKind::Await, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 99e8db9d8e6d..55e13ef00dcc 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2629,14 +2629,94 @@ impl<'a> Parser<'a> { db.note("variable declaration using `let` is a statement"); return Err(db); } else if self.span.rust_2018() && self.eat_keyword(keywords::Await) { - // FIXME: remove this branch when `await!` is no longer supported - // https://github.com/rust-lang/rust/issues/60610 - self.expect(&token::Not)?; - self.expect(&token::OpenDelim(token::Paren))?; - let expr = self.parse_expr()?; - self.expect(&token::CloseDelim(token::Paren))?; - hi = self.prev_span; - ex = ExprKind::Await(ast::AwaitOrigin::MacroLike, expr); + let await_sp = self.prev_span; + match self.token { + token::Not => { + // FIXME: make this an error when `await!` is no longer supported + // https://github.com/rust-lang/rust/issues/60610 + self.expect(&token::Not)?; + self.expect(&token::OpenDelim(token::Paren))?; + let expr = self.parse_expr().map_err(|mut err| { + err.span_label( + await_sp, + "while parsing this await macro call", + ); + err + })?; + self.expect(&token::CloseDelim(token::Paren))?; + ex = ExprKind::Await(ast::AwaitOrigin::MacroLike, expr); + } + token::Question => { + // Handle `await? ` + self.bump(); // `?` + let expr = self.parse_expr().map_err(|mut err| { + err.span_label( + await_sp, + "while parsing this incorrect await statement", + ); + err + })?; + let sp = lo.to(expr.span); + let expr_str = self.sess.source_map().span_to_snippet(expr.span) + .unwrap_or_else(|_| pprust::expr_to_string(&expr)); + let expr = self.mk_expr( + sp, + ExprKind::Await(ast::AwaitOrigin::FieldLike, expr), + ThinVec::new(), + ); + hi = sp; + ex = ExprKind::Try(expr); + let mut err = self.struct_span_err( + await_sp, + "incorrect use of `await`", + ); + err.span_suggestion( + sp, + "`await` is not a statement", + format!("{}.await?", expr_str), + Applicability::MachineApplicable, + ); + err.emit(); + } + ref t => { + // Handle `await ` + let expr = if t == &token::OpenDelim(token::Brace) { + // Handle `await { }` + // this needs to be handled separatedly from the next arm to avoid + // interpreting `await { }?` as `?.await` + self.parse_block_expr( + None, + self.span, + BlockCheckMode::Default, + ThinVec::new(), + ) + } else { + self.parse_expr() + }.map_err(|mut err| { + err.span_label( + await_sp, + "while parsing this incorrect await statement", + ); + err + })?; + let expr_str = self.sess.source_map().span_to_snippet(expr.span) + .unwrap_or_else(|_| pprust::expr_to_string(&expr)); + let sp = lo.to(expr.span); + hi = sp; + ex = ExprKind::Await(ast::AwaitOrigin::FieldLike, expr); + let mut err = self.struct_span_err( + await_sp, + "incorrect use of `await`", + ); + err.span_suggestion( + sp, + "`await` is not a statement", + format!("{}.await", expr_str), + Applicability::MachineApplicable, + ); + err.emit(); + } + } } else if self.token.is_path_start() { let path = self.parse_path(PathStyle::Expr)?; @@ -2913,6 +2993,23 @@ impl<'a> Parser<'a> { ExprKind::Await(ast::AwaitOrigin::FieldLike, self_arg), ThinVec::new(), ); + if self.token == token::OpenDelim(token::Paren) && + self.look_ahead(1, |t| t == &token::CloseDelim(token::Paren)) + { + // future.await() + let lo = self.span; + self.bump(); // ( + let sp = lo.to(self.span); + self.bump(); // ) + let mut err = self.struct_span_err(span, "incorrect use of `await`"); + err.span_suggestion( + sp, + "`await` is not a method call, remove the parentheses", + String::new(), + Applicability::MachineApplicable, + ); + err.emit() + } return Ok(await_expr); } let segment = self.parse_path_segment(PathStyle::Expr)?; diff --git a/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.rs b/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.rs index b2e8e4be1724..f59f1160e703 100644 --- a/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.rs +++ b/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.rs @@ -22,6 +22,4 @@ macro_rules! await { () => {} } -fn main() { - match await { await => () } //~ ERROR expected `!`, found `{` -} +fn main() {} diff --git a/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.stderr b/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.stderr index 076a31bd9ced..c4b82b29f027 100644 --- a/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.stderr +++ b/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.stderr @@ -68,13 +68,5 @@ help: you can escape reserved keywords to use them as identifiers LL | macro_rules! r#await { | ^^^^^^^ -error: expected `!`, found `{` - --> $DIR/2018-edition-error-in-non-macro-position.rs:26:17 - | -LL | match await { await => () } - | ----- ^ expected `!` - | | - | while parsing this match expression - -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors diff --git a/src/test/ui/await-keyword/2018-edition-error.rs b/src/test/ui/await-keyword/2018-edition-error.rs index e0b2962ce979..d85686968426 100644 --- a/src/test/ui/await-keyword/2018-edition-error.rs +++ b/src/test/ui/await-keyword/2018-edition-error.rs @@ -9,6 +9,4 @@ mod outer_mod { use self::outer_mod::await::await; //~ ERROR expected identifier //~^ ERROR expected identifier, found reserved keyword `await` -fn main() { - match await { await => () } //~ ERROR expected `!`, found `{` -} +fn main() {} diff --git a/src/test/ui/await-keyword/2018-edition-error.stderr b/src/test/ui/await-keyword/2018-edition-error.stderr index c8bf9b42ca54..8afe5c1a36b3 100644 --- a/src/test/ui/await-keyword/2018-edition-error.stderr +++ b/src/test/ui/await-keyword/2018-edition-error.stderr @@ -38,13 +38,5 @@ help: you can escape reserved keywords to use them as identifiers LL | use self::outer_mod::await::r#await; | ^^^^^^^ -error: expected `!`, found `{` - --> $DIR/2018-edition-error.rs:13:17 - | -LL | match await { await => () } - | ----- ^ expected `!` - | | - | while parsing this match expression - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors diff --git a/src/test/ui/await-keyword/incorrect-syntax-suggestions.rs b/src/test/ui/await-keyword/incorrect-syntax-suggestions.rs new file mode 100644 index 000000000000..ca3654d3c878 --- /dev/null +++ b/src/test/ui/await-keyword/incorrect-syntax-suggestions.rs @@ -0,0 +1,93 @@ +// edition:2018 + +#![feature(async_await)] + +async fn bar() -> Result<(), ()> { + Ok(()) +} + +async fn foo1() -> Result<(), ()> { + let _ = await bar(); //~ ERROR incorrect use of `await` + Ok(()) +} +async fn foo2() -> Result<(), ()> { + let _ = await? bar(); //~ ERROR incorrect use of `await` + Ok(()) +} +async fn foo3() -> Result<(), ()> { + let _ = await bar()?; //~ ERROR incorrect use of `await` + //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try` + Ok(()) +} +async fn foo21() -> Result<(), ()> { + let _ = await { bar() }; //~ ERROR incorrect use of `await` + Ok(()) +} +async fn foo22() -> Result<(), ()> { + let _ = await(bar()); //~ ERROR incorrect use of `await` + Ok(()) +} +async fn foo23() -> Result<(), ()> { + let _ = await { bar() }?; //~ ERROR incorrect use of `await` + Ok(()) +} +async fn foo4() -> Result<(), ()> { + let _ = (await bar())?; //~ ERROR incorrect use of `await` + Ok(()) +} +async fn foo5() -> Result<(), ()> { + let _ = bar().await(); //~ ERROR incorrect use of `await` + Ok(()) +} +async fn foo6() -> Result<(), ()> { + let _ = bar().await()?; //~ ERROR incorrect use of `await` + Ok(()) +} +async fn foo7() -> Result<(), ()> { + let _ = bar().await; // OK + Ok(()) +} +async fn foo8() -> Result<(), ()> { + let _ = bar().await?; // OK + Ok(()) +} +fn foo9() -> Result<(), ()> { + let _ = await bar(); //~ ERROR `await` is only allowed inside `async` functions and blocks + //~^ ERROR incorrect use of `await` + Ok(()) +} +fn foo10() -> Result<(), ()> { + let _ = await? bar(); //~ ERROR `await` is only allowed inside `async` functions and blocks + //~^ ERROR incorrect use of `await` + Ok(()) +} +fn foo11() -> Result<(), ()> { + let _ = await bar()?; //~ ERROR `await` is only allowed inside `async` functions and blocks + //~^ ERROR incorrect use of `await` + Ok(()) +} +fn foo12() -> Result<(), ()> { + let _ = (await bar())?; //~ ERROR `await` is only allowed inside `async` functions and blocks + //~^ ERROR incorrect use of `await` + Ok(()) +} +fn foo13() -> Result<(), ()> { + let _ = bar().await(); //~ ERROR `await` is only allowed inside `async` functions and blocks + //~^ ERROR incorrect use of `await` + Ok(()) +} +fn foo14() -> Result<(), ()> { + let _ = bar().await()?; //~ ERROR `await` is only allowed inside `async` functions and blocks + //~^ ERROR incorrect use of `await` + Ok(()) +} +fn foo15() -> Result<(), ()> { + let _ = bar().await; //~ ERROR `await` is only allowed inside `async` functions and blocks + Ok(()) +} +fn foo16() -> Result<(), ()> { + let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks + Ok(()) +} + +fn main() {} diff --git a/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr b/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr new file mode 100644 index 000000000000..f39ccfcc95c8 --- /dev/null +++ b/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr @@ -0,0 +1,196 @@ +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:10:13 + | +LL | let _ = await bar(); + | ^^^^^------ + | | + | help: `await` is not a statement: `bar().await` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:14:13 + | +LL | let _ = await? bar(); + | ^^^^^------- + | | + | help: `await` is not a statement: `bar().await?` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:18:13 + | +LL | let _ = await bar()?; + | ^^^^^------- + | | + | help: `await` is not a statement: `bar()?.await` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:23:13 + | +LL | let _ = await { bar() }; + | ^^^^^---------- + | | + | help: `await` is not a statement: `{ bar() }.await` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:27:13 + | +LL | let _ = await(bar()); + | ^^^^^------- + | | + | help: `await` is not a statement: `(bar()).await` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:31:13 + | +LL | let _ = await { bar() }?; + | ^^^^^---------- + | | + | help: `await` is not a statement: `{ bar() }.await` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:35:14 + | +LL | let _ = (await bar())?; + | ^^^^^------ + | | + | help: `await` is not a statement: `bar().await` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:39:13 + | +LL | let _ = bar().await(); + | ^^^^^^^^^^^-- help: `await` is not a method call, remove the parentheses + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:43:13 + | +LL | let _ = bar().await()?; + | ^^^^^^^^^^^-- help: `await` is not a method call, remove the parentheses + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:55:13 + | +LL | let _ = await bar(); + | ^^^^^------ + | | + | help: `await` is not a statement: `bar().await` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:60:13 + | +LL | let _ = await? bar(); + | ^^^^^------- + | | + | help: `await` is not a statement: `bar().await?` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:65:13 + | +LL | let _ = await bar()?; + | ^^^^^------- + | | + | help: `await` is not a statement: `bar()?.await` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:70:14 + | +LL | let _ = (await bar())?; + | ^^^^^------ + | | + | help: `await` is not a statement: `bar().await` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:75:13 + | +LL | let _ = bar().await(); + | ^^^^^^^^^^^-- help: `await` is not a method call, remove the parentheses + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:80:13 + | +LL | let _ = bar().await()?; + | ^^^^^^^^^^^-- help: `await` is not a method call, remove the parentheses + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/incorrect-syntax-suggestions.rs:55:13 + | +LL | async fn foo8() -> Result<(), ()> { + | --------------------------------- this function is not `async` +... +LL | let _ = await bar(); + | ^^^^^^^^^^^ only allowed inside `async` functions and blocks + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/incorrect-syntax-suggestions.rs:60:13 + | +LL | fn foo9() -> Result<(), ()> { + | --------------------------- this function is not `async` +... +LL | let _ = await? bar(); + | ^^^^^^^^^^^^ only allowed inside `async` functions and blocks + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/incorrect-syntax-suggestions.rs:65:13 + | +LL | fn foo10() -> Result<(), ()> { + | ---------------------------- this function is not `async` +... +LL | let _ = await bar()?; + | ^^^^^^^^^^^^ only allowed inside `async` functions and blocks + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/incorrect-syntax-suggestions.rs:70:14 + | +LL | fn foo11() -> Result<(), ()> { + | ---------------------------- this function is not `async` +... +LL | let _ = (await bar())?; + | ^^^^^^^^^^^ only allowed inside `async` functions and blocks + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/incorrect-syntax-suggestions.rs:75:13 + | +LL | fn foo12() -> Result<(), ()> { + | ---------------------------- this function is not `async` +... +LL | let _ = bar().await(); + | ^^^^^^^^^^^ only allowed inside `async` functions and blocks + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/incorrect-syntax-suggestions.rs:80:13 + | +LL | fn foo13() -> Result<(), ()> { + | ---------------------------- this function is not `async` +... +LL | let _ = bar().await()?; + | ^^^^^^^^^^^ only allowed inside `async` functions and blocks + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/incorrect-syntax-suggestions.rs:85:13 + | +LL | fn foo14() -> Result<(), ()> { + | ---------------------------- this function is not `async` +... +LL | let _ = bar().await; + | ^^^^^^^^^^^ only allowed inside `async` functions and blocks + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/incorrect-syntax-suggestions.rs:89:13 + | +LL | fn foo15() -> Result<(), ()> { + | ---------------------------- this function is not `async` +... +LL | let _ = bar().await?; + | ^^^^^^^^^^^ only allowed inside `async` functions and blocks + +error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try` + --> $DIR/incorrect-syntax-suggestions.rs:18:19 + | +LL | let _ = await bar()?; + | ^^^^^^ the `?` operator cannot be applied to type `impl std::future::Future` + | + = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future` + = note: required by `std::ops::Try::into_result` + +error: aborting due to 24 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/await-keyword/post_expansion_error.stderr b/src/test/ui/await-keyword/post_expansion_error.stderr index 0996c38b3b6c..4e525974c2c6 100644 --- a/src/test/ui/await-keyword/post_expansion_error.stderr +++ b/src/test/ui/await-keyword/post_expansion_error.stderr @@ -2,7 +2,9 @@ error: expected expression, found `)` --> $DIR/post_expansion_error.rs:8:12 | LL | await!() - | ^ expected expression + | ----- ^ expected expression + | | + | while parsing this await macro call error: aborting due to previous error diff --git a/src/test/ui/issues/issue-51719.rs b/src/test/ui/issues/issue-51719.rs index 2c02ac01142b..b2dbadebc7c1 100644 --- a/src/test/ui/issues/issue-51719.rs +++ b/src/test/ui/issues/issue-51719.rs @@ -9,3 +9,5 @@ async fn foo() {} fn make_generator() { let _gen = || foo.await; //~ ERROR `await` is only allowed inside `async` functions and blocks } + +fn main() {} \ No newline at end of file diff --git a/src/test/ui/issues/issue-51719.stderr b/src/test/ui/issues/issue-51719.stderr index 768909b66ec7..cb4a5e903708 100644 --- a/src/test/ui/issues/issue-51719.stderr +++ b/src/test/ui/issues/issue-51719.stderr @@ -1,8 +1,11 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/issue-51719.rs:10:19 | +LL | async fn foo() {} + | -------------- this function is not `async` +... LL | let _gen = || foo.await; - | ^^^^^^^^^ + | ^^^^^^^^^ only allowed inside `async` functions and blocks error: aborting due to previous error diff --git a/src/test/ui/issues/issue-51751.stderr b/src/test/ui/issues/issue-51751.stderr index 0c4cb034a938..842b99f16f25 100644 --- a/src/test/ui/issues/issue-51751.stderr +++ b/src/test/ui/issues/issue-51751.stderr @@ -1,8 +1,11 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/issue-51751.rs:11:20 | +LL | async fn inc(limit: i64) -> i64 { + | ------------------------------- this function is not `async` +... LL | let finished = result.await; - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ only allowed inside `async` functions and blocks error: aborting due to previous error From ee02661474abad0c91b8031c920904ab14f30c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 May 2019 19:59:56 -0700 Subject: [PATCH 163/239] Split parser logic to its own method --- src/libsyntax/parse/parser.rs | 183 ++++++++++++++++++---------------- 1 file changed, 96 insertions(+), 87 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 55e13ef00dcc..83bfd93d0664 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2630,93 +2630,9 @@ impl<'a> Parser<'a> { return Err(db); } else if self.span.rust_2018() && self.eat_keyword(keywords::Await) { let await_sp = self.prev_span; - match self.token { - token::Not => { - // FIXME: make this an error when `await!` is no longer supported - // https://github.com/rust-lang/rust/issues/60610 - self.expect(&token::Not)?; - self.expect(&token::OpenDelim(token::Paren))?; - let expr = self.parse_expr().map_err(|mut err| { - err.span_label( - await_sp, - "while parsing this await macro call", - ); - err - })?; - self.expect(&token::CloseDelim(token::Paren))?; - ex = ExprKind::Await(ast::AwaitOrigin::MacroLike, expr); - } - token::Question => { - // Handle `await? ` - self.bump(); // `?` - let expr = self.parse_expr().map_err(|mut err| { - err.span_label( - await_sp, - "while parsing this incorrect await statement", - ); - err - })?; - let sp = lo.to(expr.span); - let expr_str = self.sess.source_map().span_to_snippet(expr.span) - .unwrap_or_else(|_| pprust::expr_to_string(&expr)); - let expr = self.mk_expr( - sp, - ExprKind::Await(ast::AwaitOrigin::FieldLike, expr), - ThinVec::new(), - ); - hi = sp; - ex = ExprKind::Try(expr); - let mut err = self.struct_span_err( - await_sp, - "incorrect use of `await`", - ); - err.span_suggestion( - sp, - "`await` is not a statement", - format!("{}.await?", expr_str), - Applicability::MachineApplicable, - ); - err.emit(); - } - ref t => { - // Handle `await ` - let expr = if t == &token::OpenDelim(token::Brace) { - // Handle `await { }` - // this needs to be handled separatedly from the next arm to avoid - // interpreting `await { }?` as `?.await` - self.parse_block_expr( - None, - self.span, - BlockCheckMode::Default, - ThinVec::new(), - ) - } else { - self.parse_expr() - }.map_err(|mut err| { - err.span_label( - await_sp, - "while parsing this incorrect await statement", - ); - err - })?; - let expr_str = self.sess.source_map().span_to_snippet(expr.span) - .unwrap_or_else(|_| pprust::expr_to_string(&expr)); - let sp = lo.to(expr.span); - hi = sp; - ex = ExprKind::Await(ast::AwaitOrigin::FieldLike, expr); - let mut err = self.struct_span_err( - await_sp, - "incorrect use of `await`", - ); - err.span_suggestion( - sp, - "`await` is not a statement", - format!("{}.await", expr_str), - Applicability::MachineApplicable, - ); - err.emit(); - } - } + let e = self.parse_async_macro_or_stmt(lo, await_sp)?; + hi = e.0; + ex = e.1; } else if self.token.is_path_start() { let path = self.parse_path(PathStyle::Expr)?; @@ -2781,6 +2697,99 @@ impl<'a> Parser<'a> { self.maybe_recover_from_bad_qpath(expr, true) } + fn parse_async_macro_or_stmt( + &mut self, + lo: Span, + await_sp: Span, + ) -> PResult<'a, (Span, ExprKind)> { + Ok(match self.token { + token::Not => { + // Handle correct `await!()` + // FIXME: make this an error when `await!` is no longer supported + // https://github.com/rust-lang/rust/issues/60610 + self.expect(&token::Not)?; + self.expect(&token::OpenDelim(token::Paren))?; + let expr = self.parse_expr().map_err(|mut err| { + err.span_label( + await_sp, + "while parsing this await macro call", + ); + err + })?; + self.expect(&token::CloseDelim(token::Paren))?; + (expr.span, ExprKind::Await(ast::AwaitOrigin::MacroLike, expr)) + } + token::Question => { + // Handle `await? ` + self.bump(); // `?` + let expr = self.parse_expr().map_err(|mut err| { + err.span_label( + await_sp, + "while parsing this incorrect await statement", + ); + err + })?; + let sp = lo.to(expr.span); + let expr_str = self.sess.source_map().span_to_snippet(expr.span) + .unwrap_or_else(|_| pprust::expr_to_string(&expr)); + let expr = self.mk_expr( + sp, + ExprKind::Await(ast::AwaitOrigin::FieldLike, expr), + ThinVec::new(), + ); + let mut err = self.struct_span_err( + await_sp, + "incorrect use of `await`", + ); + err.span_suggestion( + sp, + "`await` is not a statement", + format!("{}.await?", expr_str), + Applicability::MachineApplicable, + ); + err.emit(); + (sp, ExprKind::Try(expr)) + } + ref t => { + // Handle `await ` + let expr = if t == &token::OpenDelim(token::Brace) { + // Handle `await { }` + // this needs to be handled separatedly from the next arm to avoid + // interpreting `await { }?` as `?.await` + self.parse_block_expr( + None, + self.span, + BlockCheckMode::Default, + ThinVec::new(), + ) + } else { + self.parse_expr() + }.map_err(|mut err| { + err.span_label( + await_sp, + "while parsing this incorrect await statement", + ); + err + })?; + let expr_str = self.sess.source_map().span_to_snippet(expr.span) + .unwrap_or_else(|_| pprust::expr_to_string(&expr)); + let sp = lo.to(expr.span); + let mut err = self.struct_span_err( + await_sp, + "incorrect use of `await`", + ); + err.span_suggestion( + sp, + "`await` is not a statement", + format!("{}.await", expr_str), + Applicability::MachineApplicable, + ); + err.emit(); + (sp, ExprKind::Await(ast::AwaitOrigin::FieldLike, expr)) + } + }) + } + fn maybe_parse_struct_expr( &mut self, lo: Span, From 01c6689604d671c5fa51671940f69833222194ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 May 2019 20:06:15 -0700 Subject: [PATCH 164/239] Simplify span usage for incorrect await --- src/libsyntax/parse/parser.rs | 6 +- .../incorrect-syntax-suggestions.stderr | 60 ++++++------------- src/test/ui/feature-gate/await-macro.stderr | 2 +- 3 files changed, 23 insertions(+), 45 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 83bfd93d0664..45081aadfd97 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2738,7 +2738,7 @@ impl<'a> Parser<'a> { ThinVec::new(), ); let mut err = self.struct_span_err( - await_sp, + sp, "incorrect use of `await`", ); err.span_suggestion( @@ -2775,7 +2775,7 @@ impl<'a> Parser<'a> { .unwrap_or_else(|_| pprust::expr_to_string(&expr)); let sp = lo.to(expr.span); let mut err = self.struct_span_err( - await_sp, + sp, "incorrect use of `await`", ); err.span_suggestion( @@ -3010,7 +3010,7 @@ impl<'a> Parser<'a> { self.bump(); // ( let sp = lo.to(self.span); self.bump(); // ) - let mut err = self.struct_span_err(span, "incorrect use of `await`"); + let mut err = self.struct_span_err(sp, "incorrect use of `await`"); err.span_suggestion( sp, "`await` is not a method call, remove the parentheses", diff --git a/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr b/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr index f39ccfcc95c8..2e2efedcf00a 100644 --- a/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr +++ b/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr @@ -2,113 +2,91 @@ error: incorrect use of `await` --> $DIR/incorrect-syntax-suggestions.rs:10:13 | LL | let _ = await bar(); - | ^^^^^------ - | | - | help: `await` is not a statement: `bar().await` + | ^^^^^^^^^^^ help: `await` is not a statement: `bar().await` error: incorrect use of `await` --> $DIR/incorrect-syntax-suggestions.rs:14:13 | LL | let _ = await? bar(); - | ^^^^^------- - | | - | help: `await` is not a statement: `bar().await?` + | ^^^^^^^^^^^^ help: `await` is not a statement: `bar().await?` error: incorrect use of `await` --> $DIR/incorrect-syntax-suggestions.rs:18:13 | LL | let _ = await bar()?; - | ^^^^^------- - | | - | help: `await` is not a statement: `bar()?.await` + | ^^^^^^^^^^^^ help: `await` is not a statement: `bar()?.await` error: incorrect use of `await` --> $DIR/incorrect-syntax-suggestions.rs:23:13 | LL | let _ = await { bar() }; - | ^^^^^---------- - | | - | help: `await` is not a statement: `{ bar() }.await` + | ^^^^^^^^^^^^^^^ help: `await` is not a statement: `{ bar() }.await` error: incorrect use of `await` --> $DIR/incorrect-syntax-suggestions.rs:27:13 | LL | let _ = await(bar()); - | ^^^^^------- - | | - | help: `await` is not a statement: `(bar()).await` + | ^^^^^^^^^^^^ help: `await` is not a statement: `(bar()).await` error: incorrect use of `await` --> $DIR/incorrect-syntax-suggestions.rs:31:13 | LL | let _ = await { bar() }?; - | ^^^^^---------- - | | - | help: `await` is not a statement: `{ bar() }.await` + | ^^^^^^^^^^^^^^^ help: `await` is not a statement: `{ bar() }.await` error: incorrect use of `await` --> $DIR/incorrect-syntax-suggestions.rs:35:14 | LL | let _ = (await bar())?; - | ^^^^^------ - | | - | help: `await` is not a statement: `bar().await` + | ^^^^^^^^^^^ help: `await` is not a statement: `bar().await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:39:13 + --> $DIR/incorrect-syntax-suggestions.rs:39:24 | LL | let _ = bar().await(); - | ^^^^^^^^^^^-- help: `await` is not a method call, remove the parentheses + | ^^ help: `await` is not a method call, remove the parentheses error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:43:13 + --> $DIR/incorrect-syntax-suggestions.rs:43:24 | LL | let _ = bar().await()?; - | ^^^^^^^^^^^-- help: `await` is not a method call, remove the parentheses + | ^^ help: `await` is not a method call, remove the parentheses error: incorrect use of `await` --> $DIR/incorrect-syntax-suggestions.rs:55:13 | LL | let _ = await bar(); - | ^^^^^------ - | | - | help: `await` is not a statement: `bar().await` + | ^^^^^^^^^^^ help: `await` is not a statement: `bar().await` error: incorrect use of `await` --> $DIR/incorrect-syntax-suggestions.rs:60:13 | LL | let _ = await? bar(); - | ^^^^^------- - | | - | help: `await` is not a statement: `bar().await?` + | ^^^^^^^^^^^^ help: `await` is not a statement: `bar().await?` error: incorrect use of `await` --> $DIR/incorrect-syntax-suggestions.rs:65:13 | LL | let _ = await bar()?; - | ^^^^^------- - | | - | help: `await` is not a statement: `bar()?.await` + | ^^^^^^^^^^^^ help: `await` is not a statement: `bar()?.await` error: incorrect use of `await` --> $DIR/incorrect-syntax-suggestions.rs:70:14 | LL | let _ = (await bar())?; - | ^^^^^------ - | | - | help: `await` is not a statement: `bar().await` + | ^^^^^^^^^^^ help: `await` is not a statement: `bar().await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:75:13 + --> $DIR/incorrect-syntax-suggestions.rs:75:24 | LL | let _ = bar().await(); - | ^^^^^^^^^^^-- help: `await` is not a method call, remove the parentheses + | ^^ help: `await` is not a method call, remove the parentheses error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:80:13 + --> $DIR/incorrect-syntax-suggestions.rs:80:24 | LL | let _ = bar().await()?; - | ^^^^^^^^^^^-- help: `await` is not a method call, remove the parentheses + | ^^ help: `await` is not a method call, remove the parentheses error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/incorrect-syntax-suggestions.rs:55:13 diff --git a/src/test/ui/feature-gate/await-macro.stderr b/src/test/ui/feature-gate/await-macro.stderr index 699a7a8886e8..57aab6800f7a 100644 --- a/src/test/ui/feature-gate/await-macro.stderr +++ b/src/test/ui/feature-gate/await-macro.stderr @@ -2,7 +2,7 @@ error[E0658]: `await!()` macro syntax is unstable, and will soon be remove --> $DIR/await-macro.rs:9:5 | LL | await!(bar()); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/50547 = help: add #![feature(await_macro)] to the crate attributes to enable From 91c36c40bdd68d928f9202077309ae48f575d187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 May 2019 20:37:50 -0700 Subject: [PATCH 165/239] tidy fix --- src/test/ui/issues/issue-51719.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/issues/issue-51719.rs b/src/test/ui/issues/issue-51719.rs index b2dbadebc7c1..5966edd0bf09 100644 --- a/src/test/ui/issues/issue-51719.rs +++ b/src/test/ui/issues/issue-51719.rs @@ -10,4 +10,4 @@ fn make_generator() { let _gen = || foo.await; //~ ERROR `await` is only allowed inside `async` functions and blocks } -fn main() {} \ No newline at end of file +fn main() {} From c61660500555c81d6049b7e7b5b502d1bd9df80f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 16 May 2019 13:17:40 -0700 Subject: [PATCH 166/239] Point at enclosing fn/closure when it's not async --- src/librustc/hir/lowering.rs | 16 +++-- .../incorrect-syntax-suggestions.rs | 14 +++++ .../incorrect-syntax-suggestions.stderr | 58 +++++++++++-------- src/test/ui/issues/issue-51719.stderr | 7 +-- src/test/ui/issues/issue-51751.stderr | 6 +- 5 files changed, 60 insertions(+), 41 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 12ccc79e4ab4..3a8b139236cc 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -99,7 +99,7 @@ pub struct LoweringContext<'a> { /// Used to get the current `fn`'s def span to point to when using `await` /// outside of an `async fn`. - current_item_id: Option, + current_item: Option, catch_scopes: Vec, loop_scopes: Vec, @@ -254,7 +254,7 @@ pub fn lower_crate( node_id_to_hir_id: IndexVec::new(), is_generator: false, is_async_body: false, - current_item_id: None, + current_item: None, is_in_trait_impl: false, lifetimes_to_define: Vec::new(), is_collecting_in_band_lifetimes: false, @@ -3120,8 +3120,8 @@ impl<'a> LoweringContext<'a> { } ItemKind::Fn(ref decl, ref header, ref generics, ref body) => { let fn_def_id = self.resolver.definitions().local_def_id(id); - let hir_id = self.lower_node_id(id); self.with_new_scopes(|this| { + this.current_item = Some(ident.span); let mut lower_fn = |decl: &FnDecl| { // Note: we don't need to change the return type from `T` to // `impl Future` here because lower_body @@ -3159,7 +3159,6 @@ impl<'a> LoweringContext<'a> { } else { lower_fn(decl) }; - this.current_item_id = Some(hir_id); hir::ItemKind::Fn( fn_decl, @@ -3661,6 +3660,7 @@ impl<'a> LoweringContext<'a> { } else { lower_method(sig) }; + self.current_item = Some(i.span); (generics, hir::ImplItemKind::Method(sig, body_id)) } @@ -4277,6 +4277,7 @@ impl<'a> LoweringContext<'a> { let fn_decl = self.lower_fn_decl(decl, None, false, None); self.with_new_scopes(|this| { + this.current_item = Some(fn_decl_span); let mut is_generator = false; let body_id = this.lower_body(Some(decl), |this| { let e = this.lower_expr(body); @@ -5565,11 +5566,8 @@ impl<'a> LoweringContext<'a> { "`await` is only allowed inside `async` functions and blocks" ); err.span_label(await_span, "only allowed inside `async` functions and blocks"); - if let Some(item_id) = self.current_item_id { - err.span_label( - self.sess.source_map().def_span(self.items[&item_id].span), - "this function is not `async`", - ); + if let Some(item_sp) = self.current_item { + err.span_label(item_sp, "this is not `async`"); } err.emit(); return hir::ExprKind::Err; diff --git a/src/test/ui/await-keyword/incorrect-syntax-suggestions.rs b/src/test/ui/await-keyword/incorrect-syntax-suggestions.rs index ca3654d3c878..6b615cc9ff98 100644 --- a/src/test/ui/await-keyword/incorrect-syntax-suggestions.rs +++ b/src/test/ui/await-keyword/incorrect-syntax-suggestions.rs @@ -89,5 +89,19 @@ fn foo16() -> Result<(), ()> { let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks Ok(()) } +fn foo24() -> Result<(), ()> { + fn foo() -> Result<(), ()> { + let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks + Ok(()) + } + foo() +} +fn foo25() -> Result<(), ()> { + let foo = || { + let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks + Ok(()) + }; + foo() +} fn main() {} diff --git a/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr b/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr index 2e2efedcf00a..5ea59d4bcee1 100644 --- a/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr +++ b/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr @@ -91,75 +91,83 @@ LL | let _ = bar().await()?; error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/incorrect-syntax-suggestions.rs:55:13 | -LL | async fn foo8() -> Result<(), ()> { - | --------------------------------- this function is not `async` -... +LL | fn foo9() -> Result<(), ()> { + | ---- this is not `async` LL | let _ = await bar(); | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/incorrect-syntax-suggestions.rs:60:13 | -LL | fn foo9() -> Result<(), ()> { - | --------------------------- this function is not `async` -... +LL | fn foo10() -> Result<(), ()> { + | ----- this is not `async` LL | let _ = await? bar(); | ^^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/incorrect-syntax-suggestions.rs:65:13 | -LL | fn foo10() -> Result<(), ()> { - | ---------------------------- this function is not `async` -... +LL | fn foo11() -> Result<(), ()> { + | ----- this is not `async` LL | let _ = await bar()?; | ^^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/incorrect-syntax-suggestions.rs:70:14 | -LL | fn foo11() -> Result<(), ()> { - | ---------------------------- this function is not `async` -... +LL | fn foo12() -> Result<(), ()> { + | ----- this is not `async` LL | let _ = (await bar())?; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/incorrect-syntax-suggestions.rs:75:13 | -LL | fn foo12() -> Result<(), ()> { - | ---------------------------- this function is not `async` -... +LL | fn foo13() -> Result<(), ()> { + | ----- this is not `async` LL | let _ = bar().await(); | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/incorrect-syntax-suggestions.rs:80:13 | -LL | fn foo13() -> Result<(), ()> { - | ---------------------------- this function is not `async` -... +LL | fn foo14() -> Result<(), ()> { + | ----- this is not `async` LL | let _ = bar().await()?; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/incorrect-syntax-suggestions.rs:85:13 | -LL | fn foo14() -> Result<(), ()> { - | ---------------------------- this function is not `async` -... +LL | fn foo15() -> Result<(), ()> { + | ----- this is not `async` LL | let _ = bar().await; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/incorrect-syntax-suggestions.rs:89:13 | -LL | fn foo15() -> Result<(), ()> { - | ---------------------------- this function is not `async` -... +LL | fn foo16() -> Result<(), ()> { + | ----- this is not `async` LL | let _ = bar().await?; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/incorrect-syntax-suggestions.rs:94:17 + | +LL | fn foo() -> Result<(), ()> { + | --- this is not `async` +LL | let _ = bar().await?; + | ^^^^^^^^^^^ only allowed inside `async` functions and blocks + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/incorrect-syntax-suggestions.rs:101:17 + | +LL | let foo = || { + | -- this is not `async` +LL | let _ = bar().await?; + | ^^^^^^^^^^^ only allowed inside `async` functions and blocks + error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try` --> $DIR/incorrect-syntax-suggestions.rs:18:19 | @@ -169,6 +177,6 @@ LL | let _ = await bar()?; = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future` = note: required by `std::ops::Try::into_result` -error: aborting due to 24 previous errors +error: aborting due to 26 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-51719.stderr b/src/test/ui/issues/issue-51719.stderr index cb4a5e903708..c06165b24468 100644 --- a/src/test/ui/issues/issue-51719.stderr +++ b/src/test/ui/issues/issue-51719.stderr @@ -1,11 +1,10 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/issue-51719.rs:10:19 | -LL | async fn foo() {} - | -------------- this function is not `async` -... LL | let _gen = || foo.await; - | ^^^^^^^^^ only allowed inside `async` functions and blocks + | -- ^^^^^^^^^ only allowed inside `async` functions and blocks + | | + | this is not `async` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-51751.stderr b/src/test/ui/issues/issue-51751.stderr index 842b99f16f25..97b63d1590ec 100644 --- a/src/test/ui/issues/issue-51751.stderr +++ b/src/test/ui/issues/issue-51751.stderr @@ -1,9 +1,9 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/issue-51751.rs:11:20 | -LL | async fn inc(limit: i64) -> i64 { - | ------------------------------- this function is not `async` -... +LL | fn main() { + | ---- this is not `async` +LL | let result = inc(10000); LL | let finished = result.await; | ^^^^^^^^^^^^ only allowed inside `async` functions and blocks From 0183a575f686003586ca3308db8a55d6224f4789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 16 May 2019 13:20:06 -0700 Subject: [PATCH 167/239] readd match await test case --- .../incorrect-syntax-suggestions.rs | 6 ++++- .../incorrect-syntax-suggestions.stderr | 27 ++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/test/ui/await-keyword/incorrect-syntax-suggestions.rs b/src/test/ui/await-keyword/incorrect-syntax-suggestions.rs index 6b615cc9ff98..e1e5bdd3d1b9 100644 --- a/src/test/ui/await-keyword/incorrect-syntax-suggestions.rs +++ b/src/test/ui/await-keyword/incorrect-syntax-suggestions.rs @@ -104,4 +104,8 @@ fn foo25() -> Result<(), ()> { foo() } -fn main() {} +fn main() { + match await { await => () } + //~^ ERROR expected expression, found `=>` + //~| ERROR incorrect use of `await` +} //~ ERROR expected one of `.`, `?`, `{`, or an operator, found `}` diff --git a/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr b/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr index 5ea59d4bcee1..bc7bd77479e4 100644 --- a/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr +++ b/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr @@ -88,6 +88,31 @@ error: incorrect use of `await` LL | let _ = bar().await()?; | ^^ help: `await` is not a method call, remove the parentheses +error: expected expression, found `=>` + --> $DIR/incorrect-syntax-suggestions.rs:108:25 + | +LL | match await { await => () } + | ----- ^^ expected expression + | | + | while parsing this incorrect await statement + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:108:11 + | +LL | match await { await => () } + | ^^^^^^^^^^^^^^^^^^^^^ help: `await` is not a statement: `{ await => () }.await` + +error: expected one of `.`, `?`, `{`, or an operator, found `}` + --> $DIR/incorrect-syntax-suggestions.rs:111:1 + | +LL | match await { await => () } + | ----- - expected one of `.`, `?`, `{`, or an operator here + | | + | while parsing this match expression +... +LL | } + | ^ unexpected token + error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/incorrect-syntax-suggestions.rs:55:13 | @@ -177,6 +202,6 @@ LL | let _ = await bar()?; = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future` = note: required by `std::ops::Try::into_result` -error: aborting due to 26 previous errors +error: aborting due to 29 previous errors For more information about this error, try `rustc --explain E0277`. From b9d6fe3ae96a7f1f478dc6baf29b8e4cff5ab865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 16 May 2019 13:33:26 -0700 Subject: [PATCH 168/239] Review comments - Change wording of suggestion - Move recovery logic to `diagnostics.rs` - Reduce ammount of code duplication --- src/libsyntax/parse/diagnostics.rs | 40 +++++- src/libsyntax/parse/parser.rs | 124 ++++-------------- .../incorrect-syntax-suggestions.stderr | 26 ++-- 3 files changed, 81 insertions(+), 109 deletions(-) diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index 32e1ee94f0df..61453e35095b 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -1,5 +1,5 @@ use crate::ast; -use crate::ast::{Expr, ExprKind, Item, ItemKind, Pat, PatKind, QSelf, Ty, TyKind}; +use crate::ast::{BlockCheckMode, Expr, ExprKind, Item, ItemKind, Pat, PatKind, QSelf, Ty, TyKind}; use crate::parse::parser::PathStyle; use crate::parse::token; use crate::parse::PResult; @@ -223,4 +223,42 @@ impl<'a> Parser<'a> { false } } + + /// Consume alternative await syntaxes like `await `, `await? `, `await()` + /// and `await { }`. + crate fn parse_incorrect_await_syntax( + &mut self, + lo: Span, + await_sp: Span, + ) -> PResult<'a, (Span, ExprKind)> { + let is_question = self.eat(&token::Question); // Handle `await? `. + let expr = if self.token == token::OpenDelim(token::Brace) { + // Handle `await { }`. + // This needs to be handled separatedly from the next arm to avoid + // interpreting `await { }?` as `?.await`. + self.parse_block_expr( + None, + self.span, + BlockCheckMode::Default, + ThinVec::new(), + ) + } else { + self.parse_expr() + }.map_err(|mut err| { + err.span_label(await_sp, "while parsing this incorrect await expression"); + err + })?; + let expr_str = self.sess.source_map().span_to_snippet(expr.span) + .unwrap_or_else(|_| pprust::expr_to_string(&expr)); + let suggestion = format!("{}.await{}", expr_str, if is_question { "?" } else { "" }); + let sp = lo.to(expr.span); + let app = match expr.node { + ExprKind::Try(_) => Applicability::MaybeIncorrect, // `await ?` + _ => Applicability::MachineApplicable, + }; + self.struct_span_err(sp, "incorrect use of `await`") + .span_suggestion(sp, "`await` is a postfix operation", suggestion, app) + .emit(); + Ok((sp, ExprKind::Await(ast::AwaitOrigin::FieldLike, expr))) + } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 45081aadfd97..bb0f9fa9502a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2629,10 +2629,9 @@ impl<'a> Parser<'a> { db.note("variable declaration using `let` is a statement"); return Err(db); } else if self.span.rust_2018() && self.eat_keyword(keywords::Await) { - let await_sp = self.prev_span; - let e = self.parse_async_macro_or_stmt(lo, await_sp)?; - hi = e.0; - ex = e.1; + let (await_hi, e_kind) = self.parse_await_macro_or_alt(lo, self.prev_span)?; + hi = await_hi; + ex = e_kind; } else if self.token.is_path_start() { let path = self.parse_path(PathStyle::Expr)?; @@ -2697,97 +2696,29 @@ impl<'a> Parser<'a> { self.maybe_recover_from_bad_qpath(expr, true) } - fn parse_async_macro_or_stmt( + /// Parse `await!()` calls, or alternatively recover from incorrect but reasonable + /// alternative syntaxes `await `, `await? `, `await()` and + /// `await { }`. + fn parse_await_macro_or_alt( &mut self, lo: Span, await_sp: Span, ) -> PResult<'a, (Span, ExprKind)> { - Ok(match self.token { - token::Not => { - // Handle correct `await!()` - // FIXME: make this an error when `await!` is no longer supported - // https://github.com/rust-lang/rust/issues/60610 - self.expect(&token::Not)?; - self.expect(&token::OpenDelim(token::Paren))?; - let expr = self.parse_expr().map_err(|mut err| { - err.span_label( - await_sp, - "while parsing this await macro call", - ); - err - })?; - self.expect(&token::CloseDelim(token::Paren))?; - (expr.span, ExprKind::Await(ast::AwaitOrigin::MacroLike, expr)) - } - token::Question => { - // Handle `await? ` - self.bump(); // `?` - let expr = self.parse_expr().map_err(|mut err| { - err.span_label( - await_sp, - "while parsing this incorrect await statement", - ); - err - })?; - let sp = lo.to(expr.span); - let expr_str = self.sess.source_map().span_to_snippet(expr.span) - .unwrap_or_else(|_| pprust::expr_to_string(&expr)); - let expr = self.mk_expr( - sp, - ExprKind::Await(ast::AwaitOrigin::FieldLike, expr), - ThinVec::new(), - ); - let mut err = self.struct_span_err( - sp, - "incorrect use of `await`", - ); - err.span_suggestion( - sp, - "`await` is not a statement", - format!("{}.await?", expr_str), - Applicability::MachineApplicable, - ); - err.emit(); - (sp, ExprKind::Try(expr)) - } - ref t => { - // Handle `await ` - let expr = if t == &token::OpenDelim(token::Brace) { - // Handle `await { }` - // this needs to be handled separatedly from the next arm to avoid - // interpreting `await { }?` as `?.await` - self.parse_block_expr( - None, - self.span, - BlockCheckMode::Default, - ThinVec::new(), - ) - } else { - self.parse_expr() - }.map_err(|mut err| { - err.span_label( - await_sp, - "while parsing this incorrect await statement", - ); - err - })?; - let expr_str = self.sess.source_map().span_to_snippet(expr.span) - .unwrap_or_else(|_| pprust::expr_to_string(&expr)); - let sp = lo.to(expr.span); - let mut err = self.struct_span_err( - sp, - "incorrect use of `await`", - ); - err.span_suggestion( - sp, - "`await` is not a statement", - format!("{}.await", expr_str), - Applicability::MachineApplicable, - ); - err.emit(); - (sp, ExprKind::Await(ast::AwaitOrigin::FieldLike, expr)) - } - }) + if self.token == token::Not { + // Handle correct `await!()`. + // FIXME: make this an error when `await!` is no longer supported + // https://github.com/rust-lang/rust/issues/60610 + self.expect(&token::Not)?; + self.expect(&token::OpenDelim(token::Paren))?; + let expr = self.parse_expr().map_err(|mut err| { + err.span_label(await_sp, "while parsing this await macro call"); + err + })?; + self.expect(&token::CloseDelim(token::Paren))?; + Ok((expr.span, ExprKind::Await(ast::AwaitOrigin::MacroLike, expr))) + } else { // Handle `await `. + self.parse_incorrect_await_syntax(lo, await_sp) + } } fn maybe_parse_struct_expr( @@ -2938,10 +2869,13 @@ impl<'a> Parser<'a> { } /// Parses a block or unsafe block. - fn parse_block_expr(&mut self, opt_label: Option