]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #87596 - jesyspa:issue-87318-hidden-whitespace, r=estebank
authorYuki Okushi <jtitor@2k36.org>
Fri, 30 Jul 2021 19:09:31 +0000 (04:09 +0900)
committerGitHub <noreply@github.com>
Fri, 30 Jul 2021 19:09:31 +0000 (04:09 +0900)
Add warning when whitespace is not skipped after an escaped newline

Fixes issue #87318, also simplifies issue #87319.

* Add support to the lexer to emit warnings as well as errors.
* Emit a warning when a string literal contains an escaped newline, but when (some of) the whitespace on the next line is not skipped due to it being non-ASCII.

56 files changed:
compiler/rustc_error_codes/src/error_codes/E0744.md
compiler/rustc_expand/src/mbe/macro_rules.rs
compiler/rustc_feature/src/active.rs
compiler/rustc_lint_defs/src/builtin.rs
compiler/rustc_llvm/build.rs
compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs
compiler/rustc_passes/src/check_const.rs
compiler/rustc_span/src/symbol.rs
compiler/rustc_typeck/src/check/cast.rs
compiler/rustc_typeck/src/check/method/prelude2021.rs
library/core/src/ptr/non_null.rs
library/std/src/macros.rs
src/test/ui/cast/issue-85586.rs [new file with mode: 0644]
src/test/ui/cast/issue-85586.stderr [new file with mode: 0644]
src/test/ui/consts/const-fn-error.rs
src/test/ui/consts/const-fn-error.stderr
src/test/ui/consts/const-for-feature-gate.rs [new file with mode: 0644]
src/test/ui/consts/const-for-feature-gate.stderr [new file with mode: 0644]
src/test/ui/consts/const-for.rs [new file with mode: 0644]
src/test/ui/consts/const-for.stderr [new file with mode: 0644]
src/test/ui/consts/const-try-feature-gate.rs [new file with mode: 0644]
src/test/ui/consts/const-try-feature-gate.stderr [new file with mode: 0644]
src/test/ui/consts/const-try.rs [new file with mode: 0644]
src/test/ui/consts/control-flow/loop.stderr
src/test/ui/consts/control-flow/try.stderr
src/test/ui/hygiene/auxiliary/intercrate.rs
src/test/ui/hygiene/hygienic-label-1.rs
src/test/ui/hygiene/hygienic-label-1.stderr
src/test/ui/hygiene/hygienic-label-3.rs
src/test/ui/hygiene/hygienic-label-3.stderr
src/test/ui/issues/issue-50582.stderr
src/test/ui/issues/issue-50585.stderr
src/test/ui/lint/semicolon-in-expressions-from-macros/allow-semicolon-in-expressions-from-macros.rs [deleted file]
src/test/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs [new file with mode: 0644]
src/test/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs [new file with mode: 0644]
src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs [new file with mode: 0644]
src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr [new file with mode: 0644]
src/test/ui/macros/macro-context.rs
src/test/ui/macros/macro-context.stderr
src/test/ui/macros/macro-in-expression-context.fixed
src/test/ui/macros/macro-in-expression-context.rs
src/test/ui/macros/macro-in-expression-context.stderr
src/test/ui/never_type/issue-52443.stderr
src/test/ui/prelude2021.rs [deleted file]
src/test/ui/proc-macro/nested-nonterminal-tokens.rs
src/test/ui/rfc-2632-const-trait-impl/hir-const-check.stderr
src/test/ui/rust-2021/future-prelude-collision-generic.fixed [new file with mode: 0644]
src/test/ui/rust-2021/future-prelude-collision-generic.rs [new file with mode: 0644]
src/test/ui/rust-2021/future-prelude-collision-generic.stderr [new file with mode: 0644]
src/test/ui/rust-2021/prelude2021.rs [new file with mode: 0644]
src/test/ui/suggestions/for-i-in-vec.fixed
src/test/ui/suggestions/for-i-in-vec.rs
src/test/ui/suggestions/for-i-in-vec.stderr
src/test/ui/suggestions/option-content-move.stderr
src/tools/clippy/tests/ui/needless_borrow_pat.rs
src/tools/clippy/tests/ui/ref_binding_to_reference.rs

index 45804ab266e286d03e32a7d3be60cce926674dae..9a8ef3b840dffc12aac7afd7cc994a9c1e662bf8 100644 (file)
@@ -2,25 +2,15 @@ An unsupported expression was used inside a const context.
 
 Erroneous code example:
 
-```compile_fail,E0744
+```compile_fail,edition2018,E0744
 const _: i32 = {
-    let mut x = 0;
-
-    for i in 0..4 { // error!
-        x += i;
-    }
+    async { 0 }.await
 };
 ```
 
-At the moment, `for` loops, `.await`, and the `Try` operator (`?`) are forbidden
-inside a `const`, `static`, or `const fn`.
+At the moment, `.await` is forbidden inside a `const`, `static`, or `const fn`.
 
 This may be allowed at some point in the future, but the implementation is not
-yet complete. See the tracking issues for [`async`] and [`?`] in `const fn`, and
-(to support `for` loops in `const fn`) the tracking issues for [`impl const
-Trait for Ty`] and [`&mut T`] in `const fn`.
+yet complete. See the tracking issue for [`async`] in `const fn`.
 
 [`async`]: https://github.com/rust-lang/rust/issues/69431
-[`?`]: https://github.com/rust-lang/rust/issues/74935
-[`impl const Trait for Ty`]: https://github.com/rust-lang/rust/issues/67792
-[`&mut T`]: https://github.com/rust-lang/rust/issues/57349
index b97593b92b35523d635aab358e5e60a6e507af99..9aee86c9e57ddec76967dae4e2276312e1b17ac1 100644 (file)
@@ -45,6 +45,8 @@
     lint_node_id: NodeId,
     is_trailing_mac: bool,
     arm_span: Span,
+    /// Whether or not this macro is defined in the current crate
+    is_local: bool,
 }
 
 crate fn annotate_err_with_kind(
@@ -124,6 +126,7 @@ impl<'a> ParserAnyMacro<'a> {
             lint_node_id,
             arm_span,
             is_trailing_mac,
+            is_local,
         } = *self;
         let snapshot = &mut parser.clone();
         let fragment = match parse_ast_fragment(parser, kind) {
@@ -138,13 +141,15 @@ impl<'a> ParserAnyMacro<'a> {
         // `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
         // but `m!()` is allowed in expression positions (cf. issue #34706).
         if kind == AstFragmentKind::Expr && parser.token == token::Semi {
-            parser.sess.buffer_lint_with_diagnostic(
-                SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
-                parser.token.span,
-                lint_node_id,
-                "trailing semicolon in macro used in expression position",
-                BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident),
-            );
+            if is_local {
+                parser.sess.buffer_lint_with_diagnostic(
+                    SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
+                    parser.token.span,
+                    lint_node_id,
+                    "trailing semicolon in macro used in expression position",
+                    BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident),
+                );
+            }
             parser.bump();
         }
 
@@ -162,6 +167,7 @@ struct MacroRulesMacroExpander {
     lhses: Vec<mbe::TokenTree>,
     rhses: Vec<mbe::TokenTree>,
     valid: bool,
+    is_local: bool,
 }
 
 impl TTMacroExpander for MacroRulesMacroExpander {
@@ -183,6 +189,7 @@ fn expand<'cx>(
             input,
             &self.lhses,
             &self.rhses,
+            self.is_local,
         )
     }
 }
@@ -210,6 +217,7 @@ fn generic_extension<'cx>(
     arg: TokenStream,
     lhses: &[mbe::TokenTree],
     rhses: &[mbe::TokenTree],
+    is_local: bool,
 ) -> Box<dyn MacResult + 'cx> {
     let sess = &cx.sess.parse_sess;
 
@@ -311,6 +319,7 @@ fn generic_extension<'cx>(
                     lint_node_id: cx.current_expansion.lint_node_id,
                     is_trailing_mac: cx.current_expansion.is_trailing_mac,
                     arm_span,
+                    is_local,
                 });
             }
             Failure(token, msg) => match best_failure {
@@ -544,6 +553,9 @@ pub fn compile_declarative_macro(
         lhses,
         rhses,
         valid,
+        // Macros defined in the current crate have a real node id,
+        // whereas macros from an external crate have a dummy id.
+        is_local: def.id != DUMMY_NODE_ID,
     }))
 }
 
index bf99d2988178d0d61ae9ca6a07081b2d3e4058a3..1ec9a0518b809d7c8c4376530209beee0cd0d534 100644 (file)
@@ -677,6 +677,12 @@ pub fn set(&self, features: &mut Features, span: Span) {
     /// Allows `#[derive(Default)]` and `#[default]` on enums.
     (active, derive_default_enum, "1.56.0", Some(86985), None),
 
+    /// Allows `for _ in _` loops in const contexts.
+    (active, const_for, "1.56.0", Some(87575), None),
+
+    /// Allows the `?` operator in const contexts.
+    (active, const_try, "1.56.0", Some(74935), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
index 5b1cd0bcb3ffe72b34ebeca9b8ae714e064f6c7c..7195c41eae92e7aacb32d08ad578f93c977f1dfb 100644 (file)
     /// [issue #79813]: https://github.com/rust-lang/rust/issues/79813
     /// [future-incompatible]: ../index.md#future-incompatible-lints
     pub SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
-    Allow,
+    Warn,
     "trailing semicolon in macro body used as expression",
     @future_incompatible = FutureIncompatibleInfo {
         reference: "issue #79813 <https://github.com/rust-lang/rust/issues/79813>",
index 452d1b19a18a84b18e861736f51505a437a0170a..964b7cace9cd4e45326377d62d7a0a0e1616808a 100644 (file)
@@ -182,7 +182,7 @@ fn main() {
     } else if target.contains("windows-gnu") {
         println!("cargo:rustc-link-lib=shell32");
         println!("cargo:rustc-link-lib=uuid");
-    } else if target.contains("netbsd") || target.contains("haiku") {
+    } else if target.contains("netbsd") || target.contains("haiku") || target.contains("darwin") {
         println!("cargo:rustc-link-lib=z");
     }
     cmd.args(&components);
index 3f87d9c7ac94811ebb95ba53e97bed6b7e8bfcea..2be23159bf563a5938e0fd70fa54eaa10ea0c556 100644 (file)
@@ -2,7 +2,8 @@
 use rustc_middle::mir::*;
 use rustc_middle::ty;
 use rustc_span::source_map::DesugaringKind;
-use rustc_span::{sym, Span};
+use rustc_span::{sym, Span, DUMMY_SP};
+use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions;
 
 use crate::borrow_check::diagnostics::UseSpans;
 use crate::borrow_check::prefixes::PrefixSet;
@@ -384,36 +385,44 @@ fn report_cannot_move_from_borrowed_content(
                 }
             }
         };
-        if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
-            let def_id = match *move_place.ty(self.body, self.infcx.tcx).ty.kind() {
-                ty::Adt(self_def, _) => self_def.did,
-                ty::Foreign(def_id)
-                | ty::FnDef(def_id, _)
-                | ty::Closure(def_id, _)
-                | ty::Generator(def_id, ..)
-                | ty::Opaque(def_id, _) => def_id,
-                _ => return err,
+        let ty = move_place.ty(self.body, self.infcx.tcx).ty;
+        let def_id = match *ty.kind() {
+            ty::Adt(self_def, _) => self_def.did,
+            ty::Foreign(def_id)
+            | ty::FnDef(def_id, _)
+            | ty::Closure(def_id, _)
+            | ty::Generator(def_id, ..)
+            | ty::Opaque(def_id, _) => def_id,
+            _ => return err,
+        };
+        let is_option = self.infcx.tcx.is_diagnostic_item(sym::option_type, def_id);
+        let is_result = self.infcx.tcx.is_diagnostic_item(sym::result_type, def_id);
+        if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) {
+            err.span_suggestion_verbose(
+                span.shrink_to_hi(),
+                &format!(
+                    "consider borrowing the `{}`'s content",
+                    if is_option { "Option" } else { "Result" }
+                ),
+                ".as_ref()".to_string(),
+                Applicability::MaybeIncorrect,
+            );
+        } else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_))) {
+            let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) {
+                Some(def_id) => type_known_to_meet_bound_modulo_regions(
+                    &self.infcx,
+                    self.param_env,
+                    self.infcx.tcx.mk_imm_ref(self.infcx.tcx.lifetimes.re_erased, ty),
+                    def_id,
+                    DUMMY_SP,
+                ),
+                _ => false,
             };
-            let is_option = self.infcx.tcx.is_diagnostic_item(sym::option_type, def_id);
-            let is_result = self.infcx.tcx.is_diagnostic_item(sym::result_type, def_id);
-            if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) {
-                err.span_suggestion(
-                    span,
-                    &format!(
-                        "consider borrowing the `{}`'s content",
-                        if is_option { "Option" } else { "Result" }
-                    ),
-                    format!("{}.as_ref()", snippet),
-                    Applicability::MaybeIncorrect,
-                );
-            } else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_)))
-                && self.infcx.tcx.is_diagnostic_item(sym::vec_type, def_id)
-            {
-                // FIXME: suggest for anything that implements `IntoIterator`.
-                err.span_suggestion(
-                    span,
-                    "consider iterating over a slice of the `Vec<_>`'s content",
-                    format!("&{}", snippet),
+            if suggest {
+                err.span_suggestion_verbose(
+                    span.shrink_to_lo(),
+                    &format!("consider iterating over a slice of the `{}`'s content", ty),
+                    "&".to_string(),
                     Applicability::MaybeIncorrect,
                 );
             }
index 6ee54cfe37f306cbbc9a18cdf1885ae8b7c668dc..f6a93f5e02d5fec22a87de5b695b34c4124c67e6 100644 (file)
@@ -40,13 +40,14 @@ fn required_feature_gates(self) -> Option<&'static [Symbol]> {
         use hir::MatchSource::*;
 
         let gates: &[_] = match self {
-            // A `for` loop's desugaring contains a call to `IntoIterator::into_iter`,
-            // so they are not yet allowed.
-            // Likewise, `?` desugars to a call to `Try::into_result`.
-            Self::Loop(ForLoop) | Self::Match(ForLoopDesugar | TryDesugar | AwaitDesugar) => {
+            Self::Match(AwaitDesugar) => {
                 return None;
             }
 
+            Self::Loop(ForLoop) | Self::Match(ForLoopDesugar) => &[sym::const_for],
+
+            Self::Match(TryDesugar) => &[sym::const_try],
+
             Self::Match(IfLetGuardDesugar) => bug!("`if let` guard outside a `match` expression"),
 
             // All other expressions are allowed.
index 114750d9b7b3aa4ad0a8d9ce55fec0500acfb1ae..295e53aba35421349818352a80629e6ab45e68c0 100644 (file)
         const_fn_transmute,
         const_fn_union,
         const_fn_unsize,
+        const_for,
         const_format_args,
         const_generic_defaults,
         const_generics,
         const_trait_bound_opt_out,
         const_trait_impl,
         const_transmute,
+        const_try,
         constant,
         constructor,
         contents,
index b3808eae1ad1155c10af372a76d9632562b005c6..181972e3e7bade679d581f9d78135f6b3e1b4bfb 100644 (file)
@@ -604,8 +604,8 @@ fn trivial_cast_lint(&self, fcx: &FnCtxt<'a, 'tcx>) {
     }
 
     pub fn check(mut self, fcx: &FnCtxt<'a, 'tcx>) {
-        self.expr_ty = fcx.structurally_resolved_type(self.span, self.expr_ty);
-        self.cast_ty = fcx.structurally_resolved_type(self.span, self.cast_ty);
+        self.expr_ty = fcx.structurally_resolved_type(self.expr.span, self.expr_ty);
+        self.cast_ty = fcx.structurally_resolved_type(self.cast_span, self.cast_ty);
 
         debug!("check_cast({}, {:?} as {:?})", self.expr.hir_id, self.expr_ty, self.cast_ty);
 
index f13e23914f7ab54b35a31737c680405943c000a4..6eb8af98640eb53f17bfbaf518bb03c1ac7348f3 100644 (file)
@@ -5,7 +5,7 @@
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_middle::ty::subst::InternalSubsts;
-use rustc_middle::ty::{Ref, Ty};
+use rustc_middle::ty::{Adt, Ref, Ty};
 use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
 use rustc_span::symbol::kw::Underscore;
 use rustc_span::symbol::{sym, Ident};
@@ -255,16 +255,31 @@ pub(super) fn lint_fully_qualified_call_from_2018(
                 method_name.name
             ));
 
-            let self_ty = self
+            let self_ty_name = self
                 .sess()
                 .source_map()
                 .span_to_snippet(self_ty_span)
                 .unwrap_or_else(|_| self_ty.to_string());
 
+            let self_ty_generics_count = match self_ty.kind() {
+                // Get the number of generics the self type has (if an Adt) unless we can determine that
+                // the user has written the self type with generics already which we (naively) do by looking
+                // for a "<" in `self_ty_name`.
+                Adt(def, _) if !self_ty_name.contains("<") => self.tcx.generics_of(def.did).count(),
+                _ => 0,
+            };
+            let self_ty_generics = if self_ty_generics_count > 0 {
+                format!("<{}>", vec!["_"; self_ty_generics_count].join(", "))
+            } else {
+                String::new()
+            };
             lint.span_suggestion(
                 span,
                 "disambiguate the associated function",
-                format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,),
+                format!(
+                    "<{}{} as {}>::{}",
+                    self_ty_name, self_ty_generics, trait_name, method_name.name,
+                ),
                 Applicability::MachineApplicable,
             );
 
index 3ab40f1faa1d6a2bad27b7dba6a02f5b7f8b4136..032df7f5a80ad8d82d52443d8e786116eb210701 100644 (file)
@@ -71,6 +71,16 @@ impl<T: Sized> NonNull<T> {
     /// a `T`, which means this must not be used as a "not yet initialized"
     /// sentinel value. Types that lazily allocate must track initialization by
     /// some other means.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let ptr = NonNull::<u32>::dangling();
+    /// // Important: don't try to access the value of `ptr` without
+    /// // initializing it first! The pointer is not null but isn't valid either!
+    /// ```
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[rustc_const_stable(feature = "const_nonnull_dangling", since = "1.36.0")]
     #[inline]
@@ -155,6 +165,18 @@ impl<T: ?Sized> NonNull<T> {
     /// # Safety
     ///
     /// `ptr` must be non-null.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let ptr = unsafe { NonNull::new_unchecked(&mut x as *mut _) };
+    ///
+    /// // NEVER DO THAT!!!
+    /// let ptr = unsafe { NonNull::<u32>::new_unchecked(std::ptr::null_mut()) };
+    /// ```
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[rustc_const_stable(feature = "const_nonnull_new_unchecked", since = "1.25.0")]
     #[inline]
@@ -164,6 +186,19 @@ impl<T: ?Sized> NonNull<T> {
     }
 
     /// Creates a new `NonNull` if `ptr` is non-null.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let ptr = NonNull::<u32>::new(&mut x as *mut _).expect("ptr is null!");
+    ///
+    /// if let Some(ptr) = NonNull::<u32>::new(std::ptr::null_mut()) {
+    ///     unreachable!();
+    /// }
+    /// ```
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[inline]
     pub fn new(ptr: *mut T) -> Option<Self> {
@@ -205,6 +240,22 @@ pub const fn to_raw_parts(self) -> (NonNull<()>, <T as super::Pointee>::Metadata
     }
 
     /// Acquires the underlying `*mut` pointer.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let ptr = NonNull::new(&mut x).expect("ptr is null!");
+    ///
+    /// let x_value = unsafe { *ptr.as_ptr() };
+    /// assert_eq!(x_value, 0);
+    ///
+    /// unsafe { *ptr.as_ptr() += 2; }
+    /// let x_value = unsafe { *ptr.as_ptr() };
+    /// assert_eq!(x_value, 2);
+    /// ```
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[rustc_const_stable(feature = "const_nonnull_as_ptr", since = "1.32.0")]
     #[inline]
@@ -239,6 +290,18 @@ pub const fn as_ptr(self) -> *mut T {
     /// (The part about being initialized is not yet fully decided, but until
     /// it is, the only safe approach is to ensure that they are indeed initialized.)
     ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let ptr = NonNull::new(&mut x as *mut _).expect("ptr is null!");
+    ///
+    /// let ref_x = unsafe { ptr.as_ref() };
+    /// println!("{}", ref_x);
+    /// ```
+    ///
     /// [the module documentation]: crate::ptr#safety
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[inline]
@@ -274,6 +337,19 @@ pub unsafe fn as_ref<'a>(&self) -> &'a T {
     /// This applies even if the result of this method is unused!
     /// (The part about being initialized is not yet fully decided, but until
     /// it is, the only safe approach is to ensure that they are indeed initialized.)
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let mut ptr = NonNull::new(&mut x).expect("null pointer");
+    ///
+    /// let x_ref = unsafe { ptr.as_mut() };
+    /// assert_eq!(*x_ref, 0);
+    /// *x_ref += 2;
+    /// assert_eq!(*x_ref, 2);
+    /// ```
     ///
     /// [the module documentation]: crate::ptr#safety
     #[stable(feature = "nonnull", since = "1.25.0")]
@@ -285,6 +361,18 @@ pub unsafe fn as_mut<'a>(&mut self) -> &'a mut T {
     }
 
     /// Casts to a pointer of another type.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let ptr = NonNull::new(&mut x as *mut _).expect("null pointer");
+    ///
+    /// let casted_ptr = ptr.cast::<i8>();
+    /// let raw_ptr: *mut i8 = casted_ptr.as_ptr();
+    /// ```
     #[stable(feature = "nonnull_cast", since = "1.27.0")]
     #[rustc_const_stable(feature = "const_nonnull_cast", since = "1.36.0")]
     #[inline]
index 7afe52a3fd693ccf2cec1d69901eb4ba3df56135..676695795badcdde278ed9f47f4a08bacb1e43d4 100644 (file)
@@ -290,7 +290,7 @@ macro_rules! dbg {
     // `$val` expression could be a block (`{ .. }`), in which case the `eprintln!`
     // will be malformed.
     () => {
-        $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!());
+        $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!())
     };
     ($val:expr $(,)?) => {
         // Use of `match` here is intentional because it affects the lifetimes
diff --git a/src/test/ui/cast/issue-85586.rs b/src/test/ui/cast/issue-85586.rs
new file mode 100644 (file)
index 0000000..7881658
--- /dev/null
@@ -0,0 +1,10 @@
+// Check that errors for unresolved types in cast expressions are reported
+// for the offending subexpression, not the whole cast expression.
+
+#![allow(unused_variables)]
+
+fn main() {
+    let a = [1, 2, 3].iter().sum();
+    let b = (a + 1) as usize;
+    //~^ ERROR: type annotations needed [E0282]
+}
diff --git a/src/test/ui/cast/issue-85586.stderr b/src/test/ui/cast/issue-85586.stderr
new file mode 100644 (file)
index 0000000..271885a
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0282]: type annotations needed
+  --> $DIR/issue-85586.rs:8:13
+   |
+LL |     let b = (a + 1) as usize;
+   |             ^^^^^^^ cannot infer type
+   |
+   = note: type must be known at this point
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
index b9c5a0e040ddc69ea1f687237ed979a7f829df35..948c162e8946d8c3a8a54d8ff6445b55727ebee5 100644 (file)
@@ -7,7 +7,7 @@ const fn f(x: usize) -> usize {
         //~| ERROR calls in constant functions
         //~| ERROR calls in constant functions
         //~| ERROR E0080
-        //~| ERROR E0744
+        //~| ERROR `for` is not allowed in a `const fn`
         sum += i;
     }
     sum
index f5e69bba4c5b7da4aae3ac74161b37234cc6fbee..df24585e5551ac0e0018d09f6d125428666685dd 100644 (file)
@@ -1,4 +1,4 @@
-error[E0744]: `for` is not allowed in a `const fn`
+error[E0658]: `for` is not allowed in a `const fn`
   --> $DIR/const-fn-error.rs:5:5
    |
 LL | /     for i in 0..x {
@@ -9,6 +9,9 @@ LL | |
 LL | |         sum += i;
 LL | |     }
    | |_____^
+   |
+   = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information
+   = help: add `#![feature(const_for)]` to the crate attributes to enable
 
 error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
   --> $DIR/const-fn-error.rs:5:14
@@ -45,5 +48,5 @@ LL |     let a : [i32; f(X)];
 
 error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0015, E0080, E0658, E0744.
+Some errors have detailed explanations: E0015, E0080, E0658.
 For more information about an error, try `rustc --explain E0015`.
diff --git a/src/test/ui/consts/const-for-feature-gate.rs b/src/test/ui/consts/const-for-feature-gate.rs
new file mode 100644 (file)
index 0000000..bec7b80
--- /dev/null
@@ -0,0 +1,8 @@
+// gate-test-const_for
+
+const _: () = {
+    for _ in 0..5 {}
+    //~^ error: `for` is not allowed in a `const`
+};
+
+fn main() {}
diff --git a/src/test/ui/consts/const-for-feature-gate.stderr b/src/test/ui/consts/const-for-feature-gate.stderr
new file mode 100644 (file)
index 0000000..2ea377e
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0658]: `for` is not allowed in a `const`
+  --> $DIR/const-for-feature-gate.rs:4:5
+   |
+LL |     for _ in 0..5 {}
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information
+   = help: add `#![feature(const_for)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/consts/const-for.rs b/src/test/ui/consts/const-for.rs
new file mode 100644 (file)
index 0000000..5fc1ee0
--- /dev/null
@@ -0,0 +1,10 @@
+#![feature(const_for)]
+#![feature(const_mut_refs)]
+
+const _: () = {
+    for _ in 0..5 {}
+    //~^ error: calls in constants are limited to
+    //~| error: calls in constants are limited to
+};
+
+fn main() {}
diff --git a/src/test/ui/consts/const-for.stderr b/src/test/ui/consts/const-for.stderr
new file mode 100644 (file)
index 0000000..a35c04b
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
+  --> $DIR/const-for.rs:5:14
+   |
+LL |     for _ in 0..5 {}
+   |              ^^^^
+
+error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
+  --> $DIR/const-for.rs:5:14
+   |
+LL |     for _ in 0..5 {}
+   |              ^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/src/test/ui/consts/const-try-feature-gate.rs b/src/test/ui/consts/const-try-feature-gate.rs
new file mode 100644 (file)
index 0000000..0839c23
--- /dev/null
@@ -0,0 +1,9 @@
+// gate-test-const_try
+
+const fn t() -> Option<()> {
+    Some(())?;
+    //~^ error: `?` is not allowed in a `const fn`
+    None
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/const-try-feature-gate.stderr b/src/test/ui/consts/const-try-feature-gate.stderr
new file mode 100644 (file)
index 0000000..cd1a063
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0658]: `?` is not allowed in a `const fn`
+  --> $DIR/const-try-feature-gate.rs:4:5
+   |
+LL |     Some(())?;
+   |     ^^^^^^^^^
+   |
+   = note: see issue #74935 <https://github.com/rust-lang/rust/issues/74935> for more information
+   = help: add `#![feature(const_try)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/consts/const-try.rs b/src/test/ui/consts/const-try.rs
new file mode 100644 (file)
index 0000000..e199fd9
--- /dev/null
@@ -0,0 +1,39 @@
+// check-pass
+
+// Demonstrates what's needed to make use of `?` in const contexts.
+
+#![crate_type = "lib"]
+#![feature(try_trait_v2)]
+#![feature(const_trait_impl)]
+#![feature(const_try)]
+
+use std::ops::{ControlFlow, FromResidual, Try};
+
+struct TryMe;
+struct Error;
+
+impl const FromResidual<Error> for TryMe {
+    fn from_residual(residual: Error) -> Self {
+        TryMe
+    }
+}
+
+impl const Try for TryMe {
+    type Output = ();
+    type Residual = Error;
+    fn from_output(output: Self::Output) -> Self {
+        TryMe
+    }
+    fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
+        ControlFlow::Break(Error)
+    }
+}
+
+const fn t() -> TryMe {
+    TryMe?;
+    TryMe
+}
+
+const _: () = {
+    t();
+};
index 7b99fa4fe4609c29f2fd9eb5386fb99287cfaf65..5f6ad8c105d7433cbc2781d9f97f9b10f3796150 100644 (file)
@@ -1,19 +1,25 @@
-error[E0744]: `for` is not allowed in a `const`
+error[E0658]: `for` is not allowed in a `const`
   --> $DIR/loop.rs:53:5
    |
 LL | /     for i in 0..4 {
 LL | |         x += i;
 LL | |     }
    | |_____^
+   |
+   = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information
+   = help: add `#![feature(const_for)]` to the crate attributes to enable
 
-error[E0744]: `for` is not allowed in a `const`
+error[E0658]: `for` is not allowed in a `const`
   --> $DIR/loop.rs:57:5
    |
 LL | /     for i in 0..4 {
 LL | |         x += i;
 LL | |     }
    | |_____^
+   |
+   = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information
+   = help: add `#![feature(const_for)]` to the crate attributes to enable
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0744`.
+For more information about this error, try `rustc --explain E0658`.
index 35075a3e60b98d3cba64200099064eecf64cbe6e..5aeec8fbf8665c18c5ef73f6a2d9213497918b6b 100644 (file)
@@ -1,9 +1,12 @@
-error[E0744]: `?` is not allowed in a `const fn`
+error[E0658]: `?` is not allowed in a `const fn`
   --> $DIR/try.rs:6:5
    |
 LL |     x?;
    |     ^^
+   |
+   = note: see issue #74935 <https://github.com/rust-lang/rust/issues/74935> for more information
+   = help: add `#![feature(const_try)]` to the crate attributes to enable
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0744`.
+For more information about this error, try `rustc --explain E0658`.
index 10d399ba54e7191fe9c879320811fce04348b044..0685358851edda9aae3c0bd6ef27ea867d9aff66 100644 (file)
@@ -5,7 +5,7 @@ pub mod foo {
     mod bar {
         fn f() -> u32 { 1 }
         pub macro m() {
-            f();
+            f()
         }
     }
 }
index 66361eec21a52b1d8b4bca007d3dcd4efe57b557..a06d9255ab5b0d598f9a0fbbc71e92fcc8561d69 100644 (file)
@@ -3,5 +3,5 @@ macro_rules! foo {
 }
 
 pub fn main() {
-    'x: loop { foo!() }
+    'x: loop { foo!(); }
 }
index 97a7240b9069b60329a5b341251d4b37e04c14a3..c1ed861836c1cea08f164c58a08b8c057c4be6d0 100644 (file)
@@ -4,8 +4,8 @@ error[E0426]: use of undeclared label `'x`
 LL |     () => { break 'x; }
    |                   ^^ undeclared label `'x`
 ...
-LL |     'x: loop { foo!() }
-   |                ------ in this macro invocation
+LL |     'x: loop { foo!(); }
+   |                ------- in this macro invocation
    |
    = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
index a81eb842259709f71e67e4c2353f18799a8e4c63..ab0559e1b6a8379adcbf912800bbe78fcf04ac32 100644 (file)
@@ -4,6 +4,6 @@ macro_rules! foo {
 
 pub fn main() {
     'x: for _ in 0..1 {
-        foo!()
+        foo!();
     };
 }
index 52840049f825aa52e6ed6167f83f72c2ab7e9849..29d1b67e09f9b88c137729b11efce84a4279a2d3 100644 (file)
@@ -4,8 +4,8 @@ error[E0426]: use of undeclared label `'x`
 LL |     () => { break 'x; }
    |                   ^^ undeclared label `'x`
 ...
-LL |         foo!()
-   |         ------ in this macro invocation
+LL |         foo!();
+   |         ------- in this macro invocation
    |
    = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
index 4f531460e69e23def023e40ae31f9502845581e0..465fb9baac3f03856a83a8fac4c523822312e92c 100644 (file)
@@ -1,8 +1,11 @@
-error[E0744]: `for` is not allowed in a `const`
+error[E0658]: `for` is not allowed in a `const`
   --> $DIR/issue-50582.rs:2:20
    |
 LL |     Vec::<[(); 1 + for x in 0..1 {}]>::new();
    |                    ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information
+   = help: add `#![feature(const_for)]` to the crate attributes to enable
 
 error[E0277]: cannot add `()` to `{integer}`
   --> $DIR/issue-50582.rs:2:18
@@ -14,5 +17,5 @@ LL |     Vec::<[(); 1 + for x in 0..1 {}]>::new();
 
 error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0277, E0744.
+Some errors have detailed explanations: E0277, E0658.
 For more information about an error, try `rustc --explain E0277`.
index c2630b664b55f22b6cd311e6a28b90fdb61155a3..e43cc20cbb57d2882e0c085cba16ebdc96d97819 100644 (file)
@@ -1,8 +1,11 @@
-error[E0744]: `for` is not allowed in a `const`
+error[E0658]: `for` is not allowed in a `const`
   --> $DIR/issue-50585.rs:2:18
    |
 LL |     |y: Vec<[(); for x in 0..2 {}]>| {};
    |                  ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information
+   = help: add `#![feature(const_for)]` to the crate attributes to enable
 
 error[E0308]: mismatched types
   --> $DIR/issue-50585.rs:2:18
@@ -12,5 +15,5 @@ LL |     |y: Vec<[(); for x in 0..2 {}]>| {};
 
 error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0308, E0744.
+Some errors have detailed explanations: E0308, E0658.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/allow-semicolon-in-expressions-from-macros.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/allow-semicolon-in-expressions-from-macros.rs
deleted file mode 100644 (file)
index 6f9e6ec..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// check-pass
-// Ensure that trailing semicolons are allowed by default
-
-macro_rules! foo {
-    () => {
-        true;
-    }
-}
-
-fn main() {
-    let val = match true {
-        true => false,
-        _ => foo!()
-    };
-}
diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs
new file mode 100644 (file)
index 0000000..781391c
--- /dev/null
@@ -0,0 +1,4 @@
+#[macro_export]
+macro_rules! my_macro {
+    () => { true; }
+}
diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs
new file mode 100644 (file)
index 0000000..3745063
--- /dev/null
@@ -0,0 +1,9 @@
+// aux-build:foreign-crate.rs
+// check-pass
+
+extern crate foreign_crate;
+
+// Test that we do not lint for a macro in a foreign crate
+fn main() {
+    let _ = foreign_crate::my_macro!();
+}
diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs
new file mode 100644 (file)
index 0000000..2c63311
--- /dev/null
@@ -0,0 +1,16 @@
+// check-pass
+// Ensure that trailing semicolons cause warnings by default
+
+macro_rules! foo {
+    () => {
+        true; //~  WARN trailing semicolon in macro
+              //~| WARN this was previously
+    }
+}
+
+fn main() {
+    let _val = match true {
+        true => false,
+        _ => foo!()
+    };
+}
diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr
new file mode 100644 (file)
index 0000000..d770a8c
--- /dev/null
@@ -0,0 +1,16 @@
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/warn-semicolon-in-expressions-from-macros.rs:6:13
+   |
+LL |         true;
+   |             ^
+...
+LL |         _ => foo!()
+   |              ------ in this macro invocation
+   |
+   = note: `#[warn(semicolon_in_expressions_from_macros)]` 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: 1 warning emitted
+
index 13e179578ad012d22f73348cc7d7b65692d960ab..d09fdf118e6f4e073683aa5d8cd9271e2d327551 100644 (file)
@@ -6,6 +6,8 @@ macro_rules! m {
                             //~| ERROR macro expansion ignores token `;`
                             //~| ERROR cannot find type `i` in this scope
                             //~| ERROR cannot find value `i` in this scope
+                            //~| WARN trailing semicolon in macro
+                            //~| WARN this was previously
 }
 
 fn main() {
index 5ed73b7fb93a3a57b79d7a3156742f0235636736..3b8a6f17491582a7df22c0881e91157b86e1600b 100644 (file)
@@ -64,7 +64,21 @@ LL |     let i = m!();
    |
    = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 6 previous errors
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/macro-context.rs:3:15
+   |
+LL |     () => ( i ; typeof );
+   |               ^
+...
+LL |     let i = m!();
+   |             ---- in this macro invocation
+   |
+   = note: `#[warn(semicolon_in_expressions_from_macros)]` 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 6 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0412, E0425.
 For more information about an error, try `rustc --explain E0412`.
index df36db0f49e72b6a46186e169bd7c34bc3a426db..f22caf2793fd5ef07f4ede88e0d819420b6f64d4 100644 (file)
@@ -3,6 +3,12 @@
 macro_rules! foo {
     () => {
         assert_eq!("A", "A");
+        //~^ WARN trailing semicolon in macro
+        //~| WARN this was previously
+        //~| NOTE macro invocations at the end of a block
+        //~| NOTE to ignore the value produced by the macro
+        //~| NOTE for more information
+        //~| NOTE `#[warn(semicolon_in_expressions_from_macros)]` on by default
         assert_eq!("B", "B");
     }
     //~^^ ERROR macro expansion ignores token `assert_eq` and any following
@@ -12,4 +18,10 @@ macro_rules! foo {
 fn main() {
     foo!();
     //~^ NOTE caused by the macro expansion here
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
 }
index b3f5e568967e8604a1ae0153575140d0e6113128..1a056e582ff4758b8298afabf202bfd5cc3a4081 100644 (file)
@@ -3,6 +3,12 @@
 macro_rules! foo {
     () => {
         assert_eq!("A", "A");
+        //~^ WARN trailing semicolon in macro
+        //~| WARN this was previously
+        //~| NOTE macro invocations at the end of a block
+        //~| NOTE to ignore the value produced by the macro
+        //~| NOTE for more information
+        //~| NOTE `#[warn(semicolon_in_expressions_from_macros)]` on by default
         assert_eq!("B", "B");
     }
     //~^^ ERROR macro expansion ignores token `assert_eq` and any following
@@ -12,4 +18,10 @@ macro_rules! foo {
 fn main() {
     foo!()
     //~^ NOTE caused by the macro expansion here
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
 }
index d27d6fbaef7a68fef3f963bf260ca75ba5a375a6..1840babd61dc2a79a7326fc4072123643ca5e397 100644 (file)
@@ -1,5 +1,5 @@
 error: macro expansion ignores token `assert_eq` and any following
-  --> $DIR/macro-in-expression-context.rs:6:9
+  --> $DIR/macro-in-expression-context.rs:12:9
    |
 LL |         assert_eq!("B", "B");
    |         ^^^^^^^^^
@@ -11,5 +11,21 @@ LL |     foo!()
    |
    = note: the usage of `foo!` is likely invalid in expression context
 
-error: aborting due to previous error
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/macro-in-expression-context.rs:5:29
+   |
+LL |         assert_eq!("A", "A");
+   |                             ^
+...
+LL |     foo!()
+   |     ------ in this macro invocation
+   |
+   = note: `#[warn(semicolon_in_expressions_from_macros)]` 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: macro invocations at the end of a block are treated as expressions
+   = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
+   = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error; 1 warning emitted
 
index 1683841e9d78137725b4e4ce37d9f37b2909cbb7..26ab5f43a27b8d55823aa6a989172e825c7a2a5e 100644 (file)
@@ -6,11 +6,14 @@ LL |     [(); {while true {break}; 0}];
    |
    = note: `#[warn(while_true)]` on by default
 
-error[E0744]: `for` is not allowed in a `const`
+error[E0658]: `for` is not allowed in a `const`
   --> $DIR/issue-52443.rs:9:12
    |
 LL |     [(); { for _ in 0usize.. {}; 0}];
    |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information
+   = help: add `#![feature(const_for)]` to the crate attributes to enable
 
 error[E0308]: mismatched types
   --> $DIR/issue-52443.rs:2:10
@@ -56,5 +59,5 @@ LL |     [(); { for _ in 0usize.. {}; 0}];
 
 error: aborting due to 6 previous errors; 1 warning emitted
 
-Some errors have detailed explanations: E0015, E0308, E0658, E0744.
+Some errors have detailed explanations: E0015, E0308, E0658.
 For more information about an error, try `rustc --explain E0015`.
diff --git a/src/test/ui/prelude2021.rs b/src/test/ui/prelude2021.rs
deleted file mode 100644 (file)
index 3a9fd69..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// check-pass
-// edition:2021
-// compile-flags: -Zunstable-options
-
-fn main() {
-    let _: u16 = 123i32.try_into().unwrap();
-}
index 2f5af10a40ac2cc1e0101ab3b9fa661fe0a41fb4..04d34e21cdc74b1bc78999de1f015c50e7bb3988 100644 (file)
@@ -17,7 +17,7 @@ macro_rules! wrap {
     (first, $e:expr) => { wrap!(second, $e + 1) };
     (second, $e:expr) => { wrap!(third, $e + 2) };
     (third, $e:expr) => {
-        print_bang!($e + 3);
+        print_bang!($e + 3)
     };
 }
 
index 3ec329cba1eb2a027bbd07794078ae136b6e5079..32df63e449d4a912eac1e1b2502cde40298aef21 100644 (file)
@@ -1,9 +1,12 @@
-error[E0744]: `?` is not allowed in a `const fn`
+error[E0658]: `?` is not allowed in a `const fn`
   --> $DIR/hir-const-check.rs:11:9
    |
 LL |         Some(())?;
    |         ^^^^^^^^^
+   |
+   = note: see issue #74935 <https://github.com/rust-lang/rust/issues/74935> for more information
+   = help: add `#![feature(const_try)]` to the crate attributes to enable
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0744`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.fixed b/src/test/ui/rust-2021/future-prelude-collision-generic.fixed
new file mode 100644 (file)
index 0000000..f0d8cb9
--- /dev/null
@@ -0,0 +1,37 @@
+// test for https://github.com/rust-lang/rust/issues/86940
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+struct Generic<T, U>(T, U);
+
+trait MyFromIter {
+    fn from_iter(_: i32) -> Self;
+}
+
+impl MyFromIter for Generic<i32, i32> {
+    fn from_iter(x: i32) -> Self {
+        Self(x, x)
+    }
+}
+
+impl std::iter::FromIterator<i32> for Generic<i32, i32> {
+    fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
+        todo!()
+    }
+}
+
+fn main() {
+    <Generic<_, _> as MyFromIter>::from_iter(1);
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~| this is accepted in the current edition (Rust 2018)
+    <Generic::<i32, i32> as MyFromIter>::from_iter(1);
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~| this is accepted in the current edition (Rust 2018)
+    <Generic::<_, _> as MyFromIter>::from_iter(1);
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~| this is accepted in the current edition (Rust 2018)
+}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.rs b/src/test/ui/rust-2021/future-prelude-collision-generic.rs
new file mode 100644 (file)
index 0000000..1984053
--- /dev/null
@@ -0,0 +1,37 @@
+// test for https://github.com/rust-lang/rust/issues/86940
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+struct Generic<T, U>(T, U);
+
+trait MyFromIter {
+    fn from_iter(_: i32) -> Self;
+}
+
+impl MyFromIter for Generic<i32, i32> {
+    fn from_iter(x: i32) -> Self {
+        Self(x, x)
+    }
+}
+
+impl std::iter::FromIterator<i32> for Generic<i32, i32> {
+    fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
+        todo!()
+    }
+}
+
+fn main() {
+    Generic::from_iter(1);
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~| this is accepted in the current edition (Rust 2018)
+    Generic::<i32, i32>::from_iter(1);
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~| this is accepted in the current edition (Rust 2018)
+    Generic::<_, _>::from_iter(1);
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~| this is accepted in the current edition (Rust 2018)
+}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.stderr b/src/test/ui/rust-2021/future-prelude-collision-generic.stderr
new file mode 100644 (file)
index 0000000..2c6a63d
--- /dev/null
@@ -0,0 +1,34 @@
+warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision-generic.rs:28:5
+   |
+LL |     Generic::from_iter(1);
+   |     ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic<_, _> as MyFromIter>::from_iter`
+   |
+note: the lint level is defined here
+  --> $DIR/future-prelude-collision-generic.rs:5:9
+   |
+LL | #![warn(rust_2021_prelude_collisions)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision-generic.rs:31:5
+   |
+LL |     Generic::<i32, i32>::from_iter(1);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<i32, i32> as MyFromIter>::from_iter`
+   |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision-generic.rs:34:5
+   |
+LL |     Generic::<_, _>::from_iter(1);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<_, _> as MyFromIter>::from_iter`
+   |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: 3 warnings emitted
+
diff --git a/src/test/ui/rust-2021/prelude2021.rs b/src/test/ui/rust-2021/prelude2021.rs
new file mode 100644 (file)
index 0000000..3a9fd69
--- /dev/null
@@ -0,0 +1,7 @@
+// check-pass
+// edition:2021
+// compile-flags: -Zunstable-options
+
+fn main() {
+    let _: u16 = 123i32.try_into().unwrap();
+}
index ec7358bd08ad23b20de8c59055324fa67a3c70c9..223ddf0f0ad2abfc7113ed4891942999c06dad1f 100644 (file)
@@ -3,12 +3,15 @@
 
 struct Foo {
     v: Vec<u32>,
+    h: std::collections::HashMap<i32, i32>,
 }
 
 impl Foo {
     fn bar(&self) {
         for _ in &self.v { //~ ERROR cannot move out of `self.v` which is behind a shared reference
         }
+        for _ in &self.h { //~ ERROR cannot move out of `self.h` which is behind a shared reference
+        }
     }
 }
 
index 304fe8cc81f1a9fb526a9c22a04b9d9ecdf748cd..7942698cc8eff3b56dc490a4a689ad3c089cb764 100644 (file)
@@ -3,12 +3,15 @@
 
 struct Foo {
     v: Vec<u32>,
+    h: std::collections::HashMap<i32, i32>,
 }
 
 impl Foo {
     fn bar(&self) {
         for _ in self.v { //~ ERROR cannot move out of `self.v` which is behind a shared reference
         }
+        for _ in self.h { //~ ERROR cannot move out of `self.h` which is behind a shared reference
+        }
     }
 }
 
index 48f3f423ac638aac67396ab971d14e88edd3a3a2..011fdf34c28b543cf60d4d4a93fde4e36d6ad089 100644 (file)
@@ -1,12 +1,25 @@
 error[E0507]: cannot move out of `self.v` which is behind a shared reference
-  --> $DIR/for-i-in-vec.rs:10:18
+  --> $DIR/for-i-in-vec.rs:11:18
    |
 LL |         for _ in self.v {
-   |                  ^^^^^^
-   |                  |
-   |                  move occurs because `self.v` has type `Vec<u32>`, which does not implement the `Copy` trait
-   |                  help: consider iterating over a slice of the `Vec<_>`'s content: `&self.v`
+   |                  ^^^^^^ move occurs because `self.v` has type `Vec<u32>`, which does not implement the `Copy` trait
+   |
+help: consider iterating over a slice of the `Vec<u32>`'s content
+   |
+LL |         for _ in &self.v {
+   |                  ^
+
+error[E0507]: cannot move out of `self.h` which is behind a shared reference
+  --> $DIR/for-i-in-vec.rs:13:18
+   |
+LL |         for _ in self.h {
+   |                  ^^^^^^ move occurs because `self.h` has type `HashMap<i32, i32>`, which does not implement the `Copy` trait
+   |
+help: consider iterating over a slice of the `HashMap<i32, i32>`'s content
+   |
+LL |         for _ in &self.h {
+   |                  ^
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0507`.
index c00a0f1700bb44e417b6c33a6009f9e73dc66efb..94766530091552c0f393824858ad88eb46066cfe 100644 (file)
@@ -2,19 +2,23 @@ error[E0507]: cannot move out of `selection.1` which is behind a shared referenc
   --> $DIR/option-content-move.rs:11:20
    |
 LL |                 if selection.1.unwrap().contains(selection.0) {
-   |                    ^^^^^^^^^^^
-   |                    |
-   |                    move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait
-   |                    help: consider borrowing the `Option`'s content: `selection.1.as_ref()`
+   |                    ^^^^^^^^^^^ move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait
+   |
+help: consider borrowing the `Option`'s content
+   |
+LL |                 if selection.1.as_ref().unwrap().contains(selection.0) {
+   |                               ^^^^^^^^^
 
 error[E0507]: cannot move out of `selection.1` which is behind a shared reference
   --> $DIR/option-content-move.rs:29:20
    |
 LL |                 if selection.1.unwrap().contains(selection.0) {
-   |                    ^^^^^^^^^^^
-   |                    |
-   |                    move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait
-   |                    help: consider borrowing the `Result`'s content: `selection.1.as_ref()`
+   |                    ^^^^^^^^^^^ move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait
+   |
+help: consider borrowing the `Result`'s content
+   |
+LL |                 if selection.1.as_ref().unwrap().contains(selection.0) {
+   |                               ^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index f0926220755a2006f061657a43aad2188e932a38..7a8137778b44607cd397c03b04205f43e27aeb84 100644 (file)
@@ -7,7 +7,7 @@
 fn f1(_: &str) {}
 macro_rules! m1 {
     ($e:expr) => {
-        f1($e);
+        f1($e)
     };
 }
 macro_rules! m3 {
index c7235e1c221057528a40b310a372971cf0201f87..cd6db8ddc8864fd2a08de85ed9de26c8c31fd553 100644 (file)
@@ -7,7 +7,7 @@
 fn f1(_: &str) {}
 macro_rules! m2 {
     ($e:expr) => {
-        f1(*$e);
+        f1(*$e)
     };
 }
 macro_rules! m3 {