From ee3fc9dff8f2cff217883cd4a6f979677a1263f9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 2 Aug 2022 15:47:14 -0400 Subject: never consider unsafe blocks unused if they would be required with unsafe_op_in_unsafe_fn --- compiler/rustc_errors/src/diagnostic_builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 9e68ee282e6..04159bff4ff 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -566,7 +566,7 @@ impl Drop for DiagnosticBuilderInner<'_> { ), )); handler.emit_diagnostic(&mut self.diagnostic); - panic!(); + panic!("error was constructed but not emitted"); } } // `.emit()` was previously called, or maybe we're during `.cancel()`. -- cgit 1.4.1-3-g733a5 From e9e46c95ce60469f596b8188c439dc278dff6bc4 Mon Sep 17 00:00:00 2001 From: Christopher Durham Date: Wed, 17 Aug 2022 06:07:33 -0500 Subject: Don't treat stashed warnings as errors --- compiler/rustc_errors/src/lib.rs | 74 +++++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 12 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 395bf5aad01..fe2afdf5a20 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -625,19 +625,13 @@ impl Handler { /// Stash a given diagnostic with the given `Span` and `StashKey` as the key for later stealing. pub fn stash_diagnostic(&self, span: Span, key: StashKey, diag: Diagnostic) { let mut inner = self.inner.borrow_mut(); - // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic - // if/when we have a more robust macro-friendly replacement for `(span, key)` as a key. - // See the PR for a discussion. - inner.stashed_diagnostics.insert((span, key), diag); + inner.stash((span, key), diag); } /// Steal a previously stashed diagnostic with the given `Span` and `StashKey` as the key. pub fn steal_diagnostic(&self, span: Span, key: StashKey) -> Option> { - self.inner - .borrow_mut() - .stashed_diagnostics - .remove(&(span, key)) - .map(|diag| DiagnosticBuilder::new_diagnostic(self, diag)) + let mut inner = self.inner.borrow_mut(); + inner.steal((span, key)).map(|diag| DiagnosticBuilder::new_diagnostic(self, diag)) } /// Emit all stashed diagnostics. @@ -1105,13 +1099,31 @@ impl HandlerInner { /// Emit all stashed diagnostics. fn emit_stashed_diagnostics(&mut self) -> Option { + let has_errors = self.has_errors(); let diags = self.stashed_diagnostics.drain(..).map(|x| x.1).collect::>(); let mut reported = None; for mut diag in diags { + // Decrement the count tracking the stash; emitting will increment it. if diag.is_error() { - reported = Some(ErrorGuaranteed(())); + if matches!(diag.level, Level::Error { lint: true }) { + self.lint_err_count -= 1; + } else { + self.err_count -= 1; + } + } else { + if diag.is_force_warn() { + self.warn_count -= 1; + } else { + // Unless they're forced, don't flush stashed warnings when + // there are errors, to avoid causing warning overload. The + // stash would've been stolen already if it were important. + if has_errors { + continue; + } + } } - self.emit_diagnostic(&mut diag); + let reported_this = self.emit_diagnostic(&mut diag); + reported = reported.or(reported_this); } reported } @@ -1301,9 +1313,47 @@ impl HandlerInner { } } + fn stash(&mut self, key: (Span, StashKey), diagnostic: Diagnostic) { + // Track the diagnostic for counts, but don't panic-if-treat-err-as-bug + // yet; that happens when we actually emit the diagnostic. + if diagnostic.is_error() { + if matches!(diagnostic.level, Level::Error { lint: true }) { + self.lint_err_count += 1; + } else { + self.err_count += 1; + } + } else { + // Warnings are only automatically flushed if they're forced. + if diagnostic.is_force_warn() { + self.warn_count += 1; + } + } + + // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic + // if/when we have a more robust macro-friendly replacement for `(span, key)` as a key. + // See the PR for a discussion. + self.stashed_diagnostics.insert(key, diagnostic); + } + + fn steal(&mut self, key: (Span, StashKey)) -> Option { + let diagnostic = self.stashed_diagnostics.remove(&key)?; + if diagnostic.is_error() { + if matches!(diagnostic.level, Level::Error { lint: true }) { + self.lint_err_count -= 1; + } else { + self.err_count -= 1; + } + } else { + if diagnostic.is_force_warn() { + self.warn_count -= 1; + } + } + Some(diagnostic) + } + #[inline] fn err_count(&self) -> usize { - self.err_count + self.stashed_diagnostics.len() + self.err_count } fn has_errors(&self) -> bool { -- cgit 1.4.1-3-g733a5 From 767239f7403a3808e534da02ca388632eac2bc18 Mon Sep 17 00:00:00 2001 From: Christopher Durham Date: Wed, 17 Aug 2022 06:52:47 -0500 Subject: Reenable early feature-gates as future-compat warnings --- compiler/rustc_ast_passes/src/feature_gate.rs | 58 +++++++++++++--------- compiler/rustc_errors/src/lib.rs | 1 + compiler/rustc_lint_defs/src/builtin.rs | 51 +++++++++++++++++++ compiler/rustc_session/src/parse.rs | 55 ++++++++++++++++++-- src/test/ui/macros/stringify.rs | 7 +++ .../ui/or-patterns/or-patterns-syntactic-pass.rs | 16 +++--- .../or-patterns/or-patterns-syntactic-pass.stderr | 13 +++++ ...nstraints-before-generic-args-syntactic-pass.rs | 4 ++ ...aints-before-generic-args-syntactic-pass.stderr | 24 +++++++++ src/test/ui/pattern/rest-pat-syntactic.rs | 5 +- src/test/ui/pattern/rest-pat-syntactic.stderr | 24 +++++++++ 11 files changed, 224 insertions(+), 34 deletions(-) create mode 100644 src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr create mode 100644 src/test/ui/parser/constraints-before-generic-args-syntactic-pass.stderr create mode 100644 src/test/ui/pattern/rest-pat-syntactic.stderr (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 97eee56f948..68fca081018 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -2,10 +2,10 @@ use rustc_ast as ast; use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; use rustc_ast::{AssocConstraint, AssocConstraintKind, NodeId}; use rustc_ast::{PatKind, RangeEnd, VariantData}; -use rustc_errors::{struct_span_err, Applicability}; +use rustc_errors::{struct_span_err, Applicability, StashKey}; +use rustc_feature::Features; use rustc_feature::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; -use rustc_feature::{Features, GateIssue}; -use rustc_session::parse::{feature_err, feature_err_issue}; +use rustc_session::parse::{feature_err, feature_warn}; use rustc_session::Session; use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; @@ -20,9 +20,7 @@ macro_rules! gate_feature_fn { let has_feature: bool = has_feature(visitor.features); debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature); if !has_feature && !span.allows_unstable($name) { - feature_err_issue(&visitor.sess.parse_sess, name, span, GateIssue::Language, explain) - .help(help) - .emit(); + feature_err(&visitor.sess.parse_sess, name, span, explain).help(help).emit(); } }}; ($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{ @@ -31,8 +29,19 @@ macro_rules! gate_feature_fn { let has_feature: bool = has_feature(visitor.features); debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature); if !has_feature && !span.allows_unstable($name) { - feature_err_issue(&visitor.sess.parse_sess, name, span, GateIssue::Language, explain) - .emit(); + feature_err(&visitor.sess.parse_sess, name, span, explain).emit(); + } + }}; + (future_incompatible; $visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{ + let (visitor, has_feature, span, name, explain) = + (&*$visitor, $has_feature, $span, $name, $explain); + let has_feature: bool = has_feature(visitor.features); + debug!( + "gate_feature(feature = {:?}, span = {:?}); has? {} (future_incompatible)", + name, span, has_feature + ); + if !has_feature && !span.allows_unstable($name) { + feature_warn(&visitor.sess.parse_sess, name, span, explain); } }}; } @@ -44,6 +53,9 @@ macro_rules! gate_feature_post { ($visitor: expr, $feature: ident, $span: expr, $explain: expr) => { gate_feature_fn!($visitor, |x: &Features| x.$feature, $span, sym::$feature, $explain) }; + (future_incompatible; $visitor: expr, $feature: ident, $span: expr, $explain: expr) => { + gate_feature_fn!(future_incompatible; $visitor, |x: &Features| x.$feature, $span, sym::$feature, $explain) + }; } pub fn check_attribute(attr: &ast::Attribute, sess: &Session, features: &Features) { @@ -588,11 +600,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { { // When we encounter a statement of the form `foo: Ty = val;`, this will emit a type // ascription error, but the likely intention was to write a `let` statement. (#78907). - feature_err_issue( + feature_err( &self.sess.parse_sess, sym::type_ascription, lhs.span, - GateIssue::Language, "type ascription is experimental", ).span_suggestion_verbose( lhs.span.shrink_to_lo(), @@ -615,15 +626,22 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ); } ast::ExprKind::Type(..) => { - // To avoid noise about type ascription in common syntax errors, only emit if it - // is the *only* error. if self.sess.parse_sess.span_diagnostic.err_count() == 0 { + // To avoid noise about type ascription in common syntax errors, + // only emit if it is the *only* error. gate_feature_post!( &self, type_ascription, e.span, "type ascription is experimental" ); + } else { + // And if it isn't, cancel the early-pass warning. + self.sess + .parse_sess + .span_diagnostic + .steal_diagnostic(e.span, StashKey::EarlySyntaxWarning) + .map(|err| err.cancel()); } } ast::ExprKind::TryBlock(_) => { @@ -789,14 +807,12 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { // All uses of `gate_all!` below this point were added in #65742, // and subsequently disabled (with the non-early gating readded). + // We emit an early future-incompatible warning for these. + // New syntax gates should go above here to get a hard error gate. macro_rules! gate_all { ($gate:ident, $msg:literal) => { - // FIXME(eddyb) do something more useful than always - // disabling these uses of early feature-gatings. - if false { - for span in spans.get(&sym::$gate).unwrap_or(&vec![]) { - gate_feature_post!(&visitor, $gate, *span, $msg); - } + for span in spans.get(&sym::$gate).unwrap_or(&vec![]) { + gate_feature_post!(future_incompatible; &visitor, $gate, *span, $msg); } }; } @@ -809,11 +825,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { gate_all!(try_blocks, "`try` blocks are unstable"); gate_all!(label_break_value, "labels on blocks are unstable"); gate_all!(box_syntax, "box expression syntax is experimental; you can call `Box::new` instead"); - // To avoid noise about type ascription in common syntax errors, - // only emit if it is the *only* error. (Also check it last.) - if sess.parse_sess.span_diagnostic.err_count() == 0 { - gate_all!(type_ascription, "type ascription is experimental"); - } + gate_all!(type_ascription, "type ascription is experimental"); visit::walk_crate(&mut visitor, krate); } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index fe2afdf5a20..43b8288d8b6 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -458,6 +458,7 @@ struct HandlerInner { pub enum StashKey { ItemNoType, UnderscoreForArrayLengths, + EarlySyntaxWarning, } fn default_track_diagnostic(_: &Diagnostic) {} diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index f00165cd3b3..95e34da734d 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3212,6 +3212,56 @@ declare_lint! { }; } +declare_lint! { + /// The `unstable_syntax_pre_expansion` lint detects the use of unstable + /// syntax that is discarded during attribute expansion. + /// + /// ### Example + /// + /// ```rust + /// #[cfg(FALSE)] + /// macro foo() {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// The input to active attributes such as `#[cfg]` or procedural macro + /// attributes is required to be valid syntax. Previously, the compiler only + /// gated the use of unstable syntax features after resolving `#[cfg]` gates + /// and expanding procedural macros. + /// + /// To avoid relying on unstable syntax, move the use of unstable syntax + /// into a position where the compiler does not parse the syntax, such as a + /// functionlike macro. + /// + /// ```rust + /// # #![deny(unstable_syntax_pre_expansion)] + /// + /// macro_rules! identity { + /// ( $($tokens:tt)* ) => { $($tokens)* } + /// } + /// + /// #[cfg(FALSE)] + /// identity! { + /// macro foo() {} + /// } + /// ``` + /// + /// This is a [future-incompatible] lint to transition this + /// to a hard error in the future. See [issue #65860] for more details. + /// + /// [issue #65860]: https://github.com/rust-lang/rust/issues/65860 + /// [future-incompatible]: ../index.md#future-incompatible-lints + pub UNSTABLE_SYNTAX_PRE_EXPANSION, + Warn, + "unstable syntax can change at any point in the future, causing a hard error!", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #65860 ", + }; +} + declare_lint_pass! { /// Does nothing as a lint pass, but registers some `Lint`s /// that are used by other parts of the compiler. @@ -3280,6 +3330,7 @@ declare_lint_pass! { POINTER_STRUCTURAL_MATCH, NONTRIVIAL_STRUCTURAL_MATCH, SOFT_UNSTABLE, + UNSTABLE_SYNTAX_PRE_EXPANSION, INLINE_NO_SANITIZE, BAD_ASM_STYLE, ASM_SUB_REGISTER, diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index f31d52147b4..9f0886cb208 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -2,15 +2,17 @@ //! It also serves as an input to the parser itself. use crate::config::CheckCfg; -use crate::lint::{BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId}; +use crate::lint::{ + builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId, +}; use crate::SessionDiagnostic; use rustc_ast::node_id::NodeId; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{Lock, Lrc}; use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler}; use rustc_errors::{ - error_code, fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder, - DiagnosticMessage, ErrorGuaranteed, MultiSpan, + error_code, fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId, + DiagnosticMessage, ErrorGuaranteed, MultiSpan, StashKey, }; use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures}; use rustc_span::edition::Edition; @@ -101,11 +103,58 @@ pub fn feature_err_issue<'a>( issue: GateIssue, explain: &str, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + let span = span.into(); + + // Cancel an earlier warning for this same error, if it exists. + if let Some(span) = span.primary_span() { + sess.span_diagnostic + .steal_diagnostic(span, StashKey::EarlySyntaxWarning) + .map(|err| err.cancel()); + } + let mut err = sess.span_diagnostic.struct_span_err_with_code(span, explain, error_code!(E0658)); add_feature_diagnostics_for_issue(&mut err, sess, feature, issue); err } +/// Construct a future incompatibility diagnostic for a feature gate. +/// +/// This diagnostic is only a warning and *does not cause compilation to fail*. +pub fn feature_warn<'a>(sess: &'a ParseSess, feature: Symbol, span: Span, explain: &str) { + feature_warn_issue(sess, feature, span, GateIssue::Language, explain); +} + +/// Construct a future incompatibility diagnostic for a feature gate. +/// +/// This diagnostic is only a warning and *does not cause compilation to fail*. +/// +/// This variant allows you to control whether it is a library or language feature. +/// Almost always, you want to use this for a language feature. If so, prefer `feature_warn`. +pub fn feature_warn_issue<'a>( + sess: &'a ParseSess, + feature: Symbol, + span: Span, + issue: GateIssue, + explain: &str, +) { + let mut err = sess.span_diagnostic.struct_span_warn(span, explain); + add_feature_diagnostics_for_issue(&mut err, sess, feature, issue); + + // Decorate this as a future-incompatibility lint as in rustc_middle::lint::struct_lint_level + let lint = UNSTABLE_SYNTAX_PRE_EXPANSION; + let future_incompatible = lint.future_incompatible.as_ref().unwrap(); + err.code(DiagnosticId::Lint { + name: lint.name_lower(), + has_future_breakage: false, + is_force_warn: false, + }); + err.warn(lint.desc); + err.note(format!("for more information, see {}", future_incompatible.reference)); + + // A later feature_err call can steal and cancel this warning. + err.stash(span, StashKey::EarlySyntaxWarning); +} + /// Adds the diagnostics for a feature to an existing error. pub fn add_feature_diagnostics<'a>(err: &mut Diagnostic, sess: &'a ParseSess, feature: Symbol) { add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language); diff --git a/src/test/ui/macros/stringify.rs b/src/test/ui/macros/stringify.rs index 8e71ed7c112..082c1abb8f2 100644 --- a/src/test/ui/macros/stringify.rs +++ b/src/test/ui/macros/stringify.rs @@ -3,11 +3,18 @@ // compile-flags: --test #![feature(async_closure)] +#![feature(box_patterns)] +#![feature(box_syntax)] #![feature(const_trait_impl)] +#![feature(decl_macro)] #![feature(generators)] #![feature(half_open_range_patterns)] +#![feature(label_break_value)] #![feature(more_qualified_paths)] #![feature(raw_ref_op)] +#![feature(trait_alias)] +#![feature(try_blocks)] +#![feature(type_ascription)] #![deny(unused_macros)] macro_rules! stringify_block { diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs index 6f9a631b092..dda5c0bb59d 100644 --- a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs +++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs @@ -7,7 +7,7 @@ fn main() {} // Test the `pat` macro fragment parser: macro_rules! accept_pat { - ($p:pat) => {} + ($p:pat) => {}; } accept_pat!((p | q)); @@ -21,28 +21,28 @@ accept_pat!([p | q]); #[cfg(FALSE)] fn or_patterns() { // Top level of `let`: - let (| A | B); + let (A | B); let (A | B); let (A | B): u8; let (A | B) = 0; let (A | B): u8 = 0; // Top level of `for`: - for | A | B in 0 {} + for A | B in 0 {} for A | B in 0 {} // Top level of `while`: - while let | A | B = 0 {} + while let A | B = 0 {} while let A | B = 0 {} // Top level of `if`: - if let | A | B = 0 {} + if let A | B = 0 {} if let A | B = 0 {} // Top level of `match` arms: match 0 { - | A | B => {}, - A | B => {}, + A | B => {} + A | B => {} } // Functions: @@ -68,6 +68,8 @@ fn or_patterns() { // These bind as `(prefix p) | q` as opposed to `prefix (p | q)`: let (box 0 | 1); // Unstable; we *can* change the precedence if we want. + //~^ WARN box pattern syntax is experimental + //~| WARN unstable syntax let (&0 | 1); let (&mut 0 | 1); let (x @ 0 | 1); diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr new file mode 100644 index 00000000000..c43fe192a73 --- /dev/null +++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr @@ -0,0 +1,13 @@ +warning: box pattern syntax is experimental + --> $DIR/or-patterns-syntactic-pass.rs:70:10 + | +LL | let (box 0 | 1); // Unstable; we *can* change the precedence if we want. + | ^^^^^ + | + = note: see issue #29641 for more information + = help: add `#![feature(box_patterns)]` to the crate attributes to enable + = warning: unstable syntax can change at any point in the future, causing a hard error! + = note: for more information, see issue #65860 + +warning: 1 warning emitted + diff --git a/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs index afbd13e6fd9..d8346653c25 100644 --- a/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs +++ b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs @@ -3,7 +3,11 @@ #[cfg(FALSE)] fn syntax() { foo::(); + //~^ WARN associated type bounds are unstable + //~| WARN unstable syntax foo::(); + //~^ WARN associated type bounds are unstable + //~| WARN unstable syntax } fn main() {} diff --git a/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.stderr b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.stderr new file mode 100644 index 00000000000..7e843c7f4d0 --- /dev/null +++ b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.stderr @@ -0,0 +1,24 @@ +warning: associated type bounds are unstable + --> $DIR/constraints-before-generic-args-syntactic-pass.rs:5:19 + | +LL | foo::(); + | ^^^^^^ + | + = note: see issue #52662 for more information + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable + = warning: unstable syntax can change at any point in the future, causing a hard error! + = note: for more information, see issue #65860 + +warning: associated type bounds are unstable + --> $DIR/constraints-before-generic-args-syntactic-pass.rs:8:23 + | +LL | foo::(); + | ^^^^^^ + | + = note: see issue #52662 for more information + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable + = warning: unstable syntax can change at any point in the future, causing a hard error! + = note: for more information, see issue #65860 + +warning: 2 warnings emitted + diff --git a/src/test/ui/pattern/rest-pat-syntactic.rs b/src/test/ui/pattern/rest-pat-syntactic.rs index 9656a0b5de9..4da5a2db767 100644 --- a/src/test/ui/pattern/rest-pat-syntactic.rs +++ b/src/test/ui/pattern/rest-pat-syntactic.rs @@ -19,6 +19,8 @@ fn rest_patterns() { // Box patterns: let box ..; + //~^ WARN box pattern syntax is experimental + //~| WARN unstable syntax // In or-patterns: match x { @@ -57,7 +59,7 @@ fn rest_patterns() { .. | [ ( - box .., + box .., //~ WARN box pattern syntax is experimental &(..), &mut .., x @ .. @@ -67,4 +69,5 @@ fn rest_patterns() { ref mut x @ .. => {} } + //~| WARN unstable syntax } diff --git a/src/test/ui/pattern/rest-pat-syntactic.stderr b/src/test/ui/pattern/rest-pat-syntactic.stderr new file mode 100644 index 00000000000..37019b7d5ba --- /dev/null +++ b/src/test/ui/pattern/rest-pat-syntactic.stderr @@ -0,0 +1,24 @@ +warning: box pattern syntax is experimental + --> $DIR/rest-pat-syntactic.rs:21:9 + | +LL | let box ..; + | ^^^^^^ + | + = note: see issue #29641 for more information + = help: add `#![feature(box_patterns)]` to the crate attributes to enable + = warning: unstable syntax can change at any point in the future, causing a hard error! + = note: for more information, see issue #65860 + +warning: box pattern syntax is experimental + --> $DIR/rest-pat-syntactic.rs:62:17 + | +LL | box .., + | ^^^^^^ + | + = note: see issue #29641 for more information + = help: add `#![feature(box_patterns)]` to the crate attributes to enable + = warning: unstable syntax can change at any point in the future, causing a hard error! + = note: for more information, see issue #65860 + +warning: 2 warnings emitted + -- cgit 1.4.1-3-g733a5 From 91ad4e38f53ce1ef8783233bde36a81cd8177981 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Fri, 19 Aug 2022 14:47:45 +0200 Subject: Add Handler::struct_diagnostic() This unifies the struct_{warn,error,fatal}() methods in one generic method. --- compiler/rustc_errors/src/diagnostic_builder.rs | 30 ++++++++++++++++++++++ compiler/rustc_errors/src/lib.rs | 9 +++++++ compiler/rustc_session/src/parse.rs | 10 +++++++- .../session-diagnostic/diagnostic-derive.stderr | 2 +- 4 files changed, 49 insertions(+), 2 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 04159bff4ff..61d767a1cc6 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -84,6 +84,13 @@ pub trait EmissionGuarantee: Sized { /// of `Self` without actually performing the emission. #[track_caller] fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self; + + /// Creates a new `DiagnosticBuilder` that will return this type of guarantee. + #[track_caller] + fn make_diagnostic_builder( + handler: &Handler, + msg: impl Into, + ) -> DiagnosticBuilder<'_, Self>; } /// Private module for sealing the `IsError` helper trait. @@ -166,6 +173,15 @@ impl EmissionGuarantee for ErrorGuaranteed { } } } + + fn make_diagnostic_builder( + handler: &Handler, + msg: impl Into, + ) -> DiagnosticBuilder<'_, Self> { + DiagnosticBuilder::new_guaranteeing_error::<_, { Level::Error { lint: false } }>( + handler, msg, + ) + } } impl<'a> DiagnosticBuilder<'a, ()> { @@ -208,6 +224,13 @@ impl EmissionGuarantee for () { DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {} } } + + fn make_diagnostic_builder( + handler: &Handler, + msg: impl Into, + ) -> DiagnosticBuilder<'_, Self> { + DiagnosticBuilder::new(handler, Level::Warning(None), msg) + } } impl<'a> DiagnosticBuilder<'a, !> { @@ -247,6 +270,13 @@ impl EmissionGuarantee for ! { // Then fatally error, returning `!` crate::FatalError.raise() } + + fn make_diagnostic_builder( + handler: &Handler, + msg: impl Into, + ) -> DiagnosticBuilder<'_, Self> { + DiagnosticBuilder::new_fatal(handler, msg) + } } /// In general, the `DiagnosticBuilder` uses deref to allow access to diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 18e84b70b1b..9b9c334d4df 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -641,6 +641,15 @@ impl Handler { self.inner.borrow_mut().emit_stashed_diagnostics() } + /// Construct a builder with the `msg` at the level appropriate for the specific `EmissionGuarantee`. + #[rustc_lint_diagnostics] + pub fn struct_diagnostic( + &self, + msg: impl Into, + ) -> DiagnosticBuilder<'_, G> { + G::make_diagnostic_builder(self, msg) + } + /// Construct a builder at the `Warning` level at the given `span` and with the `msg`. /// /// Attempting to `.emit()` the builder will only emit if either: diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 9f0886cb208..b9b2356130a 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -12,7 +12,7 @@ use rustc_data_structures::sync::{Lock, Lrc}; use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler}; use rustc_errors::{ error_code, fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId, - DiagnosticMessage, ErrorGuaranteed, MultiSpan, StashKey, + DiagnosticMessage, EmissionGuarantee, ErrorGuaranteed, MultiSpan, StashKey, }; use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures}; use rustc_span::edition::Edition; @@ -372,4 +372,12 @@ impl ParseSess { pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { self.span_diagnostic.struct_warn(msg) } + + #[rustc_lint_diagnostics] + pub fn struct_diagnostic( + &self, + msg: impl Into, + ) -> DiagnosticBuilder<'_, G> { + self.span_diagnostic.struct_diagnostic(msg) + } } diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index c1080aa2452..a1a054c67d4 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -411,7 +411,7 @@ LL | #[derive(SessionDiagnostic)] | = help: normalized in stderr note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg` - --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:539:19 + --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:569:19 | LL | arg: impl IntoDiagnosticArg, | ^^^^^^^^^^^^^^^^^ required by this bound in `DiagnosticBuilder::<'a, G>::set_arg` -- cgit 1.4.1-3-g733a5 From c18503f3ff9f81ed3b368246ade73e79dbd53282 Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 19 Aug 2022 14:45:54 +0100 Subject: errors: `IntoDiagnosticArg` for `io::Error`/paths Add impls of `IntoDiagnosticArg` for `std::io::Error`, `std::path::Path` and `std::path::PathBuf`. Signed-off-by: David Wood --- compiler/rustc_errors/src/diagnostic.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 356f9dfdb3b..506198df4d8 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -13,6 +13,7 @@ use rustc_span::{edition::Edition, Span, DUMMY_SP}; use std::borrow::Cow; use std::fmt; use std::hash::{Hash, Hasher}; +use std::path::{Path, PathBuf}; /// Error type for `Diagnostic`'s `suggestions` field, indicating that /// `.disable_suggestions()` was called on the `Diagnostic`. @@ -83,6 +84,7 @@ into_diagnostic_arg_using_display!( u64, i128, u128, + std::io::Error, std::num::NonZeroU32, hir::Target, Edition, @@ -124,6 +126,18 @@ impl IntoDiagnosticArg for String { } } +impl<'a> IntoDiagnosticArg for &'a Path { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.display().to_string())) + } +} + +impl IntoDiagnosticArg for PathBuf { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.display().to_string())) + } +} + impl IntoDiagnosticArg for usize { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { DiagnosticArgValue::Number(self) -- cgit 1.4.1-3-g733a5 From 18b640aee5b5435491a9db82c08c8fde8b7b62c9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 28 Aug 2022 01:08:24 +0000 Subject: Suggest calling when operator types mismatch --- compiler/rustc_errors/src/lib.rs | 19 ++- compiler/rustc_lint_defs/src/lib.rs | 3 +- .../rustc_typeck/src/check/fn_ctxt/suggestions.rs | 173 +++++++++++++++------ compiler/rustc_typeck/src/check/op.rs | 128 +++++---------- src/test/ui/binop/issue-77910-2.stderr | 5 + src/test/ui/fn/fn-compare-mismatch.stderr | 10 +- src/test/ui/issues/issue-59488.stderr | 18 +-- ...ssue-70724-add_type_neq_err_label-unwrap.stderr | 7 +- 8 files changed, 199 insertions(+), 164 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 9b9c334d4df..b21e9c2c96c 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1248,9 +1248,13 @@ impl HandlerInner { } fn treat_err_as_bug(&self) -> bool { - self.flags - .treat_err_as_bug - .map_or(false, |c| self.err_count() + self.lint_err_count >= c.get()) + self.flags.treat_err_as_bug.map_or(false, |c| { + self.err_count() + + self.lint_err_count + + self.delayed_span_bugs.len() + + self.delayed_good_path_bugs.len() + >= c.get() + }) } fn print_error_count(&mut self, registry: &Registry) { @@ -1406,7 +1410,14 @@ impl HandlerInner { // This is technically `self.treat_err_as_bug()` but `delay_span_bug` is called before // incrementing `err_count` by one, so we need to +1 the comparing. // FIXME: Would be nice to increment err_count in a more coherent way. - if self.flags.treat_err_as_bug.map_or(false, |c| self.err_count() + 1 >= c.get()) { + if self.flags.treat_err_as_bug.map_or(false, |c| { + self.err_count() + + self.lint_err_count + + self.delayed_span_bugs.len() + + self.delayed_good_path_bugs.len() + + 1 + >= c.get() + }) { // FIXME: don't abort here if report_delayed_bugs is off self.span_bug(sp, msg); } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 9e7cbba9511..9c6530c8a08 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -41,7 +41,8 @@ macro_rules! pluralize { /// All suggestions are marked with an `Applicability`. Tools use the applicability of a suggestion /// to determine whether it should be automatically applied or if the user should be consulted /// before applying the suggestion. -#[derive(Copy, Clone, Debug, PartialEq, Hash, Encodable, Decodable, Serialize, Deserialize)] +#[derive(Copy, Clone, Debug, Hash, Encodable, Decodable, Serialize, Deserialize)] +#[derive(PartialEq, Eq, PartialOrd, Ord)] pub enum Applicability { /// The suggestion is definitely what the user intended, or maintains the exact meaning of the code. /// This suggestion should be automatically applied. diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 4eb0f045d77..96901b53303 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -76,10 +76,68 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { found: Ty<'tcx>, can_satisfy: impl FnOnce(Ty<'tcx>) -> bool, ) -> bool { - enum DefIdOrName { - DefId(DefId), - Name(&'static str), + let Some((def_id_or_name, output, num_inputs)) = self.extract_callable_info(expr, found) + else { return false; }; + if can_satisfy(output) { + let (sugg_call, mut applicability) = match num_inputs { + 0 => ("".to_string(), Applicability::MachineApplicable), + 1..=4 => ( + (0..num_inputs).map(|_| "_").collect::>().join(", "), + Applicability::MachineApplicable, + ), + _ => ("...".to_string(), Applicability::HasPlaceholders), + }; + + let msg = match def_id_or_name { + DefIdOrName::DefId(def_id) => match self.tcx.def_kind(def_id) { + DefKind::Ctor(CtorOf::Struct, _) => "instantiate this tuple struct".to_string(), + DefKind::Ctor(CtorOf::Variant, _) => { + "instantiate this tuple variant".to_string() + } + kind => format!("call this {}", kind.descr(def_id)), + }, + DefIdOrName::Name(name) => format!("call this {name}"), + }; + + let sugg = match expr.kind { + hir::ExprKind::Call(..) + | hir::ExprKind::Path(..) + | hir::ExprKind::Index(..) + | hir::ExprKind::Lit(..) => { + vec![(expr.span.shrink_to_hi(), format!("({sugg_call})"))] + } + hir::ExprKind::Closure { .. } => { + // Might be `{ expr } || { bool }` + applicability = Applicability::MaybeIncorrect; + vec![ + (expr.span.shrink_to_lo(), "(".to_string()), + (expr.span.shrink_to_hi(), format!(")({sugg_call})")), + ] + } + _ => { + vec![ + (expr.span.shrink_to_lo(), "(".to_string()), + (expr.span.shrink_to_hi(), format!(")({sugg_call})")), + ] + } + }; + + err.multipart_suggestion_verbose( + format!("use parentheses to {msg}"), + sugg, + applicability, + ); + + return true; } + false + } + + fn extract_callable_info( + &self, + expr: &Expr<'_>, + found: Ty<'tcx>, + ) -> Option<(DefIdOrName, Ty<'tcx>, usize)> { // Autoderef is useful here because sometimes we box callables, etc. let Some((def_id_or_name, output, inputs)) = self.autoderef(expr.span, found).silence_errors().find_map(|(found, _)| { match *found.kind() { @@ -148,67 +206,83 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => None, } - }) else { return false; }; + }) else { return None; }; let output = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, output); + // We don't want to register any extra obligations, which should be // implied by wf, but also because that would possibly result in // erroneous errors later on. let infer::InferOk { value: output, obligations: _ } = self.normalize_associated_types_in_as_infer_ok(expr.span, output); - if !output.is_ty_var() && can_satisfy(output) { - let (sugg_call, mut applicability) = match inputs { - 0 => ("".to_string(), Applicability::MachineApplicable), - 1..=4 => ( - (0..inputs).map(|_| "_").collect::>().join(", "), - Applicability::MachineApplicable, - ), - _ => ("...".to_string(), Applicability::HasPlaceholders), - }; - let msg = match def_id_or_name { - DefIdOrName::DefId(def_id) => match self.tcx.def_kind(def_id) { - DefKind::Ctor(CtorOf::Struct, _) => "instantiate this tuple struct".to_string(), - DefKind::Ctor(CtorOf::Variant, _) => { - "instantiate this tuple variant".to_string() - } - kind => format!("call this {}", kind.descr(def_id)), - }, - DefIdOrName::Name(name) => format!("call this {name}"), - }; + if output.is_ty_var() { None } else { Some((def_id_or_name, output, inputs)) } + } - let sugg = match expr.kind { - hir::ExprKind::Call(..) - | hir::ExprKind::Path(..) - | hir::ExprKind::Index(..) - | hir::ExprKind::Lit(..) => { - vec![(expr.span.shrink_to_hi(), format!("({sugg_call})"))] - } - hir::ExprKind::Closure { .. } => { - // Might be `{ expr } || { bool }` - applicability = Applicability::MaybeIncorrect; - vec![ - (expr.span.shrink_to_lo(), "(".to_string()), - (expr.span.shrink_to_hi(), format!(")({sugg_call})")), - ] - } - _ => { - vec![ - (expr.span.shrink_to_lo(), "(".to_string()), - (expr.span.shrink_to_hi(), format!(")({sugg_call})")), - ] + pub fn suggest_two_fn_call( + &self, + err: &mut Diagnostic, + lhs_expr: &'tcx hir::Expr<'tcx>, + lhs_ty: Ty<'tcx>, + rhs_expr: &'tcx hir::Expr<'tcx>, + rhs_ty: Ty<'tcx>, + can_satisfy: impl FnOnce(Ty<'tcx>, Ty<'tcx>) -> bool, + ) -> bool { + let Some((_, lhs_output_ty, num_lhs_inputs)) = self.extract_callable_info(lhs_expr, lhs_ty) + else { return false; }; + let Some((_, rhs_output_ty, num_rhs_inputs)) = self.extract_callable_info(rhs_expr, rhs_ty) + else { return false; }; + + if can_satisfy(lhs_output_ty, rhs_output_ty) { + let mut sugg = vec![]; + let mut applicability = Applicability::MachineApplicable; + + for (expr, num_inputs) in [(lhs_expr, num_lhs_inputs), (rhs_expr, num_rhs_inputs)] { + let (sugg_call, this_applicability) = match num_inputs { + 0 => ("".to_string(), Applicability::MachineApplicable), + 1..=4 => ( + (0..num_inputs).map(|_| "_").collect::>().join(", "), + Applicability::MachineApplicable, + ), + _ => ("...".to_string(), Applicability::HasPlaceholders), + }; + + applicability = applicability.max(this_applicability); + + match expr.kind { + hir::ExprKind::Call(..) + | hir::ExprKind::Path(..) + | hir::ExprKind::Index(..) + | hir::ExprKind::Lit(..) => { + sugg.extend([(expr.span.shrink_to_hi(), format!("({sugg_call})"))]); + } + hir::ExprKind::Closure { .. } => { + // Might be `{ expr } || { bool }` + applicability = Applicability::MaybeIncorrect; + sugg.extend([ + (expr.span.shrink_to_lo(), "(".to_string()), + (expr.span.shrink_to_hi(), format!(")({sugg_call})")), + ]); + } + _ => { + sugg.extend([ + (expr.span.shrink_to_lo(), "(".to_string()), + (expr.span.shrink_to_hi(), format!(")({sugg_call})")), + ]); + } } - }; + } err.multipart_suggestion_verbose( - format!("use parentheses to {msg}"), + format!("use parentheses to call these"), sugg, applicability, ); - return true; + true + } else { + false } - false } pub fn suggest_deref_ref_or_into( @@ -959,3 +1033,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } + +enum DefIdOrName { + DefId(DefId), + Name(&'static str), +} diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index eb0c51bb2f9..952086e898f 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -410,26 +410,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let mut err = struct_span_err!(self.tcx.sess, op.span, E0369, "{message}"); if !lhs_expr.span.eq(&rhs_expr.span) { - self.add_type_neq_err_label( - &mut err, - lhs_expr.span, - lhs_ty, - rhs_ty, - rhs_expr, - op, - is_assign, - expected, - ); - self.add_type_neq_err_label( - &mut err, - rhs_expr.span, - rhs_ty, - lhs_ty, - lhs_expr, - op, - is_assign, - expected, - ); + err.span_label(lhs_expr.span, lhs_ty.to_string()); + err.span_label(rhs_expr.span, rhs_ty.to_string()); } self.note_unmet_impls_on_type(&mut err, errors); (err, missing_trait, use_output) @@ -468,17 +450,50 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; + let is_compatible = |lhs_ty, rhs_ty| { + self.lookup_op_method( + lhs_ty, + Some(rhs_ty), + Some(rhs_expr), + Op::Binary(op, is_assign), + expected, + ) + .is_ok() + }; + // We should suggest `a + b` => `*a + b` if `a` is copy, and suggest // `a += b` => `*a += b` if a is a mut ref. - if is_assign == IsAssign::Yes - && let Some(lhs_deref_ty) = self.deref_once_mutably_for_diagnostic(lhs_ty) { - suggest_deref_binop(lhs_deref_ty); + if !op.span.can_be_used_for_suggestions() { + // Suppress suggestions when lhs and rhs are not in the same span as the error + } else if is_assign == IsAssign::Yes + && let Some(lhs_deref_ty) = self.deref_once_mutably_for_diagnostic(lhs_ty) + { + suggest_deref_binop(lhs_deref_ty); } else if is_assign == IsAssign::No - && let Ref(_, lhs_deref_ty, _) = lhs_ty.kind() { - if self.type_is_copy_modulo_regions(self.param_env, *lhs_deref_ty, lhs_expr.span) { + && let Ref(_, lhs_deref_ty, _) = lhs_ty.kind() + { + if self.type_is_copy_modulo_regions( + self.param_env, + *lhs_deref_ty, + lhs_expr.span, + ) { suggest_deref_binop(*lhs_deref_ty); } + } else if self.suggest_fn_call(&mut err, lhs_expr, lhs_ty, |lhs_ty| { + is_compatible(lhs_ty, rhs_ty) + }) || self.suggest_fn_call(&mut err, rhs_expr, rhs_ty, |rhs_ty| { + is_compatible(lhs_ty, rhs_ty) + }) || self.suggest_two_fn_call( + &mut err, + rhs_expr, + rhs_ty, + lhs_expr, + lhs_ty, + |lhs_ty, rhs_ty| is_compatible(lhs_ty, rhs_ty), + ) { + // Cool } + if let Some(missing_trait) = missing_trait { let mut visitor = TypeParamVisitor(vec![]); visitor.visit_ty(lhs_ty); @@ -548,69 +563,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (lhs_ty, rhs_ty, return_ty) } - /// If one of the types is an uncalled function and calling it would yield the other type, - /// suggest calling the function. Returns `true` if suggestion would apply (even if not given). - fn add_type_neq_err_label( - &self, - err: &mut Diagnostic, - span: Span, - ty: Ty<'tcx>, - other_ty: Ty<'tcx>, - other_expr: &'tcx hir::Expr<'tcx>, - op: hir::BinOp, - is_assign: IsAssign, - expected: Expectation<'tcx>, - ) -> bool /* did we suggest to call a function because of missing parentheses? */ { - err.span_label(span, ty.to_string()); - if let FnDef(def_id, _) = *ty.kind() { - if !self.tcx.has_typeck_results(def_id) { - return false; - } - // FIXME: Instead of exiting early when encountering bound vars in - // the function signature, consider keeping the binder here and - // propagating it downwards. - let Some(fn_sig) = self.tcx.fn_sig(def_id).no_bound_vars() else { - return false; - }; - - let other_ty = if let FnDef(def_id, _) = *other_ty.kind() { - if !self.tcx.has_typeck_results(def_id) { - return false; - } - // We're emitting a suggestion, so we can just ignore regions - self.tcx.fn_sig(def_id).skip_binder().output() - } else { - other_ty - }; - - if self - .lookup_op_method( - fn_sig.output(), - Some(other_ty), - Some(other_expr), - Op::Binary(op, is_assign), - expected, - ) - .is_ok() - { - let (variable_snippet, applicability) = if !fn_sig.inputs().is_empty() { - ("( /* arguments */ )", Applicability::HasPlaceholders) - } else { - ("()", Applicability::MaybeIncorrect) - }; - - err.span_suggestion_verbose( - span.shrink_to_hi(), - "you might have forgotten to call this function", - variable_snippet, - applicability, - ); - return true; - } - } - false - } - /// Provide actionable suggestions when trying to add two strings with incorrect types, /// like `&str + &str`, `String + String` and `&str + &String`. /// diff --git a/src/test/ui/binop/issue-77910-2.stderr b/src/test/ui/binop/issue-77910-2.stderr index 5477a5762a8..74860a93f37 100644 --- a/src/test/ui/binop/issue-77910-2.stderr +++ b/src/test/ui/binop/issue-77910-2.stderr @@ -5,6 +5,11 @@ LL | if foo == y {} | --- ^^ - _ | | | for<'r> fn(&'r i32) -> &'r i32 {foo} + | +help: use parentheses to call this function + | +LL | if foo(_) == y {} + | +++ error: aborting due to previous error diff --git a/src/test/ui/fn/fn-compare-mismatch.stderr b/src/test/ui/fn/fn-compare-mismatch.stderr index 096440225b9..df838cb1181 100644 --- a/src/test/ui/fn/fn-compare-mismatch.stderr +++ b/src/test/ui/fn/fn-compare-mismatch.stderr @@ -6,14 +6,10 @@ LL | let x = f == g; | | | fn() {f} | -help: you might have forgotten to call this function +help: use parentheses to call these | -LL | let x = f() == g; - | ++ -help: you might have forgotten to call this function - | -LL | let x = f == g(); - | ++ +LL | let x = f() == g(); + | ++ ++ error[E0308]: mismatched types --> $DIR/fn-compare-mismatch.rs:4:18 diff --git a/src/test/ui/issues/issue-59488.stderr b/src/test/ui/issues/issue-59488.stderr index bb6843a1958..df681eb2489 100644 --- a/src/test/ui/issues/issue-59488.stderr +++ b/src/test/ui/issues/issue-59488.stderr @@ -6,7 +6,7 @@ LL | foo > 12; | | | fn() -> i32 {foo} | -help: you might have forgotten to call this function +help: use parentheses to call this function | LL | foo() > 12; | ++ @@ -28,10 +28,10 @@ LL | bar > 13; | | | fn(i64) -> i64 {bar} | -help: you might have forgotten to call this function +help: use parentheses to call this function | -LL | bar( /* arguments */ ) > 13; - | +++++++++++++++++++ +LL | bar(_) > 13; + | +++ error[E0308]: mismatched types --> $DIR/issue-59488.rs:18:11 @@ -50,14 +50,10 @@ LL | foo > foo; | | | fn() -> i32 {foo} | -help: you might have forgotten to call this function +help: use parentheses to call these | -LL | foo() > foo; - | ++ -help: you might have forgotten to call this function - | -LL | foo > foo(); - | ++ +LL | foo() > foo(); + | ++ ++ error[E0369]: binary operation `>` cannot be applied to type `fn() -> i32 {foo}` --> $DIR/issue-59488.rs:25:9 diff --git a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr index c6e6ea1e096..9239385e643 100644 --- a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr +++ b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr @@ -8,11 +8,6 @@ LL | assert_eq!(a, 0); | {integer} | = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -help: you might have forgotten to call this function - --> $SRC_DIR/core/src/macros/mod.rs:LL:COL - | -LL | if !(*left_val() == *right_val) { - | ++ error[E0308]: mismatched types --> $DIR/issue-70724-add_type_neq_err_label-unwrap.rs:6:5 @@ -21,7 +16,7 @@ LL | assert_eq!(a, 0); | ^^^^^^^^^^^^^^^^ expected fn item, found integer | = note: expected fn item `fn() -> i32 {a}` - found type `i32` + found type `{integer}` = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `fn() -> i32 {a}` doesn't implement `Debug` -- cgit 1.4.1-3-g733a5 From d1ef8180f956c9f1a7267e32491d65188f0aefd7 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 20 Aug 2022 20:40:08 +0200 Subject: Revert let_chains stabilization This reverts commit 326646074940222d602f3683d0559088690830f4. This is the revert against master, the beta revert was already done in #100538. --- compiler/rustc_ast/src/lib.rs | 1 + compiler/rustc_ast_lowering/src/lib.rs | 1 + compiler/rustc_ast_passes/src/ast_validation.rs | 28 +- compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_ast_passes/src/lib.rs | 1 + compiler/rustc_attr/src/lib.rs | 1 + compiler/rustc_borrowck/src/lib.rs | 1 + compiler/rustc_builtin_macros/src/lib.rs | 1 + compiler/rustc_codegen_llvm/src/lib.rs | 1 + compiler/rustc_const_eval/src/lib.rs | 1 + compiler/rustc_error_messages/src/lib.rs | 1 + compiler/rustc_errors/src/lib.rs | 1 + compiler/rustc_expand/src/lib.rs | 1 + compiler/rustc_feature/src/accepted.rs | 2 - compiler/rustc_feature/src/active.rs | 2 + compiler/rustc_infer/src/lib.rs | 1 + compiler/rustc_lint/src/lib.rs | 1 + compiler/rustc_metadata/src/lib.rs | 1 + compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_mir_build/src/lib.rs | 1 + compiler/rustc_mir_transform/src/lib.rs | 1 + compiler/rustc_parse/src/lib.rs | 1 + compiler/rustc_parse/src/parser/expr.rs | 28 +- compiler/rustc_passes/src/lib.rs | 1 + compiler/rustc_resolve/src/lib.rs | 1 + compiler/rustc_session/src/lib.rs | 1 + compiler/rustc_trait_selection/src/lib.rs | 1 + compiler/rustc_typeck/src/lib.rs | 1 + library/std/src/lib.rs | 1 + src/librustdoc/lib.rs | 1 + src/test/ui/expr/if/attrs/let-chains-attr.rs | 2 + src/test/ui/expr/if/bad-if-let-suggestion.rs | 1 + src/test/ui/expr/if/bad-if-let-suggestion.stderr | 21 +- src/test/ui/mir/issue-92893.rs | 1 + src/test/ui/mir/issue-92893.stderr | 12 +- src/test/ui/mir/mir_let_chains_drop_order.rs | 1 + src/test/ui/rfc-2294-if-let-guard/feature-gate.rs | 30 +- .../ui/rfc-2294-if-let-guard/feature-gate.stderr | 178 ++++++- .../ui/rfc-2497-if-let-chains/allowed-syntax.rs | 30 -- .../ast-lowering-does-not-wrap-let-chains.rs | 1 + .../rfc-2497-if-let-chains/disallowed-positions.rs | 11 +- .../disallowed-positions.stderr | 564 ++++++++++----------- ...t-let-else-does-not-interact-with-let-chains.rs | 2 +- src/test/ui/rfc-2497-if-let-chains/feature-gate.rs | 62 +++ .../ui/rfc-2497-if-let-chains/feature-gate.stderr | 114 +++++ .../invalid-let-in-a-valid-let-context.rs | 2 + .../invalid-let-in-a-valid-let-context.stderr | 12 +- .../ui/rfc-2497-if-let-chains/irrefutable-lets.rs | 2 +- src/test/ui/rfc-2497-if-let-chains/issue-90722.rs | 2 + src/test/ui/rfc-2497-if-let-chains/issue-92145.rs | 2 + src/test/ui/rfc-2497-if-let-chains/issue-93150.rs | 1 + .../ui/rfc-2497-if-let-chains/issue-93150.stderr | 11 +- .../ui/rfc-2497-if-let-chains/then-else-blocks.rs | 2 +- src/tools/clippy/clippy_dev/src/lib.rs | 1 + src/tools/clippy/clippy_lints/src/lib.rs | 1 + src/tools/clippy/clippy_utils/src/lib.rs | 1 + src/tools/clippy/tests/ui/needless_late_init.fixed | 1 + src/tools/clippy/tests/ui/needless_late_init.rs | 1 + .../clippy/tests/ui/needless_late_init.stderr | 32 +- 59 files changed, 791 insertions(+), 396 deletions(-) delete mode 100644 src/test/ui/rfc-2497-if-let-chains/allowed-syntax.rs create mode 100644 src/test/ui/rfc-2497-if-let-chains/feature-gate.rs create mode 100644 src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index f9b4d76f28f..27061f300a2 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -14,6 +14,7 @@ #![feature(const_trait_impl)] #![feature(if_let_guard)] #![cfg_attr(bootstrap, feature(label_break_value))] +#![feature(let_chains)] #![feature(min_specialization)] #![feature(negative_impls)] #![feature(slice_internals)] diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index becb67d1165..5e9e8aa553d 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -31,6 +31,7 @@ //! in the HIR, especially for multiple identifiers. #![feature(box_patterns)] +#![feature(let_chains)] #![feature(let_else)] #![feature(never_type)] #![recursion_limit = "256"] diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index b337e5328c5..b46274e4a76 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -119,7 +119,33 @@ impl<'a> AstValidator<'a> { /// Emits an error banning the `let` expression provided in the given location. fn ban_let_expr(&self, expr: &'a Expr, forbidden_let_reason: ForbiddenLetReason) { - self.session.emit_err(ForbiddenLet { span: expr.span, reason: forbidden_let_reason }); + let sess = &self.session; + if sess.opts.unstable_features.is_nightly_build() { + let err = "`let` expressions are not supported here"; + let mut diag = sess.struct_span_err(expr.span, err); + diag.note("only supported directly in conditions of `if` and `while` expressions"); + match forbidden_let_reason { + ForbiddenLetReason::GenericForbidden => {} + ForbiddenLetReason::NotSupportedOr(span) => { + diag.span_note( + span, + "`||` operators are not supported in let chain expressions", + ); + } + ForbiddenLetReason::NotSupportedParentheses(span) => { + diag.span_note( + span, + "`let`s wrapped in parentheses are not supported in a context with let \ + chains", + ); + } + } + diag.emit(); + } else { + sess.struct_span_err(expr.span, "expected expression, found statement (`let`)") + .note("variable declaration using `let` is a statement") + .emit(); + } } fn check_gat_where( diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 4ac96ec8b60..6f7e88eb86f 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -777,6 +777,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { "`if let` guards are experimental", "you can write `if matches!(, )` instead of `if let = `" ); + gate_all!(let_chains, "`let` expressions in this position are unstable"); gate_all!( async_closure, "async closures are unstable", diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index 6a826298985..f282ff251bd 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -8,6 +8,7 @@ #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(iter_is_partitioned)] +#![feature(let_chains)] #![feature(let_else)] #![recursion_limit = "256"] diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs index 3a43f1aad02..053f848aacb 100644 --- a/compiler/rustc_attr/src/lib.rs +++ b/compiler/rustc_attr/src/lib.rs @@ -4,6 +4,7 @@ //! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax` //! to this crate. +#![feature(let_chains)] #![feature(let_else)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 0f8afb038f4..66fe49e9d12 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2,6 +2,7 @@ #![allow(rustc::potential_query_instability)] #![feature(box_patterns)] +#![feature(let_chains)] #![feature(let_else)] #![feature(min_specialization)] #![feature(never_type)] diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 48e81eb13c0..11565ba72d7 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -8,6 +8,7 @@ #![feature(decl_macro)] #![feature(if_let_guard)] #![feature(is_sorted)] +#![feature(let_chains)] #![feature(let_else)] #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index c80ad692000..636d689a34b 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -6,6 +6,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(hash_raw_entry)] +#![feature(let_chains)] #![feature(let_else)] #![feature(extern_types)] #![feature(once_cell)] diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 7272ae5aa09..72ac6af685d 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -9,6 +9,7 @@ Rust MIR: a lowered representation of Rust. #![feature(control_flow_enum)] #![feature(decl_macro)] #![feature(exact_size_is_empty)] +#![feature(let_chains)] #![feature(let_else)] #![feature(map_try_insert)] #![feature(min_specialization)] diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index b17668dc0ae..d1ac326a72c 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -1,3 +1,4 @@ +#![feature(let_chains)] #![feature(once_cell)] #![feature(rustc_attrs)] #![feature(type_alias_impl_trait)] diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 9b9c334d4df..7b0f4354afd 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -6,6 +6,7 @@ #![feature(drain_filter)] #![feature(if_let_guard)] #![feature(adt_const_params)] +#![feature(let_chains)] #![feature(let_else)] #![feature(never_type)] #![feature(result_option_inspect)] diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index e1dde1672c1..75dcbd69674 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -2,6 +2,7 @@ #![feature(associated_type_bounds)] #![feature(associated_type_defaults)] #![feature(if_let_guard)] +#![feature(let_chains)] #![feature(let_else)] #![feature(macro_metavar_expr)] #![feature(proc_macro_diagnostic)] diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index fb1ad8d6beb..c22adf77a27 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -188,8 +188,6 @@ declare_features! ( (accepted, item_like_imports, "1.15.0", Some(35120), None), /// Allows `'a: { break 'a; }`. (accepted, label_break_value, "CURRENT_RUSTC_VERSION", Some(48594), None), - /// Allows `if/while p && let q = r && ...` chains. - (accepted, let_chains, "1.64.0", Some(53667), None), /// Allows `break {expr}` with a value inside `loop`s. (accepted, loop_break_value, "1.19.0", Some(37339), None), /// Allows use of `?` as the Kleene "at most one" operator in macros. diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 22178dd2123..a5091621f66 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -422,6 +422,8 @@ declare_features! ( (active, isa_attribute, "1.48.0", Some(74727), None), // Allows setting the threshold for the `large_assignments` lint. (active, large_assignments, "1.52.0", Some(83518), None), + /// Allows `if/while p && let q = r && ...` chains. + (active, let_chains, "1.37.0", Some(53667), None), /// Allows `let...else` statements. (active, let_else, "1.56.0", Some(87335), None), /// Allows `#[link(..., cfg(..))]`. diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 602a9ab13f3..931ebca7d01 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -18,6 +18,7 @@ #![feature(control_flow_enum)] #![feature(extend_one)] #![cfg_attr(bootstrap, feature(label_break_value))] +#![feature(let_chains)] #![feature(let_else)] #![feature(min_specialization)] #![feature(never_type)] diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index f34e062fd12..c3065e4a2d9 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -33,6 +33,7 @@ #![feature(if_let_guard)] #![feature(iter_intersperse)] #![feature(iter_order_by)] +#![feature(let_chains)] #![feature(let_else)] #![feature(never_type)] #![recursion_limit = "256"] diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 75069a5f0dc..6440f3e390c 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -4,6 +4,7 @@ #![feature(generators)] #![feature(generic_associated_types)] #![feature(iter_from_generator)] +#![feature(let_chains)] #![feature(let_else)] #![feature(once_cell)] #![feature(proc_macro_internals)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 6a6505d0256..be9e5865e54 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -39,6 +39,7 @@ #![feature(extern_types)] #![feature(new_uninit)] #![feature(once_cell)] +#![feature(let_chains)] #![feature(let_else)] #![feature(min_specialization)] #![feature(trusted_len)] diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index e51ca65dc16..11cd2a9aa4d 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -5,6 +5,7 @@ #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(if_let_guard)] +#![feature(let_chains)] #![feature(let_else)] #![feature(min_specialization)] #![feature(once_cell)] diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 56fb601d2b5..75851bf9dfd 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -1,5 +1,6 @@ #![allow(rustc::potential_query_instability)] #![feature(box_patterns)] +#![feature(let_chains)] #![feature(let_else)] #![feature(map_try_insert)] #![feature(min_specialization)] diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 3691d82a835..3c88e1ef377 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -3,6 +3,7 @@ #![feature(array_windows)] #![feature(box_patterns)] #![feature(if_let_guard)] +#![feature(let_chains)] #![feature(let_else)] #![feature(never_type)] #![feature(rustc_attrs)] diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 18aa109d7a6..c8541609514 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2251,7 +2251,15 @@ impl<'a> Parser<'a> { /// Parses the condition of a `if` or `while` expression. fn parse_cond_expr(&mut self) -> PResult<'a, P> { - self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL | Restrictions::ALLOW_LET, None) + let cond = + self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL | Restrictions::ALLOW_LET, None)?; + + if let ExprKind::Let(..) = cond.kind { + // Remove the last feature gating of a `let` expression since it's stable. + self.sess.gated_spans.ungate_last(sym::let_chains, cond.span); + } + + Ok(cond) } /// Parses a `let $pat = $expr` pseudo-expression. @@ -2280,6 +2288,7 @@ impl<'a> Parser<'a> { this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into()) })?; let span = lo.to(expr.span); + self.sess.gated_spans.gate(sym::let_chains, span); Ok(self.mk_expr(span, ExprKind::Let(pat, expr, span))) } @@ -2571,13 +2580,15 @@ impl<'a> Parser<'a> { pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> { // Used to check the `let_chains` and `if_let_guard` features mostly by scaning // `&&` tokens. - fn check_let_expr(expr: &Expr) -> bool { + fn check_let_expr(expr: &Expr) -> (bool, bool) { match expr.kind { ExprKind::Binary(BinOp { node: BinOpKind::And, .. }, ref lhs, ref rhs) => { - check_let_expr(lhs) || check_let_expr(rhs) + let lhs_rslt = check_let_expr(lhs); + let rhs_rslt = check_let_expr(rhs); + (lhs_rslt.0 || rhs_rslt.0, false) } - ExprKind::Let(..) => true, - _ => false, + ExprKind::Let(..) => (true, true), + _ => (false, true), } } let attrs = self.parse_outer_attributes()?; @@ -2592,7 +2603,12 @@ impl<'a> Parser<'a> { let guard = if this.eat_keyword(kw::If) { let if_span = this.prev_token.span; let cond = this.parse_expr_res(Restrictions::ALLOW_LET, None)?; - if check_let_expr(&cond) { + let (has_let_expr, does_not_have_bin_op) = check_let_expr(&cond); + if has_let_expr { + if does_not_have_bin_op { + // Remove the last feature gating of a `let` expression since it's stable. + this.sess.gated_spans.ungate_last(sym::let_chains, cond.span); + } let span = if_span.to(cond.span); this.sess.gated_spans.gate(sym::if_let_guard, span); } diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 4af041dac0d..7b2f83958af 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -7,6 +7,7 @@ #![allow(rustc::potential_query_instability)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(iter_intersperse)] +#![feature(let_chains)] #![feature(let_else)] #![feature(map_try_insert)] #![feature(min_specialization)] diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index eb727debc91..d91a58b13ff 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -11,6 +11,7 @@ #![feature(drain_filter)] #![feature(if_let_guard)] #![feature(iter_intersperse)] +#![feature(let_chains)] #![feature(let_else)] #![feature(never_type)] #![recursion_limit = "256"] diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 0617bd5fae7..7353c1ca0e2 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -1,4 +1,5 @@ #![feature(if_let_guard)] +#![feature(let_chains)] #![feature(let_else)] #![feature(min_specialization)] #![feature(never_type)] diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index e0dd28bee30..77cc2c164c3 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -17,6 +17,7 @@ #![feature(drain_filter)] #![feature(hash_drain_filter)] #![cfg_attr(bootstrap, feature(label_break_value))] +#![feature(let_chains)] #![feature(let_else)] #![feature(if_let_guard)] #![feature(never_type)] diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index 5699f642baf..8e910441a5d 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -65,6 +65,7 @@ This API is completely unstable and subject to change. #![feature(is_sorted)] #![feature(iter_intersperse)] #![cfg_attr(bootstrap, feature(label_break_value))] +#![feature(let_chains)] #![feature(let_else)] #![feature(min_specialization)] #![feature(never_type)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index f5dcdab4cd5..b0fef492d92 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -254,6 +254,7 @@ #![feature(intra_doc_pointers)] #![cfg_attr(bootstrap, feature(label_break_value))] #![feature(lang_items)] +#![feature(let_chains)] #![feature(let_else)] #![feature(linkage)] #![feature(link_cfg)] diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 8aede1e77a2..92380d12429 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -8,6 +8,7 @@ #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(drain_filter)] +#![feature(let_chains)] #![feature(let_else)] #![feature(test)] #![feature(never_type)] diff --git a/src/test/ui/expr/if/attrs/let-chains-attr.rs b/src/test/ui/expr/if/attrs/let-chains-attr.rs index d62c2cb403f..2cd8731141a 100644 --- a/src/test/ui/expr/if/attrs/let-chains-attr.rs +++ b/src/test/ui/expr/if/attrs/let-chains-attr.rs @@ -1,5 +1,7 @@ // check-pass +#![feature(let_chains)] + #[cfg(FALSE)] fn foo() { #[attr] diff --git a/src/test/ui/expr/if/bad-if-let-suggestion.rs b/src/test/ui/expr/if/bad-if-let-suggestion.rs index 070a5b20128..a8b2a283039 100644 --- a/src/test/ui/expr/if/bad-if-let-suggestion.rs +++ b/src/test/ui/expr/if/bad-if-let-suggestion.rs @@ -4,6 +4,7 @@ fn a() { if let x = 1 && i = 2 {} //~^ ERROR cannot find value `i` in this scope + //~| ERROR `let` expressions in this position are unstable //~| ERROR mismatched types //~| ERROR `let` expressions are not supported here } diff --git a/src/test/ui/expr/if/bad-if-let-suggestion.stderr b/src/test/ui/expr/if/bad-if-let-suggestion.stderr index 9f7a21c7d1a..60d286fedf5 100644 --- a/src/test/ui/expr/if/bad-if-let-suggestion.stderr +++ b/src/test/ui/expr/if/bad-if-let-suggestion.stderr @@ -13,7 +13,7 @@ LL | if let x = 1 && i = 2 {} | ^ not found in this scope error[E0425]: cannot find value `i` in this scope - --> $DIR/bad-if-let-suggestion.rs:12:9 + --> $DIR/bad-if-let-suggestion.rs:13:9 | LL | fn a() { | ------ similarly named function `a` defined here @@ -22,7 +22,7 @@ LL | if (i + j) = i {} | ^ help: a function with a similar name exists: `a` error[E0425]: cannot find value `j` in this scope - --> $DIR/bad-if-let-suggestion.rs:12:13 + --> $DIR/bad-if-let-suggestion.rs:13:13 | LL | fn a() { | ------ similarly named function `a` defined here @@ -31,7 +31,7 @@ LL | if (i + j) = i {} | ^ help: a function with a similar name exists: `a` error[E0425]: cannot find value `i` in this scope - --> $DIR/bad-if-let-suggestion.rs:12:18 + --> $DIR/bad-if-let-suggestion.rs:13:18 | LL | fn a() { | ------ similarly named function `a` defined here @@ -40,7 +40,7 @@ LL | if (i + j) = i {} | ^ help: a function with a similar name exists: `a` error[E0425]: cannot find value `x` in this scope - --> $DIR/bad-if-let-suggestion.rs:19:8 + --> $DIR/bad-if-let-suggestion.rs:20:8 | LL | fn a() { | ------ similarly named function `a` defined here @@ -48,13 +48,22 @@ LL | fn a() { LL | if x[0] = 1 {} | ^ help: a function with a similar name exists: `a` +error[E0658]: `let` expressions in this position are unstable + --> $DIR/bad-if-let-suggestion.rs:5:8 + | +LL | if let x = 1 && i = 2 {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + error[E0308]: mismatched types --> $DIR/bad-if-let-suggestion.rs:5:8 | LL | if let x = 1 && i = 2 {} | ^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` -error: aborting due to 7 previous errors +error: aborting due to 8 previous errors -Some errors have detailed explanations: E0308, E0425. +Some errors have detailed explanations: E0308, E0425, E0658. For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/mir/issue-92893.rs b/src/test/ui/mir/issue-92893.rs index c2827c7e37f..635050f376c 100644 --- a/src/test/ui/mir/issue-92893.rs +++ b/src/test/ui/mir/issue-92893.rs @@ -1,5 +1,6 @@ struct Bug { //~^ `let` expressions are not supported here + //~| `let` expressions in this position are unstable [E0658] //~| expected expression, found `let` statement a: A } diff --git a/src/test/ui/mir/issue-92893.stderr b/src/test/ui/mir/issue-92893.stderr index bd4654edf4b..4a0fcce31d7 100644 --- a/src/test/ui/mir/issue-92893.stderr +++ b/src/test/ui/mir/issue-92893.stderr @@ -12,5 +12,15 @@ LL | struct Bug { | = note: only supported directly in conditions of `if` and `while` expressions -error: aborting due to 2 previous errors +error[E0658]: `let` expressions in this position are unstable + --> $DIR/issue-92893.rs:1:22 + | +LL | struct Bug { + | ^^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/mir/mir_let_chains_drop_order.rs b/src/test/ui/mir/mir_let_chains_drop_order.rs index 21e7b5070af..6498a519571 100644 --- a/src/test/ui/mir/mir_let_chains_drop_order.rs +++ b/src/test/ui/mir/mir_let_chains_drop_order.rs @@ -4,6 +4,7 @@ // See `mir_drop_order.rs` for more information +#![feature(let_chains)] #![allow(irrefutable_let_patterns)] use std::cell::RefCell; diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs index 0fe50932b4b..f0105e08e27 100644 --- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs +++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs @@ -8,35 +8,49 @@ fn _if_let_guard() { //~^ ERROR `if let` guards are experimental () if (let 0 = 1) => {} - //~^ ERROR expected expression, found `let` statement + //~^ ERROR `let` expressions in this position are unstable + //~| ERROR expected expression, found `let` statement () if (((let 0 = 1))) => {} - //~^ ERROR expected expression, found `let` statement + //~^ ERROR `let` expressions in this position are unstable + //~| ERROR expected expression, found `let` statement () if true && let 0 = 1 => {} //~^ ERROR `if let` guards are experimental + //~| ERROR `let` expressions in this position are unstable () if let 0 = 1 && true => {} //~^ ERROR `if let` guards are experimental + //~| ERROR `let` expressions in this position are unstable () if (let 0 = 1) && true => {} - //~^ ERROR expected expression, found `let` statement + //~^ ERROR `let` expressions in this position are unstable + //~| ERROR expected expression, found `let` statement () if true && (let 0 = 1) => {} - //~^ ERROR expected expression, found `let` statement + //~^ ERROR `let` expressions in this position are unstable + //~| ERROR expected expression, found `let` statement () if (let 0 = 1) && (let 0 = 1) => {} - //~^ ERROR expected expression, found `let` statement + //~^ ERROR `let` expressions in this position are unstable + //~| ERROR `let` expressions in this position are unstable + //~| ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} //~^ ERROR `if let` guards are experimental + //~| ERROR `let` expressions in this position are unstable + //~| ERROR `let` expressions in this position are unstable + //~| ERROR `let` expressions in this position are unstable + //~| ERROR `let` expressions in this position are unstable + //~| ERROR `let` expressions in this position are unstable //~| ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement () if let Range { start: _, end: _ } = (true..true) && false => {} //~^ ERROR `if let` guards are experimental + //~| ERROR `let` expressions in this position are unstable _ => {} } @@ -52,9 +66,11 @@ fn _macros() { } } use_expr!((let 0 = 1 && 0 == 0)); - //~^ ERROR expected expression, found `let` statement + //~^ ERROR `let` expressions in this position are unstable + //~| ERROR expected expression, found `let` statement use_expr!((let 0 = 1)); - //~^ ERROR expected expression, found `let` statement + //~^ ERROR `let` expressions in this position are unstable + //~| ERROR expected expression, found `let` statement match () { #[cfg(FALSE)] () if let 0 = 1 => {} diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr index 35db84a6cb7..e017d04a5c9 100644 --- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr +++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr @@ -5,67 +5,67 @@ LL | () if (let 0 = 1) => {} | ^^^ error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:13:18 + --> $DIR/feature-gate.rs:14:18 | LL | () if (((let 0 = 1))) => {} | ^^^ error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:22:16 + --> $DIR/feature-gate.rs:26:16 | LL | () if (let 0 = 1) && true => {} | ^^^ error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:25:24 + --> $DIR/feature-gate.rs:30:24 | LL | () if true && (let 0 = 1) => {} | ^^^ error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:28:16 + --> $DIR/feature-gate.rs:34:16 | LL | () if (let 0 = 1) && (let 0 = 1) => {} | ^^^ error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:28:31 + --> $DIR/feature-gate.rs:34:31 | LL | () if (let 0 = 1) && (let 0 = 1) => {} | ^^^ error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:32:42 + --> $DIR/feature-gate.rs:40:42 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^ error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:32:55 + --> $DIR/feature-gate.rs:40:55 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^ error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:32:68 + --> $DIR/feature-gate.rs:40:68 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^ error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:54:16 + --> $DIR/feature-gate.rs:68:16 | LL | use_expr!((let 0 = 1 && 0 == 0)); | ^^^ error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:56:16 + --> $DIR/feature-gate.rs:71:16 | LL | use_expr!((let 0 = 1)); | ^^^ error: no rules expected the token `let` - --> $DIR/feature-gate.rs:64:15 + --> $DIR/feature-gate.rs:80:15 | LL | macro_rules! use_expr { | --------------------- when calling this macro @@ -84,7 +84,7 @@ LL | () if let 0 = 1 => {} = help: you can write `if matches!(, )` instead of `if let = ` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:16:12 + --> $DIR/feature-gate.rs:18:12 | LL | () if true && let 0 = 1 => {} | ^^^^^^^^^^^^^^^^^^^^ @@ -94,7 +94,7 @@ LL | () if true && let 0 = 1 => {} = help: you can write `if matches!(, )` instead of `if let = ` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:19:12 + --> $DIR/feature-gate.rs:22:12 | LL | () if let 0 = 1 && true => {} | ^^^^^^^^^^^^^^^^^^^^ @@ -104,7 +104,7 @@ LL | () if let 0 = 1 && true => {} = help: you can write `if matches!(, )` instead of `if let = ` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:32:12 + --> $DIR/feature-gate.rs:40:12 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,7 +114,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = help: you can write `if matches!(, )` instead of `if let = ` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:38:12 + --> $DIR/feature-gate.rs:51:12 | LL | () if let Range { start: _, end: _ } = (true..true) && false => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -124,7 +124,7 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {} = help: you can write `if matches!(, )` instead of `if let = ` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:60:12 + --> $DIR/feature-gate.rs:76:12 | LL | () if let 0 = 1 => {} | ^^^^^^^^^^^^ @@ -133,6 +133,150 @@ LL | () if let 0 = 1 => {} = help: add `#![feature(if_let_guard)]` to the crate attributes to enable = help: you can write `if matches!(, )` instead of `if let = ` -error: aborting due to 18 previous errors +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:10:16 + | +LL | () if (let 0 = 1) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:14:18 + | +LL | () if (((let 0 = 1))) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:18:23 + | +LL | () if true && let 0 = 1 => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:22:15 + | +LL | () if let 0 = 1 && true => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:26:16 + | +LL | () if (let 0 = 1) && true => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:30:24 + | +LL | () if true && (let 0 = 1) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:34:16 + | +LL | () if (let 0 = 1) && (let 0 = 1) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:34:31 + | +LL | () if (let 0 = 1) && (let 0 = 1) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:40:15 + | +LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:40:28 + | +LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:40:42 + | +LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:40:55 + | +LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:40:68 + | +LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:51:15 + | +LL | () if let Range { start: _, end: _ } = (true..true) && false => {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:68:16 + | +LL | use_expr!((let 0 = 1 && 0 == 0)); + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:71:16 + | +LL | use_expr!((let 0 = 1)); + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error: aborting due to 34 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2497-if-let-chains/allowed-syntax.rs b/src/test/ui/rfc-2497-if-let-chains/allowed-syntax.rs deleted file mode 100644 index ffe0499fda2..00000000000 --- a/src/test/ui/rfc-2497-if-let-chains/allowed-syntax.rs +++ /dev/null @@ -1,30 +0,0 @@ -// check-pass - -#![allow(irrefutable_let_patterns)] - -use std::ops::Range; - -fn _if() { - if let 0 = 1 {} - - if true && let 0 = 1 {} - - if let 0 = 1 && true {} - - if let Range { start: _, end: _ } = (true..true) && false {} - - if let 1 = 1 && let true = { true } && false { - } -} - -fn _while() { - while let 0 = 1 {} - - while true && let 0 = 1 {} - - while let 0 = 1 && true {} - - while let Range { start: _, end: _ } = (true..true) && false {} -} - -fn main() {} diff --git a/src/test/ui/rfc-2497-if-let-chains/ast-lowering-does-not-wrap-let-chains.rs b/src/test/ui/rfc-2497-if-let-chains/ast-lowering-does-not-wrap-let-chains.rs index 82164bda489..d851fac8e64 100644 --- a/src/test/ui/rfc-2497-if-let-chains/ast-lowering-does-not-wrap-let-chains.rs +++ b/src/test/ui/rfc-2497-if-let-chains/ast-lowering-does-not-wrap-let-chains.rs @@ -1,5 +1,6 @@ // run-pass +#![feature(let_chains)] #![allow(irrefutable_let_patterns)] fn main() { diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs index e8f1ff9c3fd..2a9a5472b2e 100644 --- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs +++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs @@ -17,6 +17,8 @@ // // To that end, we check some positions which is not part of the language above. +#![feature(let_chains)] // Avoid inflating `.stderr` with overzealous gates in this test. + #![allow(irrefutable_let_patterns)] use std::ops::Range; @@ -102,12 +104,6 @@ fn _macros() { //~^ ERROR `let` expressions are not supported here //~| ERROR `let` expressions are not supported here //~| ERROR expected expression, found `let` statement - use_expr!(true && let 0 = 1); - //~^ ERROR expected expression, found `let` statement - - macro_rules! noop_expr { ($e:expr) => {}; } - noop_expr!((let 0 = 1)); - //~^ ERROR expected expression, found `let` statement } fn nested_within_if_expr() { @@ -481,7 +477,4 @@ fn with_parenthesis() { ([1, 2, 3][let _ = ()]) //~^ ERROR expected expression, found `let` statement } - - #[cfg(FALSE)] (let 0 = 1); - //~^ ERROR expected expression, found `let` statement } diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr index d5d82166a4a..fce0cdfe0d5 100644 --- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr @@ -1,413 +1,413 @@ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:27:9 + --> $DIR/disallowed-positions.rs:29:9 | LL | if (let 0 = 1) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:31:11 + --> $DIR/disallowed-positions.rs:33:11 | LL | if (((let 0 = 1))) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:35:9 + --> $DIR/disallowed-positions.rs:37:9 | LL | if (let 0 = 1) && true {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:39:17 + --> $DIR/disallowed-positions.rs:41:17 | LL | if true && (let 0 = 1) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:43:9 + --> $DIR/disallowed-positions.rs:45:9 | LL | if (let 0 = 1) && (let 0 = 1) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:43:24 + --> $DIR/disallowed-positions.rs:45:24 | LL | if (let 0 = 1) && (let 0 = 1) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:49:35 + --> $DIR/disallowed-positions.rs:51:35 | LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:49:48 + --> $DIR/disallowed-positions.rs:51:48 | LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:49:61 + --> $DIR/disallowed-positions.rs:51:61 | LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:59:12 + --> $DIR/disallowed-positions.rs:61:12 | LL | while (let 0 = 1) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:63:14 + --> $DIR/disallowed-positions.rs:65:14 | LL | while (((let 0 = 1))) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:67:12 + --> $DIR/disallowed-positions.rs:69:12 | LL | while (let 0 = 1) && true {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:71:20 + --> $DIR/disallowed-positions.rs:73:20 | LL | while true && (let 0 = 1) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:75:12 + --> $DIR/disallowed-positions.rs:77:12 | LL | while (let 0 = 1) && (let 0 = 1) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:75:27 + --> $DIR/disallowed-positions.rs:77:27 | LL | while (let 0 = 1) && (let 0 = 1) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:81:38 + --> $DIR/disallowed-positions.rs:83:38 | LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:81:51 + --> $DIR/disallowed-positions.rs:83:51 | LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:81:64 + --> $DIR/disallowed-positions.rs:83:64 | LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:114:9 + --> $DIR/disallowed-positions.rs:110:9 | LL | if &let 0 = 0 {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:119:9 + --> $DIR/disallowed-positions.rs:115:9 | LL | if !let 0 = 0 {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:122:9 + --> $DIR/disallowed-positions.rs:118:9 | LL | if *let 0 = 0 {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:126:9 + --> $DIR/disallowed-positions.rs:122:9 | LL | if -let 0 = 0 {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:136:9 + --> $DIR/disallowed-positions.rs:132:9 | LL | if (let 0 = 0)? {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:142:16 + --> $DIR/disallowed-positions.rs:138:16 | LL | if true || let 0 = 0 {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:145:17 + --> $DIR/disallowed-positions.rs:141:17 | LL | if (true || let 0 = 0) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:148:25 + --> $DIR/disallowed-positions.rs:144:25 | LL | if true && (true || let 0 = 0) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:151:25 + --> $DIR/disallowed-positions.rs:147:25 | LL | if true || (true && let 0 = 0) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:156:12 + --> $DIR/disallowed-positions.rs:152:12 | LL | if x = let 0 = 0 {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:161:15 + --> $DIR/disallowed-positions.rs:157:15 | LL | if true..(let 0 = 0) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:165:11 + --> $DIR/disallowed-positions.rs:161:11 | LL | if ..(let 0 = 0) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:169:9 + --> $DIR/disallowed-positions.rs:165:9 | LL | if (let 0 = 0).. {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:200:19 + --> $DIR/disallowed-positions.rs:196:19 | LL | if let true = let true = true {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:206:12 + --> $DIR/disallowed-positions.rs:202:12 | LL | while &let 0 = 0 {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:211:12 + --> $DIR/disallowed-positions.rs:207:12 | LL | while !let 0 = 0 {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:214:12 + --> $DIR/disallowed-positions.rs:210:12 | LL | while *let 0 = 0 {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:218:12 + --> $DIR/disallowed-positions.rs:214:12 | LL | while -let 0 = 0 {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:228:12 + --> $DIR/disallowed-positions.rs:224:12 | LL | while (let 0 = 0)? {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:234:19 + --> $DIR/disallowed-positions.rs:230:19 | LL | while true || let 0 = 0 {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:237:20 + --> $DIR/disallowed-positions.rs:233:20 | LL | while (true || let 0 = 0) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:240:28 + --> $DIR/disallowed-positions.rs:236:28 | LL | while true && (true || let 0 = 0) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:243:28 + --> $DIR/disallowed-positions.rs:239:28 | LL | while true || (true && let 0 = 0) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:248:15 + --> $DIR/disallowed-positions.rs:244:15 | LL | while x = let 0 = 0 {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:253:18 + --> $DIR/disallowed-positions.rs:249:18 | LL | while true..(let 0 = 0) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:257:14 + --> $DIR/disallowed-positions.rs:253:14 | LL | while ..(let 0 = 0) {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:261:12 + --> $DIR/disallowed-positions.rs:257:12 | LL | while (let 0 = 0).. {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:292:22 + --> $DIR/disallowed-positions.rs:288:22 | LL | while let true = let true = true {} | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:308:6 + --> $DIR/disallowed-positions.rs:304:6 | LL | &let 0 = 0; | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:312:6 + --> $DIR/disallowed-positions.rs:308:6 | LL | !let 0 = 0; | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:315:6 + --> $DIR/disallowed-positions.rs:311:6 | LL | *let 0 = 0; | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:319:6 + --> $DIR/disallowed-positions.rs:315:6 | LL | -let 0 = 0; | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:329:6 + --> $DIR/disallowed-positions.rs:325:6 | LL | (let 0 = 0)?; | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:335:13 + --> $DIR/disallowed-positions.rs:331:13 | LL | true || let 0 = 0; | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:338:14 + --> $DIR/disallowed-positions.rs:334:14 | LL | (true || let 0 = 0); | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:341:22 + --> $DIR/disallowed-positions.rs:337:22 | LL | true && (true || let 0 = 0); | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:346:9 + --> $DIR/disallowed-positions.rs:342:9 | LL | x = let 0 = 0; | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:350:12 + --> $DIR/disallowed-positions.rs:346:12 | LL | true..(let 0 = 0); | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:353:8 + --> $DIR/disallowed-positions.rs:349:8 | LL | ..(let 0 = 0); | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:356:6 + --> $DIR/disallowed-positions.rs:352:6 | LL | (let 0 = 0)..; | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:360:6 + --> $DIR/disallowed-positions.rs:356:6 | LL | (let Range { start: _, end: _ } = true..true || false); | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:365:6 + --> $DIR/disallowed-positions.rs:361:6 | LL | (let true = let true = true); | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:365:17 + --> $DIR/disallowed-positions.rs:361:17 | LL | (let true = let true = true); | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:372:25 + --> $DIR/disallowed-positions.rs:368:25 | LL | let x = true && let y = 1; | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:378:19 + --> $DIR/disallowed-positions.rs:374:19 | LL | [1, 2, 3][let _ = ()] | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:383:6 + --> $DIR/disallowed-positions.rs:379:6 | LL | &let 0 = 0 | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:395:17 + --> $DIR/disallowed-positions.rs:391:17 | LL | true && let 1 = 1 | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:401:17 + --> $DIR/disallowed-positions.rs:397:17 | LL | true && let 1 = 1 | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:407:17 + --> $DIR/disallowed-positions.rs:403:17 | LL | true && let 1 = 1 | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:419:17 + --> $DIR/disallowed-positions.rs:415:17 | LL | true && let 1 = 1 | ^^^ error: expressions must be enclosed in braces to be used as const generic arguments - --> $DIR/disallowed-positions.rs:419:9 + --> $DIR/disallowed-positions.rs:415:9 | LL | true && let 1 = 1 | ^^^^^^^^^^^^^^^^^ @@ -418,389 +418,371 @@ LL | { true && let 1 = 1 } | + + error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:429:9 + --> $DIR/disallowed-positions.rs:425:9 | LL | if (let Some(a) = opt && true) { | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:434:9 + --> $DIR/disallowed-positions.rs:430:9 | LL | if (let Some(a) = opt) && true { | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:438:9 + --> $DIR/disallowed-positions.rs:434:9 | LL | if (let Some(a) = opt) && (let Some(b) = a) { | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:438:32 + --> $DIR/disallowed-positions.rs:434:32 | LL | if (let Some(a) = opt) && (let Some(b) = a) { | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:447:9 + --> $DIR/disallowed-positions.rs:443:9 | LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:447:31 + --> $DIR/disallowed-positions.rs:443:31 | LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:453:9 + --> $DIR/disallowed-positions.rs:449:9 | LL | if (let Some(a) = opt && (let Some(b) = a)) && true { | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:453:31 + --> $DIR/disallowed-positions.rs:449:31 | LL | if (let Some(a) = opt && (let Some(b) = a)) && true { | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:459:9 + --> $DIR/disallowed-positions.rs:455:9 | LL | if (let Some(a) = opt && (true)) && true { | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:476:22 + --> $DIR/disallowed-positions.rs:472:22 | LL | let x = (true && let y = 1); | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:481:20 + --> $DIR/disallowed-positions.rs:477:20 | LL | ([1, 2, 3][let _ = ()]) | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:485:20 - | -LL | #[cfg(FALSE)] (let 0 = 1); - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:97:16 + --> $DIR/disallowed-positions.rs:99:16 | LL | use_expr!((let 0 = 1 && 0 == 0)); | ^^^ error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:101:16 + --> $DIR/disallowed-positions.rs:103:16 | LL | use_expr!((let 0 = 1)); | ^^^ -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:105:23 - | -LL | use_expr!(true && let 0 = 1); - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:109:17 - | -LL | noop_expr!((let 0 = 1)); - | ^^^ - error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:27:9 + --> $DIR/disallowed-positions.rs:29:9 | LL | if (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:27:9 + --> $DIR/disallowed-positions.rs:29:9 | LL | if (let 0 = 1) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:31:11 + --> $DIR/disallowed-positions.rs:33:11 | LL | if (((let 0 = 1))) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:31:11 + --> $DIR/disallowed-positions.rs:33:11 | LL | if (((let 0 = 1))) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:35:9 + --> $DIR/disallowed-positions.rs:37:9 | LL | if (let 0 = 1) && true {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:35:9 + --> $DIR/disallowed-positions.rs:37:9 | LL | if (let 0 = 1) && true {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:39:17 + --> $DIR/disallowed-positions.rs:41:17 | LL | if true && (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:39:17 + --> $DIR/disallowed-positions.rs:41:17 | LL | if true && (let 0 = 1) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:43:9 + --> $DIR/disallowed-positions.rs:45:9 | LL | if (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:43:9 + --> $DIR/disallowed-positions.rs:45:9 | LL | if (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:43:24 + --> $DIR/disallowed-positions.rs:45:24 | LL | if (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:43:24 + --> $DIR/disallowed-positions.rs:45:24 | LL | if (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:49:35 + --> $DIR/disallowed-positions.rs:51:35 | LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:49:35 + --> $DIR/disallowed-positions.rs:51:35 | LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:49:48 + --> $DIR/disallowed-positions.rs:51:48 | LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:49:35 + --> $DIR/disallowed-positions.rs:51:35 | LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:49:61 + --> $DIR/disallowed-positions.rs:51:61 | LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:49:35 + --> $DIR/disallowed-positions.rs:51:35 | LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:59:12 + --> $DIR/disallowed-positions.rs:61:12 | LL | while (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:59:12 + --> $DIR/disallowed-positions.rs:61:12 | LL | while (let 0 = 1) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:63:14 + --> $DIR/disallowed-positions.rs:65:14 | LL | while (((let 0 = 1))) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:63:14 + --> $DIR/disallowed-positions.rs:65:14 | LL | while (((let 0 = 1))) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:67:12 + --> $DIR/disallowed-positions.rs:69:12 | LL | while (let 0 = 1) && true {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:67:12 + --> $DIR/disallowed-positions.rs:69:12 | LL | while (let 0 = 1) && true {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:71:20 + --> $DIR/disallowed-positions.rs:73:20 | LL | while true && (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:71:20 + --> $DIR/disallowed-positions.rs:73:20 | LL | while true && (let 0 = 1) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:75:12 + --> $DIR/disallowed-positions.rs:77:12 | LL | while (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:75:12 + --> $DIR/disallowed-positions.rs:77:12 | LL | while (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:75:27 + --> $DIR/disallowed-positions.rs:77:27 | LL | while (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:75:27 + --> $DIR/disallowed-positions.rs:77:27 | LL | while (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:81:38 + --> $DIR/disallowed-positions.rs:83:38 | LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:81:38 + --> $DIR/disallowed-positions.rs:83:38 | LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:81:51 + --> $DIR/disallowed-positions.rs:83:51 | LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:81:38 + --> $DIR/disallowed-positions.rs:83:38 | LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:81:64 + --> $DIR/disallowed-positions.rs:83:64 | LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:81:38 + --> $DIR/disallowed-positions.rs:83:38 | LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:97:16 + --> $DIR/disallowed-positions.rs:99:16 | LL | use_expr!((let 0 = 1 && 0 == 0)); | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:97:16 + --> $DIR/disallowed-positions.rs:99:16 | LL | use_expr!((let 0 = 1 && 0 == 0)); | ^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:97:16 + --> $DIR/disallowed-positions.rs:99:16 | LL | use_expr!((let 0 = 1 && 0 == 0)); | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:97:16 + --> $DIR/disallowed-positions.rs:99:16 | LL | use_expr!((let 0 = 1 && 0 == 0)); | ^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:101:16 + --> $DIR/disallowed-positions.rs:103:16 | LL | use_expr!((let 0 = 1)); | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:101:16 + --> $DIR/disallowed-positions.rs:103:16 | LL | use_expr!((let 0 = 1)); | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:101:16 + --> $DIR/disallowed-positions.rs:103:16 | LL | use_expr!((let 0 = 1)); | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:101:16 + --> $DIR/disallowed-positions.rs:103:16 | LL | use_expr!((let 0 = 1)); | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:114:9 + --> $DIR/disallowed-positions.rs:110:9 | LL | if &let 0 = 0 {} | ^^^^^^^^^ @@ -808,7 +790,7 @@ LL | if &let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:119:9 + --> $DIR/disallowed-positions.rs:115:9 | LL | if !let 0 = 0 {} | ^^^^^^^^^ @@ -816,7 +798,7 @@ LL | if !let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:122:9 + --> $DIR/disallowed-positions.rs:118:9 | LL | if *let 0 = 0 {} | ^^^^^^^^^ @@ -824,7 +806,7 @@ LL | if *let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:126:9 + --> $DIR/disallowed-positions.rs:122:9 | LL | if -let 0 = 0 {} | ^^^^^^^^^ @@ -832,72 +814,72 @@ LL | if -let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:136:9 + --> $DIR/disallowed-positions.rs:132:9 | LL | if (let 0 = 0)? {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:136:9 + --> $DIR/disallowed-positions.rs:132:9 | LL | if (let 0 = 0)? {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:142:16 + --> $DIR/disallowed-positions.rs:138:16 | LL | if true || let 0 = 0 {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:142:13 + --> $DIR/disallowed-positions.rs:138:13 | LL | if true || let 0 = 0 {} | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:145:17 + --> $DIR/disallowed-positions.rs:141:17 | LL | if (true || let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:145:14 + --> $DIR/disallowed-positions.rs:141:14 | LL | if (true || let 0 = 0) {} | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:148:25 + --> $DIR/disallowed-positions.rs:144:25 | LL | if true && (true || let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:148:22 + --> $DIR/disallowed-positions.rs:144:22 | LL | if true && (true || let 0 = 0) {} | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:151:25 + --> $DIR/disallowed-positions.rs:147:25 | LL | if true || (true && let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:151:17 + --> $DIR/disallowed-positions.rs:147:17 | LL | if true || (true && let 0 = 0) {} | ^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:156:12 + --> $DIR/disallowed-positions.rs:152:12 | LL | if x = let 0 = 0 {} | ^^^^^^^^^ @@ -905,46 +887,46 @@ LL | if x = let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:161:15 + --> $DIR/disallowed-positions.rs:157:15 | LL | if true..(let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:161:15 + --> $DIR/disallowed-positions.rs:157:15 | LL | if true..(let 0 = 0) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:165:11 + --> $DIR/disallowed-positions.rs:161:11 | LL | if ..(let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:165:11 + --> $DIR/disallowed-positions.rs:161:11 | LL | if ..(let 0 = 0) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:169:9 + --> $DIR/disallowed-positions.rs:165:9 | LL | if (let 0 = 0).. {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:169:9 + --> $DIR/disallowed-positions.rs:165:9 | LL | if (let 0 = 0).. {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:175:8 + --> $DIR/disallowed-positions.rs:171:8 | LL | if let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -952,7 +934,7 @@ LL | if let Range { start: _, end: _ } = true..true && false {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:179:8 + --> $DIR/disallowed-positions.rs:175:8 | LL | if let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -960,7 +942,7 @@ LL | if let Range { start: _, end: _ } = true..true || false {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:186:8 + --> $DIR/disallowed-positions.rs:182:8 | LL | if let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -968,7 +950,7 @@ LL | if let Range { start: F, end } = F..|| true {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:194:8 + --> $DIR/disallowed-positions.rs:190:8 | LL | if let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -976,7 +958,7 @@ LL | if let Range { start: true, end } = t..&&false {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:200:19 + --> $DIR/disallowed-positions.rs:196:19 | LL | if let true = let true = true {} | ^^^^^^^^^^^^^^^ @@ -984,7 +966,7 @@ LL | if let true = let true = true {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:206:12 + --> $DIR/disallowed-positions.rs:202:12 | LL | while &let 0 = 0 {} | ^^^^^^^^^ @@ -992,7 +974,7 @@ LL | while &let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:211:12 + --> $DIR/disallowed-positions.rs:207:12 | LL | while !let 0 = 0 {} | ^^^^^^^^^ @@ -1000,7 +982,7 @@ LL | while !let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:214:12 + --> $DIR/disallowed-positions.rs:210:12 | LL | while *let 0 = 0 {} | ^^^^^^^^^ @@ -1008,7 +990,7 @@ LL | while *let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:218:12 + --> $DIR/disallowed-positions.rs:214:12 | LL | while -let 0 = 0 {} | ^^^^^^^^^ @@ -1016,72 +998,72 @@ LL | while -let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:228:12 + --> $DIR/disallowed-positions.rs:224:12 | LL | while (let 0 = 0)? {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:228:12 + --> $DIR/disallowed-positions.rs:224:12 | LL | while (let 0 = 0)? {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:234:19 + --> $DIR/disallowed-positions.rs:230:19 | LL | while true || let 0 = 0 {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:234:16 + --> $DIR/disallowed-positions.rs:230:16 | LL | while true || let 0 = 0 {} | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:237:20 + --> $DIR/disallowed-positions.rs:233:20 | LL | while (true || let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:237:17 + --> $DIR/disallowed-positions.rs:233:17 | LL | while (true || let 0 = 0) {} | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:240:28 + --> $DIR/disallowed-positions.rs:236:28 | LL | while true && (true || let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:240:25 + --> $DIR/disallowed-positions.rs:236:25 | LL | while true && (true || let 0 = 0) {} | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:243:28 + --> $DIR/disallowed-positions.rs:239:28 | LL | while true || (true && let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:243:20 + --> $DIR/disallowed-positions.rs:239:20 | LL | while true || (true && let 0 = 0) {} | ^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:248:15 + --> $DIR/disallowed-positions.rs:244:15 | LL | while x = let 0 = 0 {} | ^^^^^^^^^ @@ -1089,46 +1071,46 @@ LL | while x = let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:253:18 + --> $DIR/disallowed-positions.rs:249:18 | LL | while true..(let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:253:18 + --> $DIR/disallowed-positions.rs:249:18 | LL | while true..(let 0 = 0) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:257:14 + --> $DIR/disallowed-positions.rs:253:14 | LL | while ..(let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:257:14 + --> $DIR/disallowed-positions.rs:253:14 | LL | while ..(let 0 = 0) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:261:12 + --> $DIR/disallowed-positions.rs:257:12 | LL | while (let 0 = 0).. {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:261:12 + --> $DIR/disallowed-positions.rs:257:12 | LL | while (let 0 = 0).. {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:267:11 + --> $DIR/disallowed-positions.rs:263:11 | LL | while let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1136,7 +1118,7 @@ LL | while let Range { start: _, end: _ } = true..true && false {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:271:11 + --> $DIR/disallowed-positions.rs:267:11 | LL | while let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1144,7 +1126,7 @@ LL | while let Range { start: _, end: _ } = true..true || false {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:278:11 + --> $DIR/disallowed-positions.rs:274:11 | LL | while let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1152,7 +1134,7 @@ LL | while let Range { start: F, end } = F..|| true {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:286:11 + --> $DIR/disallowed-positions.rs:282:11 | LL | while let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1160,7 +1142,7 @@ LL | while let Range { start: true, end } = t..&&false {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:292:22 + --> $DIR/disallowed-positions.rs:288:22 | LL | while let true = let true = true {} | ^^^^^^^^^^^^^^^ @@ -1168,7 +1150,7 @@ LL | while let true = let true = true {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:308:6 + --> $DIR/disallowed-positions.rs:304:6 | LL | &let 0 = 0; | ^^^^^^^^^ @@ -1176,7 +1158,7 @@ LL | &let 0 = 0; = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:312:6 + --> $DIR/disallowed-positions.rs:308:6 | LL | !let 0 = 0; | ^^^^^^^^^ @@ -1184,7 +1166,7 @@ LL | !let 0 = 0; = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:315:6 + --> $DIR/disallowed-positions.rs:311:6 | LL | *let 0 = 0; | ^^^^^^^^^ @@ -1192,7 +1174,7 @@ LL | *let 0 = 0; = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:319:6 + --> $DIR/disallowed-positions.rs:315:6 | LL | -let 0 = 0; | ^^^^^^^^^ @@ -1200,59 +1182,59 @@ LL | -let 0 = 0; = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:329:6 + --> $DIR/disallowed-positions.rs:325:6 | LL | (let 0 = 0)?; | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:329:6 + --> $DIR/disallowed-positions.rs:325:6 | LL | (let 0 = 0)?; | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:335:13 + --> $DIR/disallowed-positions.rs:331:13 | LL | true || let 0 = 0; | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:335:10 + --> $DIR/disallowed-positions.rs:331:10 | LL | true || let 0 = 0; | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:338:14 + --> $DIR/disallowed-positions.rs:334:14 | LL | (true || let 0 = 0); | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:338:11 + --> $DIR/disallowed-positions.rs:334:11 | LL | (true || let 0 = 0); | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:341:22 + --> $DIR/disallowed-positions.rs:337:22 | LL | true && (true || let 0 = 0); | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:341:19 + --> $DIR/disallowed-positions.rs:337:19 | LL | true && (true || let 0 = 0); | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:346:9 + --> $DIR/disallowed-positions.rs:342:9 | LL | x = let 0 = 0; | ^^^^^^^^^ @@ -1260,46 +1242,46 @@ LL | x = let 0 = 0; = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:350:12 + --> $DIR/disallowed-positions.rs:346:12 | LL | true..(let 0 = 0); | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:350:12 + --> $DIR/disallowed-positions.rs:346:12 | LL | true..(let 0 = 0); | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:353:8 + --> $DIR/disallowed-positions.rs:349:8 | LL | ..(let 0 = 0); | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:353:8 + --> $DIR/disallowed-positions.rs:349:8 | LL | ..(let 0 = 0); | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:356:6 + --> $DIR/disallowed-positions.rs:352:6 | LL | (let 0 = 0)..; | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:356:6 + --> $DIR/disallowed-positions.rs:352:6 | LL | (let 0 = 0)..; | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:360:6 + --> $DIR/disallowed-positions.rs:356:6 | LL | (let Range { start: _, end: _ } = true..true || false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1307,20 +1289,20 @@ LL | (let Range { start: _, end: _ } = true..true || false); = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:365:6 + --> $DIR/disallowed-positions.rs:361:6 | LL | (let true = let true = true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:365:6 + --> $DIR/disallowed-positions.rs:361:6 | LL | (let true = let true = true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:383:6 + --> $DIR/disallowed-positions.rs:379:6 | LL | &let 0 = 0 | ^^^^^^^^^ @@ -1328,7 +1310,7 @@ LL | &let 0 = 0 = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:395:17 + --> $DIR/disallowed-positions.rs:391:17 | LL | true && let 1 = 1 | ^^^^^^^^^ @@ -1336,7 +1318,7 @@ LL | true && let 1 = 1 = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:401:17 + --> $DIR/disallowed-positions.rs:397:17 | LL | true && let 1 = 1 | ^^^^^^^^^ @@ -1344,7 +1326,7 @@ LL | true && let 1 = 1 = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:407:17 + --> $DIR/disallowed-positions.rs:403:17 | LL | true && let 1 = 1 | ^^^^^^^^^ @@ -1352,7 +1334,7 @@ LL | true && let 1 = 1 = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:419:17 + --> $DIR/disallowed-positions.rs:415:17 | LL | true && let 1 = 1 | ^^^^^^^^^ @@ -1360,124 +1342,124 @@ LL | true && let 1 = 1 = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:429:9 + --> $DIR/disallowed-positions.rs:425:9 | LL | if (let Some(a) = opt && true) { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:429:9 + --> $DIR/disallowed-positions.rs:425:9 | LL | if (let Some(a) = opt && true) { | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:434:9 + --> $DIR/disallowed-positions.rs:430:9 | LL | if (let Some(a) = opt) && true { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:434:9 + --> $DIR/disallowed-positions.rs:430:9 | LL | if (let Some(a) = opt) && true { | ^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:438:9 + --> $DIR/disallowed-positions.rs:434:9 | LL | if (let Some(a) = opt) && (let Some(b) = a) { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:438:9 + --> $DIR/disallowed-positions.rs:434:9 | LL | if (let Some(a) = opt) && (let Some(b) = a) { | ^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:438:32 + --> $DIR/disallowed-positions.rs:434:32 | LL | if (let Some(a) = opt) && (let Some(b) = a) { | ^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:438:32 + --> $DIR/disallowed-positions.rs:434:32 | LL | if (let Some(a) = opt) && (let Some(b) = a) { | ^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:447:9 + --> $DIR/disallowed-positions.rs:443:9 | LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:447:9 + --> $DIR/disallowed-positions.rs:443:9 | LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:447:31 + --> $DIR/disallowed-positions.rs:443:31 | LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { | ^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:447:31 + --> $DIR/disallowed-positions.rs:443:31 | LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { | ^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:453:9 + --> $DIR/disallowed-positions.rs:449:9 | LL | if (let Some(a) = opt && (let Some(b) = a)) && true { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:453:9 + --> $DIR/disallowed-positions.rs:449:9 | LL | if (let Some(a) = opt && (let Some(b) = a)) && true { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:453:31 + --> $DIR/disallowed-positions.rs:449:31 | LL | if (let Some(a) = opt && (let Some(b) = a)) && true { | ^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:453:31 + --> $DIR/disallowed-positions.rs:449:31 | LL | if (let Some(a) = opt && (let Some(b) = a)) && true { | ^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:459:9 + --> $DIR/disallowed-positions.rs:455:9 | LL | if (let Some(a) = opt && (true)) && true { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:459:9 + --> $DIR/disallowed-positions.rs:455:9 | LL | if (let Some(a) = opt && (true)) && true { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:114:8 + --> $DIR/disallowed-positions.rs:110:8 | LL | if &let 0 = 0 {} | ^^^^^^^^^^ expected `bool`, found `&bool` @@ -1489,19 +1471,19 @@ LL + if let 0 = 0 {} | error[E0614]: type `bool` cannot be dereferenced - --> $DIR/disallowed-positions.rs:122:8 + --> $DIR/disallowed-positions.rs:118:8 | LL | if *let 0 = 0 {} | ^^^^^^^^^^ error[E0600]: cannot apply unary operator `-` to type `bool` - --> $DIR/disallowed-positions.rs:126:8 + --> $DIR/disallowed-positions.rs:122:8 | LL | if -let 0 = 0 {} | ^^^^^^^^^^ cannot apply unary operator `-` error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:136:8 + --> $DIR/disallowed-positions.rs:132:8 | LL | if (let 0 = 0)? {} | ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool` @@ -1509,7 +1491,7 @@ LL | if (let 0 = 0)? {} = help: the trait `Try` is not implemented for `bool` error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) - --> $DIR/disallowed-positions.rs:136:19 + --> $DIR/disallowed-positions.rs:132:19 | LL | / fn nested_within_if_expr() { LL | | if &let 0 = 0 {} @@ -1526,7 +1508,7 @@ LL | | } = help: the trait `FromResidual<_>` is not implemented for `()` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:156:8 + --> $DIR/disallowed-positions.rs:152:8 | LL | if x = let 0 = 0 {} | ^^^^^^^^^^^^^ expected `bool`, found `()` @@ -1537,7 +1519,7 @@ LL | if x == let 0 = 0 {} | ~~ error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:161:8 + --> $DIR/disallowed-positions.rs:157:8 | LL | if true..(let 0 = 0) {} | ^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1546,7 +1528,7 @@ LL | if true..(let 0 = 0) {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:165:8 + --> $DIR/disallowed-positions.rs:161:8 | LL | if ..(let 0 = 0) {} | ^^^^^^^^^^^^^ expected `bool`, found struct `RangeTo` @@ -1555,7 +1537,7 @@ LL | if ..(let 0 = 0) {} found struct `RangeTo` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:169:8 + --> $DIR/disallowed-positions.rs:165:8 | LL | if (let 0 = 0).. {} | ^^^^^^^^^^^^^ expected `bool`, found struct `RangeFrom` @@ -1564,7 +1546,7 @@ LL | if (let 0 = 0).. {} found struct `RangeFrom` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:175:12 + --> $DIR/disallowed-positions.rs:171:12 | LL | if let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` @@ -1575,7 +1557,7 @@ LL | if let Range { start: _, end: _ } = true..true && false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:175:8 + --> $DIR/disallowed-positions.rs:171:8 | LL | if let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1584,7 +1566,7 @@ LL | if let Range { start: _, end: _ } = true..true && false {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:179:12 + --> $DIR/disallowed-positions.rs:175:12 | LL | if let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` @@ -1595,7 +1577,7 @@ LL | if let Range { start: _, end: _ } = true..true || false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:179:8 + --> $DIR/disallowed-positions.rs:175:8 | LL | if let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1604,7 +1586,7 @@ LL | if let Range { start: _, end: _ } = true..true || false {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:186:12 + --> $DIR/disallowed-positions.rs:182:12 | LL | if let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `fn() -> bool` @@ -1615,20 +1597,20 @@ LL | if let Range { start: F, end } = F..|| true {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:186:41 + --> $DIR/disallowed-positions.rs:182:41 | LL | if let Range { start: F, end } = F..|| true {} | ^^^^^^^ expected `bool`, found closure | = note: expected type `bool` - found closure `[closure@$DIR/disallowed-positions.rs:186:41: 186:43]` + found closure `[closure@$DIR/disallowed-positions.rs:182:41: 182:43]` help: use parentheses to call this closure | LL | if let Range { start: F, end } = F..(|| true)() {} | + +++ error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:186:8 + --> $DIR/disallowed-positions.rs:182:8 | LL | if let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1637,7 +1619,7 @@ LL | if let Range { start: F, end } = F..|| true {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:194:12 + --> $DIR/disallowed-positions.rs:190:12 | LL | if let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool` @@ -1648,7 +1630,7 @@ LL | if let Range { start: true, end } = t..&&false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:194:44 + --> $DIR/disallowed-positions.rs:190:44 | LL | if let Range { start: true, end } = t..&&false {} | ^^^^^^^ expected `bool`, found `&&bool` @@ -1660,7 +1642,7 @@ LL + if let Range { start: true, end } = t..false {} | error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:194:8 + --> $DIR/disallowed-positions.rs:190:8 | LL | if let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1669,7 +1651,7 @@ LL | if let Range { start: true, end } = t..&&false {} found struct `std::ops::Range` error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:132:20 + --> $DIR/disallowed-positions.rs:128:20 | LL | if let 0 = 0? {} | ^^ the `?` operator cannot be applied to type `{integer}` @@ -1677,7 +1659,7 @@ LL | if let 0 = 0? {} = help: the trait `Try` is not implemented for `{integer}` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:206:11 + --> $DIR/disallowed-positions.rs:202:11 | LL | while &let 0 = 0 {} | ^^^^^^^^^^ expected `bool`, found `&bool` @@ -1689,19 +1671,19 @@ LL + while let 0 = 0 {} | error[E0614]: type `bool` cannot be dereferenced - --> $DIR/disallowed-positions.rs:214:11 + --> $DIR/disallowed-positions.rs:210:11 | LL | while *let 0 = 0 {} | ^^^^^^^^^^ error[E0600]: cannot apply unary operator `-` to type `bool` - --> $DIR/disallowed-positions.rs:218:11 + --> $DIR/disallowed-positions.rs:214:11 | LL | while -let 0 = 0 {} | ^^^^^^^^^^ cannot apply unary operator `-` error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:228:11 + --> $DIR/disallowed-positions.rs:224:11 | LL | while (let 0 = 0)? {} | ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool` @@ -1709,7 +1691,7 @@ LL | while (let 0 = 0)? {} = help: the trait `Try` is not implemented for `bool` error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) - --> $DIR/disallowed-positions.rs:228:22 + --> $DIR/disallowed-positions.rs:224:22 | LL | / fn nested_within_while_expr() { LL | | while &let 0 = 0 {} @@ -1726,7 +1708,7 @@ LL | | } = help: the trait `FromResidual<_>` is not implemented for `()` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:248:11 + --> $DIR/disallowed-positions.rs:244:11 | LL | while x = let 0 = 0 {} | ^^^^^^^^^^^^^ expected `bool`, found `()` @@ -1737,7 +1719,7 @@ LL | while x == let 0 = 0 {} | ~~ error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:253:11 + --> $DIR/disallowed-positions.rs:249:11 | LL | while true..(let 0 = 0) {} | ^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1746,7 +1728,7 @@ LL | while true..(let 0 = 0) {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:257:11 + --> $DIR/disallowed-positions.rs:253:11 | LL | while ..(let 0 = 0) {} | ^^^^^^^^^^^^^ expected `bool`, found struct `RangeTo` @@ -1755,7 +1737,7 @@ LL | while ..(let 0 = 0) {} found struct `RangeTo` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:261:11 + --> $DIR/disallowed-positions.rs:257:11 | LL | while (let 0 = 0).. {} | ^^^^^^^^^^^^^ expected `bool`, found struct `RangeFrom` @@ -1764,7 +1746,7 @@ LL | while (let 0 = 0).. {} found struct `RangeFrom` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:267:15 + --> $DIR/disallowed-positions.rs:263:15 | LL | while let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` @@ -1775,7 +1757,7 @@ LL | while let Range { start: _, end: _ } = true..true && false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:267:11 + --> $DIR/disallowed-positions.rs:263:11 | LL | while let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1784,7 +1766,7 @@ LL | while let Range { start: _, end: _ } = true..true && false {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:271:15 + --> $DIR/disallowed-positions.rs:267:15 | LL | while let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` @@ -1795,7 +1777,7 @@ LL | while let Range { start: _, end: _ } = true..true || false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:271:11 + --> $DIR/disallowed-positions.rs:267:11 | LL | while let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1804,7 +1786,7 @@ LL | while let Range { start: _, end: _ } = true..true || false {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:278:15 + --> $DIR/disallowed-positions.rs:274:15 | LL | while let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `fn() -> bool` @@ -1815,20 +1797,20 @@ LL | while let Range { start: F, end } = F..|| true {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:278:44 + --> $DIR/disallowed-positions.rs:274:44 | LL | while let Range { start: F, end } = F..|| true {} | ^^^^^^^ expected `bool`, found closure | = note: expected type `bool` - found closure `[closure@$DIR/disallowed-positions.rs:278:44: 278:46]` + found closure `[closure@$DIR/disallowed-positions.rs:274:44: 274:46]` help: use parentheses to call this closure | LL | while let Range { start: F, end } = F..(|| true)() {} | + +++ error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:278:11 + --> $DIR/disallowed-positions.rs:274:11 | LL | while let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1837,7 +1819,7 @@ LL | while let Range { start: F, end } = F..|| true {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:286:15 + --> $DIR/disallowed-positions.rs:282:15 | LL | while let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool` @@ -1848,7 +1830,7 @@ LL | while let Range { start: true, end } = t..&&false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:286:47 + --> $DIR/disallowed-positions.rs:282:47 | LL | while let Range { start: true, end } = t..&&false {} | ^^^^^^^ expected `bool`, found `&&bool` @@ -1860,7 +1842,7 @@ LL + while let Range { start: true, end } = t..false {} | error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:286:11 + --> $DIR/disallowed-positions.rs:282:11 | LL | while let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1869,7 +1851,7 @@ LL | while let Range { start: true, end } = t..&&false {} found struct `std::ops::Range` error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:224:23 + --> $DIR/disallowed-positions.rs:220:23 | LL | while let 0 = 0? {} | ^^ the `?` operator cannot be applied to type `{integer}` @@ -1877,19 +1859,19 @@ LL | while let 0 = 0? {} = help: the trait `Try` is not implemented for `{integer}` error[E0614]: type `bool` cannot be dereferenced - --> $DIR/disallowed-positions.rs:315:5 + --> $DIR/disallowed-positions.rs:311:5 | LL | *let 0 = 0; | ^^^^^^^^^^ error[E0600]: cannot apply unary operator `-` to type `bool` - --> $DIR/disallowed-positions.rs:319:5 + --> $DIR/disallowed-positions.rs:315:5 | LL | -let 0 = 0; | ^^^^^^^^^^ cannot apply unary operator `-` error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:329:5 + --> $DIR/disallowed-positions.rs:325:5 | LL | (let 0 = 0)?; | ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool` @@ -1897,7 +1879,7 @@ LL | (let 0 = 0)?; = help: the trait `Try` is not implemented for `bool` error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) - --> $DIR/disallowed-positions.rs:329:16 + --> $DIR/disallowed-positions.rs:325:16 | LL | / fn outside_if_and_while_expr() { LL | | &let 0 = 0; @@ -1914,7 +1896,7 @@ LL | | } = help: the trait `FromResidual<_>` is not implemented for `()` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:360:10 + --> $DIR/disallowed-positions.rs:356:10 | LL | (let Range { start: _, end: _ } = true..true || false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` @@ -1925,7 +1907,7 @@ LL | (let Range { start: _, end: _ } = true..true || false); found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:383:5 + --> $DIR/disallowed-positions.rs:379:5 | LL | fn outside_if_and_while_expr() { | - help: try adding a return type: `-> &bool` @@ -1934,14 +1916,14 @@ LL | &let 0 = 0 | ^^^^^^^^^^ expected `()`, found `&bool` error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:325:17 + --> $DIR/disallowed-positions.rs:321:17 | LL | let 0 = 0?; | ^^ the `?` operator cannot be applied to type `{integer}` | = help: the trait `Try` is not implemented for `{integer}` -error: aborting due to 218 previous errors +error: aborting due to 215 previous errors Some errors have detailed explanations: E0277, E0308, E0600, E0614. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs index deef4240d4d..12befc637c7 100644 --- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs +++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs @@ -1,4 +1,4 @@ -#![feature(let_else)] +#![feature(let_chains, let_else)] fn main() { let opt = Some(1i32); diff --git a/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs b/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs new file mode 100644 index 00000000000..2b407ef510c --- /dev/null +++ b/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs @@ -0,0 +1,62 @@ +// gate-test-let_chains + +// Here we test feature gating for ´let_chains`. +// See `disallowed-positions.rs` for the grammar +// defining the language for gated allowed positions. + +#![allow(irrefutable_let_patterns)] + +use std::ops::Range; + +fn _if() { + if let 0 = 1 {} // Stable! + + if true && let 0 = 1 {} + //~^ ERROR `let` expressions in this position are unstable [E0658] + + if let 0 = 1 && true {} + //~^ ERROR `let` expressions in this position are unstable [E0658] + + if let Range { start: _, end: _ } = (true..true) && false {} + //~^ ERROR `let` expressions in this position are unstable [E0658] + + if let 1 = 1 && let true = { true } && false { + //~^ ERROR `let` expressions in this position are unstable [E0658] + //~| ERROR `let` expressions in this position are unstable [E0658] + } +} + +fn _while() { + while let 0 = 1 {} // Stable! + + while true && let 0 = 1 {} + //~^ ERROR `let` expressions in this position are unstable [E0658] + + while let 0 = 1 && true {} + //~^ ERROR `let` expressions in this position are unstable [E0658] + + while let Range { start: _, end: _ } = (true..true) && false {} + //~^ ERROR `let` expressions in this position are unstable [E0658] +} + +fn _macros() { + macro_rules! noop_expr { ($e:expr) => {}; } + + noop_expr!((let 0 = 1)); + //~^ ERROR `let` expressions in this position are unstable [E0658] + //~| ERROR expected expression, found `let` statement + + macro_rules! use_expr { + ($e:expr) => { + if $e {} + while $e {} + } + } + #[cfg(FALSE)] (let 0 = 1); + //~^ ERROR `let` expressions in this position are unstable [E0658] + //~| ERROR expected expression, found `let` statement + use_expr!(let 0 = 1); + //~^ ERROR no rules expected the token `let` +} + +fn main() {} diff --git a/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr new file mode 100644 index 00000000000..feea1c254d8 --- /dev/null +++ b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr @@ -0,0 +1,114 @@ +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:55:20 + | +LL | #[cfg(FALSE)] (let 0 = 1); + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:45:17 + | +LL | noop_expr!((let 0 = 1)); + | ^^^ + +error: no rules expected the token `let` + --> $DIR/feature-gate.rs:58:15 + | +LL | macro_rules! use_expr { + | --------------------- when calling this macro +... +LL | use_expr!(let 0 = 1); + | ^^^ no rules expected this token in macro call + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:14:16 + | +LL | if true && let 0 = 1 {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:17:8 + | +LL | if let 0 = 1 && true {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:20:8 + | +LL | if let Range { start: _, end: _ } = (true..true) && false {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:23:8 + | +LL | if let 1 = 1 && let true = { true } && false { + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:23:21 + | +LL | if let 1 = 1 && let true = { true } && false { + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:32:19 + | +LL | while true && let 0 = 1 {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:35:11 + | +LL | while let 0 = 1 && true {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:38:11 + | +LL | while let Range { start: _, end: _ } = (true..true) && false {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:55:20 + | +LL | #[cfg(FALSE)] (let 0 = 1); + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/feature-gate.rs:45:17 + | +LL | noop_expr!((let 0 = 1)); + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error: aborting due to 13 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs b/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs index 7bc6d43a727..a942d1f4caf 100644 --- a/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs +++ b/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs @@ -1,3 +1,5 @@ +#![feature(let_chains)] + fn main() { let _opt = Some(1i32); diff --git a/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr b/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr index d1552a0b2d5..d1ce83c7233 100644 --- a/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr @@ -1,35 +1,35 @@ error: expected expression, found `let` statement - --> $DIR/invalid-let-in-a-valid-let-context.rs:6:19 + --> $DIR/invalid-let-in-a-valid-let-context.rs:8:19 | LL | let _ = &&let Some(x) = Some(42); | ^^^ error: expected expression, found `let` statement - --> $DIR/invalid-let-in-a-valid-let-context.rs:11:47 + --> $DIR/invalid-let-in-a-valid-let-context.rs:13:47 | LL | if let Some(elem) = _opt && [1, 2, 3][let _ = &&let Some(x) = Some(42)] = 1 { | ^^^ error: expected expression, found `let` statement - --> $DIR/invalid-let-in-a-valid-let-context.rs:11:57 + --> $DIR/invalid-let-in-a-valid-let-context.rs:13:57 | LL | if let Some(elem) = _opt && [1, 2, 3][let _ = &&let Some(x) = Some(42)] = 1 { | ^^^ error: expected expression, found `let` statement - --> $DIR/invalid-let-in-a-valid-let-context.rs:21:23 + --> $DIR/invalid-let-in-a-valid-let-context.rs:23:23 | LL | [1, 2, 3][let _ = ()]; | ^^^ error: expected expression, found `let` statement - --> $DIR/invalid-let-in-a-valid-let-context.rs:30:47 + --> $DIR/invalid-let-in-a-valid-let-context.rs:32:47 | LL | if let Some(elem) = _opt && [1, 2, 3][let _ = ()] = 1 { | ^^^ error: expected expression, found `let` statement - --> $DIR/invalid-let-in-a-valid-let-context.rs:38:21 + --> $DIR/invalid-let-in-a-valid-let-context.rs:40:21 | LL | let x = let y = 1; | ^^^ diff --git a/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.rs b/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.rs index 1ef4bc56e52..3d1626e8ffb 100644 --- a/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.rs +++ b/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.rs @@ -1,7 +1,7 @@ // revisions: allowed disallowed //[allowed] check-pass -#![feature(if_let_guard)] +#![feature(if_let_guard, let_chains)] #![cfg_attr(allowed, allow(irrefutable_let_patterns))] #![cfg_attr(disallowed, deny(irrefutable_let_patterns))] diff --git a/src/test/ui/rfc-2497-if-let-chains/issue-90722.rs b/src/test/ui/rfc-2497-if-let-chains/issue-90722.rs index 34302ba96d3..6b7d8835650 100644 --- a/src/test/ui/rfc-2497-if-let-chains/issue-90722.rs +++ b/src/test/ui/rfc-2497-if-let-chains/issue-90722.rs @@ -1,5 +1,7 @@ // check-pass +#![feature(let_chains)] + fn main() { let x = Some(vec!["test"]); diff --git a/src/test/ui/rfc-2497-if-let-chains/issue-92145.rs b/src/test/ui/rfc-2497-if-let-chains/issue-92145.rs index 6938062fa35..7c7e31f4db4 100644 --- a/src/test/ui/rfc-2497-if-let-chains/issue-92145.rs +++ b/src/test/ui/rfc-2497-if-let-chains/issue-92145.rs @@ -1,5 +1,7 @@ // check-pass +#![feature(let_chains)] + fn main() { let opt = Some("foo bar"); diff --git a/src/test/ui/rfc-2497-if-let-chains/issue-93150.rs b/src/test/ui/rfc-2497-if-let-chains/issue-93150.rs index f6de37867d8..f90b9ab0d40 100644 --- a/src/test/ui/rfc-2497-if-let-chains/issue-93150.rs +++ b/src/test/ui/rfc-2497-if-let-chains/issue-93150.rs @@ -2,6 +2,7 @@ fn main() { match true { _ if let true = true && true => {} //~^ ERROR `if let` guards are + //~| ERROR `let` expressions in this _ => {} } } diff --git a/src/test/ui/rfc-2497-if-let-chains/issue-93150.stderr b/src/test/ui/rfc-2497-if-let-chains/issue-93150.stderr index 0d620df96f6..b25f299a219 100644 --- a/src/test/ui/rfc-2497-if-let-chains/issue-93150.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/issue-93150.stderr @@ -8,6 +8,15 @@ LL | _ if let true = true && true => {} = help: add `#![feature(if_let_guard)]` to the crate attributes to enable = help: you can write `if matches!(, )` instead of `if let = ` -error: aborting due to previous error +error[E0658]: `let` expressions in this position are unstable + --> $DIR/issue-93150.rs:3:14 + | +LL | _ if let true = true && true => {} + | ^^^^^^^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2497-if-let-chains/then-else-blocks.rs b/src/test/ui/rfc-2497-if-let-chains/then-else-blocks.rs index beaca33d563..e061174f667 100644 --- a/src/test/ui/rfc-2497-if-let-chains/then-else-blocks.rs +++ b/src/test/ui/rfc-2497-if-let-chains/then-else-blocks.rs @@ -1,6 +1,6 @@ // run-pass -#![feature(if_let_guard)] +#![feature(if_let_guard, let_chains)] fn check_if_let(opt: Option>>, value: i32) -> bool { if let Some(first) = opt diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs index 8a6bd1cbdf5..82574a8e64b 100644 --- a/src/tools/clippy/clippy_dev/src/lib.rs +++ b/src/tools/clippy/clippy_dev/src/lib.rs @@ -1,3 +1,4 @@ +#![feature(let_chains)] #![feature(let_else)] #![feature(once_cell)] #![feature(rustc_private)] diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index e6a405f8170..ec5c73c1357 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -4,6 +4,7 @@ #![feature(control_flow_enum)] #![feature(drain_filter)] #![feature(iter_intersperse)] +#![feature(let_chains)] #![feature(let_else)] #![feature(lint_reasons)] #![feature(never_type)] diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index f716f009ff3..313f1f1d9a6 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -2,6 +2,7 @@ #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(let_else)] +#![feature(let_chains)] #![feature(lint_reasons)] #![feature(once_cell)] #![feature(rustc_private)] diff --git a/src/tools/clippy/tests/ui/needless_late_init.fixed b/src/tools/clippy/tests/ui/needless_late_init.fixed index 4c98e1827bd..fee8e3030b8 100644 --- a/src/tools/clippy/tests/ui/needless_late_init.fixed +++ b/src/tools/clippy/tests/ui/needless_late_init.fixed @@ -1,4 +1,5 @@ // run-rustfix +#![feature(let_chains)] #![allow( unused, clippy::assign_op_pattern, diff --git a/src/tools/clippy/tests/ui/needless_late_init.rs b/src/tools/clippy/tests/ui/needless_late_init.rs index 25e1e0214fb..402d9f9ef7f 100644 --- a/src/tools/clippy/tests/ui/needless_late_init.rs +++ b/src/tools/clippy/tests/ui/needless_late_init.rs @@ -1,4 +1,5 @@ // run-rustfix +#![feature(let_chains)] #![allow( unused, clippy::assign_op_pattern, diff --git a/src/tools/clippy/tests/ui/needless_late_init.stderr b/src/tools/clippy/tests/ui/needless_late_init.stderr index 97f0f7019a9..313cdbbeba1 100644 --- a/src/tools/clippy/tests/ui/needless_late_init.stderr +++ b/src/tools/clippy/tests/ui/needless_late_init.stderr @@ -1,5 +1,5 @@ error: unneeded late initialization - --> $DIR/needless_late_init.rs:22:5 + --> $DIR/needless_late_init.rs:23:5 | LL | let a; | ^^^^^^ created here @@ -13,7 +13,7 @@ LL | let a = "zero"; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:25:5 + --> $DIR/needless_late_init.rs:26:5 | LL | let b; | ^^^^^^ created here @@ -27,7 +27,7 @@ LL | let b = 1; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:26:5 + --> $DIR/needless_late_init.rs:27:5 | LL | let c; | ^^^^^^ created here @@ -41,7 +41,7 @@ LL | let c = 2; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:30:5 + --> $DIR/needless_late_init.rs:31:5 | LL | let d: usize; | ^^^^^^^^^^^^^ created here @@ -54,7 +54,7 @@ LL | let d: usize = 1; | ~~~~~~~~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:33:5 + --> $DIR/needless_late_init.rs:34:5 | LL | let e; | ^^^^^^ created here @@ -67,7 +67,7 @@ LL | let e = format!("{}", d); | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:38:5 + --> $DIR/needless_late_init.rs:39:5 | LL | let a; | ^^^^^^ @@ -88,7 +88,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:47:5 + --> $DIR/needless_late_init.rs:48:5 | LL | let b; | ^^^^^^ @@ -109,7 +109,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:54:5 + --> $DIR/needless_late_init.rs:55:5 | LL | let d; | ^^^^^^ @@ -130,7 +130,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:62:5 + --> $DIR/needless_late_init.rs:63:5 | LL | let e; | ^^^^^^ @@ -151,7 +151,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:69:5 + --> $DIR/needless_late_init.rs:70:5 | LL | let f; | ^^^^^^ @@ -167,7 +167,7 @@ LL + 1 => "three", | error: unneeded late initialization - --> $DIR/needless_late_init.rs:75:5 + --> $DIR/needless_late_init.rs:76:5 | LL | let g: usize; | ^^^^^^^^^^^^^ @@ -187,7 +187,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:83:5 + --> $DIR/needless_late_init.rs:84:5 | LL | let x; | ^^^^^^ created here @@ -201,7 +201,7 @@ LL | let x = 1; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:87:5 + --> $DIR/needless_late_init.rs:88:5 | LL | let x; | ^^^^^^ created here @@ -215,7 +215,7 @@ LL | let x = SignificantDrop; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:91:5 + --> $DIR/needless_late_init.rs:92:5 | LL | let x; | ^^^^^^ created here @@ -229,7 +229,7 @@ LL | let x = SignificantDrop; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:110:5 + --> $DIR/needless_late_init.rs:111:5 | LL | let a; | ^^^^^^ @@ -250,7 +250,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:127:5 + --> $DIR/needless_late_init.rs:128:5 | LL | let a; | ^^^^^^ -- cgit 1.4.1-3-g733a5 From 8af7f4208a789ba27a341c99df2de9c018b79828 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Mon, 22 Aug 2022 13:38:08 +0200 Subject: Code deduplication in tool_only_multipart_suggestion --- compiler/rustc_errors/src/diagnostic.rs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 506198df4d8..f75e2596f36 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -686,19 +686,12 @@ impl Diagnostic { suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self { - assert!(!suggestion.is_empty()); - self.push_suggestion(CodeSuggestion { - substitutions: vec![Substitution { - parts: suggestion - .into_iter() - .map(|(span, snippet)| SubstitutionPart { snippet, span }) - .collect(), - }], - msg: self.subdiagnostic_message_to_diagnostic_message(msg), - style: SuggestionStyle::CompletelyHidden, + self.multipart_suggestion_with_style( + msg, + suggestion, applicability, - }); - self + SuggestionStyle::CompletelyHidden, + ) } /// Prints out a message with a suggested edit of the code. -- cgit 1.4.1-3-g733a5