diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000000..6a3ab0c920744 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: ["rust-lang.org/funding"] diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 78da2fa9163ca..e348cc1ab2810 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1819,8 +1819,14 @@ pub enum ExprKind { /// A use expression (`x.use`). Span is of use keyword. Use(Box, Span), - /// A try block (`try { ... }`). - TryBlock(Box), + /// A try block (`try { ... }`), if the type is `None`, or + /// A try block (`try bikeshed Ty { ... }`) if the type is `Some`. + /// + /// Note that `try bikeshed` is a *deliberately ridiculous* placeholder + /// syntax to avoid deciding what keyword or symbol should go there. + /// It's that way for experimentation only; an RFC to decide the final + /// semantics and syntax would be needed to put it on stabilization-track. + TryBlock(Box, Option>), /// An assignment (`a = foo()`). /// The `Span` argument is the span of the `=` token. diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index dde773fd147da..7a0424d395750 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -1048,8 +1048,8 @@ macro_rules! common_visitor_and_walkers { visit_visitable!($($mut)? vis, kind), ExprKind::Try(subexpression) => visit_visitable!($($mut)? vis, subexpression), - ExprKind::TryBlock(body) => - visit_visitable!($($mut)? vis, body), + ExprKind::TryBlock(body, optional_type) => + visit_visitable!($($mut)? vis, body, optional_type), ExprKind::Lit(token) => visit_visitable!($($mut)? vis, token), ExprKind::IncludedBytes(bytes) => diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 524f8b054cb49..7230e1c424740 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1,3 +1,4 @@ +use std::mem; use std::ops::ControlFlow; use std::sync::Arc; @@ -27,7 +28,9 @@ use super::{ GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt, }; use crate::errors::{InvalidLegacyConstGenericArg, UseConstGenericArg, YieldInClosure}; -use crate::{AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, fluent_generated}; +use crate::{ + AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, TryBlockScope, fluent_generated, +}; struct WillCreateDefIdsVisitor {} @@ -199,7 +202,9 @@ impl<'hir> LoweringContext<'_, 'hir> { ) }) } - ExprKind::TryBlock(body) => self.lower_expr_try_block(body), + ExprKind::TryBlock(body, opt_ty) => { + self.lower_expr_try_block(body, opt_ty.as_deref()) + } ExprKind::Match(expr, arms, kind) => hir::ExprKind::Match( self.lower_expr(expr), self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))), @@ -562,9 +567,14 @@ impl<'hir> LoweringContext<'_, 'hir> { /// Desugar `try { ; }` into `{ ; ::std::ops::Try::from_output() }`, /// `try { ; }` into `{ ; ::std::ops::Try::from_output(()) }` /// and save the block id to use it as a break target for desugaring of the `?` operator. - fn lower_expr_try_block(&mut self, body: &Block) -> hir::ExprKind<'hir> { + fn lower_expr_try_block(&mut self, body: &Block, opt_ty: Option<&Ty>) -> hir::ExprKind<'hir> { let body_hir_id = self.lower_node_id(body.id); - self.with_catch_scope(body_hir_id, |this| { + let new_scope = if opt_ty.is_some() { + TryBlockScope::Heterogeneous(body_hir_id) + } else { + TryBlockScope::Homogeneous(body_hir_id) + }; + let whole_block = self.with_try_block_scope(new_scope, |this| { let mut block = this.lower_block_noalloc(body_hir_id, body, true); // Final expression of the block (if present) or `()` with span at the end of block @@ -598,8 +608,16 @@ impl<'hir> LoweringContext<'_, 'hir> { ok_wrapped_span, )); - hir::ExprKind::Block(this.arena.alloc(block), None) - }) + this.arena.alloc(block) + }); + + if let Some(ty) = opt_ty { + let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path)); + let block_expr = self.arena.alloc(self.expr_block(whole_block)); + hir::ExprKind::Type(block_expr, ty) + } else { + hir::ExprKind::Block(whole_block, None) + } } fn wrap_in_try_constructor( @@ -1617,10 +1635,14 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn with_catch_scope(&mut self, catch_id: hir::HirId, f: impl FnOnce(&mut Self) -> T) -> T { - let old_scope = self.catch_scope.replace(catch_id); + fn with_try_block_scope( + &mut self, + scope: TryBlockScope, + f: impl FnOnce(&mut Self) -> T, + ) -> T { + let old_scope = mem::replace(&mut self.try_block_scope, scope); let result = f(self); - self.catch_scope = old_scope; + self.try_block_scope = old_scope; result } @@ -1978,18 +2000,25 @@ impl<'hir> LoweringContext<'_, 'hir> { let residual_ident = Ident::with_dummy_span(sym::residual); let (residual_local, residual_local_nid) = self.pat_ident(try_span, residual_ident); let residual_expr = self.expr_ident_mut(try_span, residual_ident, residual_local_nid); + + let (constructor_item, target_id) = match self.try_block_scope { + TryBlockScope::Function => { + (hir::LangItem::TryTraitFromResidual, Err(hir::LoopIdError::OutsideLoopScope)) + } + TryBlockScope::Homogeneous(block_id) => { + (hir::LangItem::ResidualIntoTryType, Ok(block_id)) + } + TryBlockScope::Heterogeneous(block_id) => { + (hir::LangItem::TryTraitFromResidual, Ok(block_id)) + } + }; let from_residual_expr = self.wrap_in_try_constructor( - if self.catch_scope.is_some() { - hir::LangItem::ResidualIntoTryType - } else { - hir::LangItem::TryTraitFromResidual - }, + constructor_item, try_span, self.arena.alloc(residual_expr), unstable_span, ); - let ret_expr = if let Some(catch_id) = self.catch_scope { - let target_id = Ok(catch_id); + let ret_expr = if target_id.is_ok() { self.arena.alloc(self.expr( try_span, hir::ExprKind::Break( @@ -2044,11 +2073,14 @@ impl<'hir> LoweringContext<'_, 'hir> { yeeted_span, ); - if let Some(catch_id) = self.catch_scope { - let target_id = Ok(catch_id); - hir::ExprKind::Break(hir::Destination { label: None, target_id }, Some(from_yeet_expr)) - } else { - self.checked_return(Some(from_yeet_expr)) + match self.try_block_scope { + TryBlockScope::Homogeneous(block_id) | TryBlockScope::Heterogeneous(block_id) => { + hir::ExprKind::Break( + hir::Destination { label: None, target_id: Ok(block_id) }, + Some(from_yeet_expr), + ) + } + TryBlockScope::Function => self.checked_return(Some(from_yeet_expr)), } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 19e826cf18f31..c20bbcca44f75 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -35,6 +35,7 @@ #![feature(if_let_guard)] // tidy-alphabetical-end +use std::mem; use std::sync::Arc; use rustc_ast::node_id::NodeMap; @@ -117,7 +118,7 @@ struct LoweringContext<'a, 'hir> { /// outside of an `async fn`. current_item: Option, - catch_scope: Option, + try_block_scope: TryBlockScope, loop_scope: Option, is_in_loop_condition: bool, is_in_dyn_type: bool, @@ -173,7 +174,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { trait_map: Default::default(), // Lowering state. - catch_scope: None, + try_block_scope: TryBlockScope::Function, loop_scope: None, is_in_loop_condition: false, is_in_dyn_type: false, @@ -416,6 +417,18 @@ enum AstOwner<'a> { ForeignItem(&'a ast::ForeignItem), } +#[derive(Copy, Clone, Debug)] +enum TryBlockScope { + /// There isn't a `try` block, so a `?` will use `return`. + Function, + /// We're inside a `try { … }` block, so a `?` will block-break + /// from that block using a type depending only on the argument. + Homogeneous(HirId), + /// We're inside a `try as _ { … }` block, so a `?` will block-break + /// from that block using the type specified. + Heterogeneous(HirId), +} + fn index_crate<'a>( node_id_to_def_id: &NodeMap, krate: &'a Crate, @@ -936,10 +949,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let old_contract = self.contract_ensures.take(); - let catch_scope = self.catch_scope.take(); + let try_block_scope = mem::replace(&mut self.try_block_scope, TryBlockScope::Function); let loop_scope = self.loop_scope.take(); let ret = f(self); - self.catch_scope = catch_scope; + self.try_block_scope = try_block_scope; self.loop_scope = loop_scope; self.contract_ensures = old_contract; diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index ee868296d9dce..88e9bbd710601 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -334,9 +334,17 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_expr(&mut self, e: &'a ast::Expr) { match e.kind { - ast::ExprKind::TryBlock(_) => { + ast::ExprKind::TryBlock(_, None) => { gate!(&self, try_blocks, e.span, "`try` expression is experimental"); } + ast::ExprKind::TryBlock(_, Some(_)) => { + gate!( + &self, + try_blocks_heterogeneous, + e.span, + "`try bikeshed` expression is experimental" + ); + } ast::ExprKind::Lit(token::Lit { kind: token::LitKind::Float | token::LitKind::Integer, suffix, diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index bdf73ac32f0d8..7dce7f6d41954 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -818,10 +818,15 @@ impl<'a> State<'a> { ); self.word("?") } - ast::ExprKind::TryBlock(blk) => { + ast::ExprKind::TryBlock(blk, opt_ty) => { let cb = self.cbox(0); let ib = self.ibox(0); self.word_nbsp("try"); + if let Some(ty) = opt_ty { + self.word_nbsp("bikeshed"); + self.print_type(ty); + self.space(); + } self.print_block_with_attrs(blk, attrs, cb, ib) } ast::ExprKind::UnsafeBinderCast(kind, expr, ty) => { diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index 31855cbd4e6cc..21b20e2bb974f 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -315,7 +315,7 @@ impl<'cx, 'a> Context<'cx, 'a> { | ExprKind::Path(_, _) | ExprKind::Ret(_) | ExprKind::Try(_) - | ExprKind::TryBlock(_) + | ExprKind::TryBlock(_, _) | ExprKind::Type(_, _) | ExprKind::Underscore | ExprKind::While(_, _, _) diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index b47b9afa4f073..5fdecd014ac05 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -47,7 +47,7 @@ use rustc_codegen_ssa::{CodegenResults, TargetConfig}; use rustc_log::tracing::info; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; -use rustc_session::config::{OutputFilenames, PrintKind, PrintRequest}; +use rustc_session::config::OutputFilenames; use rustc_span::{Symbol, sym}; use rustc_target::spec::{Abi, Arch, Env, Os}; @@ -160,16 +160,6 @@ impl CodegenBackend for CraneliftCodegenBackend { } } - fn print(&self, req: &PrintRequest, out: &mut String, _sess: &Session) { - match req.kind { - // FIXME have a default impl that returns false - PrintKind::BackendHasZstd => { - out.push_str("false\n"); - } - _ => {} - } - } - fn target_config(&self, sess: &Session) -> TargetConfig { // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)] let target_features = match sess.target.arch { diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 8c0c0afcc1dd7..0da5810518c5c 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -257,10 +257,6 @@ impl CodegenBackend for LlvmCodegenBackend { } writeln!(out).unwrap(); } - PrintKind::BackendHasZstd => { - let has_zstd = llvm::LLVMRustLLVMHasZstdCompression(); - writeln!(out, "{has_zstd}").unwrap(); - } PrintKind::CodeModels => { writeln!(out, "Available code models:").unwrap(); for name in &["tiny", "small", "kernel", "medium", "large"] { @@ -314,6 +310,10 @@ impl CodegenBackend for LlvmCodegenBackend { llvm_util::print_version(); } + fn has_zstd(&self) -> bool { + llvm::LLVMRustLLVMHasZstdCompression() + } + fn target_config(&self, sess: &Session) -> TargetConfig { target_config(sess) } diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 85bff45408140..cb74e2e46d650 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -78,6 +78,14 @@ pub trait CodegenBackend { fn print_version(&self) {} + /// Value printed by `--print=backend-has-zstd`. + /// + /// Used by compiletest to determine whether tests involving zstd compression + /// (e.g. `-Zdebuginfo-compression=zstd`) should be executed or skipped. + fn has_zstd(&self) -> bool { + false + } + /// The metadata loader used to load rlib and dylib metadata. /// /// Alternative codegen backends may want to use different rlib or dylib formats than the diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 0853f638509fd..63fc9c96f450d 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -798,8 +798,11 @@ fn print_crate_info( let calling_conventions = rustc_abi::all_names(); println_info!("{}", calling_conventions.join("\n")); } + BackendHasZstd => { + let has_zstd: bool = codegen_backend.has_zstd(); + println_info!("{has_zstd}"); + } RelocationModels - | BackendHasZstd | CodeModels | TlsModels | TargetCPUs diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 3ef4eb00c3546..ac01d98b4d1a9 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -663,6 +663,8 @@ declare_features! ( (unstable, trivial_bounds, "1.28.0", Some(48214)), /// Allows using `try {...}` expressions. (unstable, try_blocks, "1.29.0", Some(31436)), + /// Allows using `try bikeshed TargetType {...}` expressions. + (unstable, try_blocks_heterogeneous, "CURRENT_RUSTC_VERSION", Some(149488)), /// Allows `impl Trait` to be used inside type aliases (RFC 2515). (unstable, type_alias_impl_trait, "1.38.0", Some(63063)), /// Allows creation of instances of a struct by moving fields that have diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 0a7b458f3fb35..445386412058b 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -1043,7 +1043,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - lint.note("for more information, see "); let diagnostic_msg = format!( "add a dummy let to cause {migrated_variables_concat} to be fully captured" diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index dd0aa848ed2c9..7546d3948a8ff 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -35,9 +35,9 @@ use rustc_middle::lint::LevelAndSource; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, AssocContainer, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef}; -use rustc_session::lint::FutureIncompatibilityReason; // hardwired lints from rustc_lint_defs pub use rustc_session::lint::builtin::*; +use rustc_session::lint::fcw; use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass}; use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; @@ -777,8 +777,7 @@ declare_lint! { Warn, "detects anonymous parameters", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), - reference: "issue #41686 ", + reason: fcw!(EditionError 2018 "trait-fn-parameters"), }; } @@ -1664,8 +1663,7 @@ declare_lint! { Warn, "`...` range patterns are deprecated", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021), - reference: "", + reason: fcw!(EditionError 2021 "warnings-promoted-to-error"), }; } @@ -1800,8 +1798,7 @@ declare_lint! { Allow, "detects edition keywords being used as an identifier", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), - reference: "issue #49716 ", + reason: fcw!(EditionError 2018 "new-keywords"), }; } @@ -1845,8 +1842,7 @@ declare_lint! { Allow, "detects edition keywords being used as an identifier", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "gen-keyword"), }; } diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index 2521c2b4eb6ac..612d542a27deb 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -11,9 +11,8 @@ use rustc_middle::ty::significant_drop_order::{ extract_component_with_significant_dtor, ty_dtor_span, }; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_session::lint::{FutureIncompatibilityReason, LintId}; +use rustc_session::lint::{LintId, fcw}; use rustc_session::{declare_lint, impl_lint_pass}; -use rustc_span::edition::Edition; use rustc_span::{DUMMY_SP, Span}; use smallvec::SmallVec; @@ -86,8 +85,7 @@ declare_lint! { "`if let` assigns a shorter lifetime to temporary values being pattern-matched against in Edition 2024 and \ rewriting in `match` is an option to preserve the semantics up to Edition 2021", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - reference: "", + reason: fcw!(EditionSemanticsChange 2024 "temporary-if-let-scope"), }; } diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index f54afce0615fe..2fc9d562dc566 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -19,9 +19,8 @@ use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; use rustc_middle::{bug, span_bug}; -use rustc_session::lint::FutureIncompatibilityReason; +use rustc_session::lint::fcw; use rustc_session::{declare_lint, declare_lint_pass}; -use rustc_span::edition::Edition; use rustc_span::{Span, Symbol}; use rustc_trait_selection::errors::{ AddPreciseCapturingForOvercapture, impl_trait_overcapture_suggestion, @@ -71,8 +70,7 @@ declare_lint! { Allow, "`impl Trait` will capture more lifetimes than possibly intended in edition 2024", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - reference: "", + reason: fcw!(EditionSemanticsChange 2024 "rpit-lifetime-capture"), }; } diff --git a/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs b/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs index 7de6fbd941b44..f20605c914951 100644 --- a/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs +++ b/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs @@ -2,7 +2,7 @@ use rustc_ast::token::{Token, TokenKind}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; -use rustc_session::lint::FutureIncompatibilityReason; +use rustc_session::lint::fcw; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::edition::Edition; use rustc_span::sym; @@ -72,8 +72,7 @@ declare_lint! { "The `expr` fragment specifier will accept more expressions in the 2024 edition. \ To keep the existing behavior, use the `expr_2021` fragment specifier.", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - reference: "Migration Guide ", + reason: fcw!(EditionSemanticsChange 2024 "macro-fragment-specifiers"), }; } diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index 2eabeeaa88f90..f6295698b2813 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -4,9 +4,8 @@ use rustc_hir::{self as hir, LangItem}; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::{bug, ty}; use rustc_parse_format::{ParseMode, Parser, Piece}; -use rustc_session::lint::FutureIncompatibilityReason; +use rustc_session::lint::fcw; use rustc_session::{declare_lint, declare_lint_pass}; -use rustc_span::edition::Edition; use rustc_span::{InnerSpan, Span, Symbol, hygiene, sym}; use rustc_trait_selection::infer::InferCtxtExt; @@ -38,7 +37,7 @@ declare_lint! { Warn, "detect single-argument panic!() invocations in which the argument is not a format string", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2021), + reason: fcw!(EditionSemanticsChange 2021 "panic-macro-consistency"), explain_reason: false, }; report_in_external_macro diff --git a/compiler/rustc_lint/src/shadowed_into_iter.rs b/compiler/rustc_lint/src/shadowed_into_iter.rs index cfb2a7fb61864..05bb2113db09e 100644 --- a/compiler/rustc_lint/src/shadowed_into_iter.rs +++ b/compiler/rustc_lint/src/shadowed_into_iter.rs @@ -1,8 +1,7 @@ use rustc_hir::{self as hir, LangItem}; use rustc_middle::ty::{self, Ty}; -use rustc_session::lint::FutureIncompatibilityReason; +use rustc_session::lint::fcw; use rustc_session::{declare_lint, impl_lint_pass}; -use rustc_span::edition::Edition; use crate::lints::{ShadowedIntoIterDiag, ShadowedIntoIterDiagSub}; use crate::{LateContext, LateLintPass, LintContext}; @@ -31,8 +30,7 @@ declare_lint! { Warn, "detects calling `into_iter` on arrays in Rust 2015 and 2018", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2021), - reference: "", + reason: fcw!(EditionSemanticsChange 2021 "IntoIterator-for-arrays"), }; } @@ -60,8 +58,7 @@ declare_lint! { Warn, "detects calling `into_iter` on boxed slices in Rust 2015, 2018, and 2021", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - reference: "" + reason: fcw!(EditionSemanticsChange 2024 "intoiterator-box-slice"), }; } diff --git a/compiler/rustc_lint/src/static_mut_refs.rs b/compiler/rustc_lint/src/static_mut_refs.rs index 1c0df1f4234a2..1decb4b78e61a 100644 --- a/compiler/rustc_lint/src/static_mut_refs.rs +++ b/compiler/rustc_lint/src/static_mut_refs.rs @@ -1,9 +1,8 @@ use rustc_hir as hir; use rustc_hir::{Expr, Stmt}; use rustc_middle::ty::{Mutability, TyKind}; -use rustc_session::lint::FutureIncompatibilityReason; +use rustc_session::lint::fcw; use rustc_session::{declare_lint, declare_lint_pass}; -use rustc_span::edition::Edition; use rustc_span::{BytePos, Span}; use crate::lints::{MutRefSugg, RefOfMutStatic}; @@ -53,8 +52,7 @@ declare_lint! { Warn, "creating a shared reference to mutable static", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "static-mut-references"), explain_reason: false, }; @edition Edition2024 => Deny; diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 740530daf2bdb..baecc14424ecf 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -7,9 +7,7 @@ //! When removing a lint, make sure to also add a call to `register_removed` in //! compiler/rustc_lint/src/lib.rs. -use rustc_span::edition::Edition; - -use crate::{FutureIncompatibilityReason, declare_lint, declare_lint_pass}; +use crate::{declare_lint, declare_lint_pass, fcw}; declare_lint_pass! { /// Does nothing as a lint pass, but registers some `Lint`s @@ -182,8 +180,7 @@ declare_lint! { Warn, "applying forbid to lint-groups", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #81670 ", + reason: fcw!(FutureReleaseError #81670), report_in_deps: true, }; } @@ -219,8 +216,7 @@ declare_lint! { Deny, "ill-formed attribute inputs that were previously accepted and used in practice", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #57571 ", + reason: fcw!(FutureReleaseError #57571), report_in_deps: true, }; crate_level_only @@ -257,8 +253,7 @@ declare_lint! { Deny, "conflicts between `#[repr(..)]` hints that were previously accepted and used in practice", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #68585 ", + reason: fcw!(FutureReleaseError #68585), report_in_deps: true, }; } @@ -1267,8 +1262,7 @@ declare_lint! { Deny, "detect public re-exports of private extern crates", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #127909 ", + reason: fcw!(FutureReleaseError #127909), report_in_deps: true, }; } @@ -1298,8 +1292,7 @@ declare_lint! { Deny, "type parameter default erroneously allowed in invalid location", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #36887 ", + reason: fcw!(FutureReleaseError #36887), report_in_deps: true, }; } @@ -1438,8 +1431,7 @@ declare_lint! { Deny, "patterns in functions without body were erroneously allowed", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #35203 ", + reason: fcw!(FutureReleaseError #35203), }; } @@ -1480,8 +1472,7 @@ declare_lint! { Warn, "detects generic lifetime arguments in path segments with late bound lifetime parameters", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #42868 ", + reason: fcw!(FutureReleaseError #42868), }; } @@ -1520,8 +1511,7 @@ declare_lint! { Warn, "distinct impls distinguished only by the leak-check code", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::Custom("the behavior may change in a future release"), - reference: "issue #56105 ", + reason: fcw!("the behavior may change in a future release" #56105), }; } @@ -1624,8 +1614,7 @@ declare_lint! { Allow, "detects patterns whose meaning will change in Rust 2024", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - reference: "", + reason: fcw!(EditionSemanticsChange 2024 "match-ergonomics"), }; } @@ -1772,8 +1761,7 @@ declare_lint! { Warn, "raw pointer to an inference variable", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), - reference: "issue #46906 ", + reason: fcw!(EditionError 2018 "tyvar-behind-raw-pointer"), }; } @@ -1839,8 +1827,7 @@ declare_lint! { Warn, "suggest using `dyn Trait` for trait objects", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021), - reference: "", + reason: fcw!(EditionError 2021 "warnings-promoted-to-error"), }; } @@ -1894,8 +1881,7 @@ declare_lint! { "fully qualified paths that start with a module name \ instead of `crate`, `self`, or an extern crate name", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), - reference: "issue #53130 ", + reason: fcw!(EditionError 2018 "path-changes"), }; } @@ -1942,11 +1928,11 @@ declare_lint! { Warn, "detects name collision with an existing but unstable method", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::Custom( + reason: fcw!( "once this associated item is added to the standard library, \ the ambiguity may cause an error or change in behavior!" + #48919 ), - reference: "issue #48919 ", // Note: this item represents future incompatibility of all unstable functions in the // standard library, and thus should never be removed or changed to an error. }; @@ -2075,8 +2061,7 @@ declare_lint! { Deny, "detects proc macro derives using inaccessible names from parent modules", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #83583 ", + reason: fcw!(FutureReleaseError #83583), report_in_deps: true, }; } @@ -2179,8 +2164,7 @@ declare_lint! { "macro-expanded `macro_export` macros from the current crate \ cannot be referred to by absolute paths", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #52234 ", + reason: fcw!(FutureReleaseError #52234), report_in_deps: true, }; crate_level_only @@ -2301,8 +2285,7 @@ declare_lint! { Deny, "ambiguous associated items", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #57644 ", + reason: fcw!(FutureReleaseError #57644), }; } @@ -2317,8 +2300,7 @@ declare_lint! { Deny, "a feature gate that doesn't break dependent crates", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #64266 ", + reason: fcw!(FutureReleaseError #64266), report_in_deps: true, }; } @@ -2529,8 +2511,7 @@ declare_lint! { Allow, "unsafe operations in unsafe functions without an explicit unsafe block are deprecated", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "unsafe-op-in-unsafe-fn"), explain_reason: false }; @edition Edition2024 => Warn; @@ -2661,8 +2642,7 @@ declare_lint! { Warn, "detects a generic constant is used in a type without a emitting a warning", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #76200 ", + reason: fcw!(FutureReleaseError #76200), }; } @@ -2720,8 +2700,7 @@ declare_lint! { Warn, "uninhabited static", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #74840 ", + reason: fcw!(FutureReleaseError #74840), }; } @@ -2853,8 +2832,7 @@ declare_lint! { Warn, "detect unsupported use of `Self` from outer item", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #124186 ", + reason: fcw!(FutureReleaseError #124186), }; } @@ -2899,8 +2877,7 @@ declare_lint! { Deny, "trailing semicolon in macro body used as expression", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #79813 ", + reason: fcw!(FutureReleaseError #79813), report_in_deps: true, }; } @@ -2947,8 +2924,7 @@ declare_lint! { Deny, "detects derive helper attributes that are used before they are introduced", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #79202 ", + reason: fcw!(FutureReleaseError #79202), report_in_deps: true, }; } @@ -3131,8 +3107,7 @@ declare_lint! { Deny, "transparent type contains an external ZST that is marked #[non_exhaustive] or contains private fields", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #78586 ", + reason: fcw!(FutureReleaseError #78586), report_in_deps: true, }; } @@ -3183,8 +3158,7 @@ declare_lint! { Warn, "unstable syntax can change at any point in the future, causing a hard error!", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #65860 ", + reason: fcw!(FutureReleaseError #65860), }; } @@ -3425,7 +3399,7 @@ declare_lint! { Allow, "detects closures affected by Rust 2021 changes", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2021), + reason: fcw!(EditionSemanticsChange 2021 "disjoint-capture-in-closures"), explain_reason: false, }; } @@ -3520,8 +3494,7 @@ declare_lint! { Allow, "detects usage of old versions of or-patterns", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021), - reference: "", + reason: fcw!(EditionError 2021 "or-patterns-macro-rules"), }; } @@ -3569,8 +3542,7 @@ declare_lint! { "detects the usage of trait methods which are ambiguous with traits added to the \ prelude in future editions", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021), - reference: "", + reason: fcw!(EditionError 2021 "prelude"), }; } @@ -3609,8 +3581,7 @@ declare_lint! { "detects the usage of trait methods which are ambiguous with traits added to the \ prelude in future editions", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "prelude"), }; } @@ -3646,8 +3617,7 @@ declare_lint! { Allow, "identifiers that will be parsed as a prefix in Rust 2021", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021), - reference: "", + reason: fcw!(EditionError 2021 "reserving-syntax"), }; crate_level_only } @@ -3694,9 +3664,8 @@ declare_lint! { Warn, "use of unsupported calling convention", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, + reason: fcw!(FutureReleaseError #137018), report_in_deps: false, - reference: "issue #137018 ", }; } @@ -3739,8 +3708,7 @@ declare_lint! { Warn, "use of unsupported calling convention for function pointer", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #130260 ", + reason: fcw!(FutureReleaseError #130260), report_in_deps: true, }; } @@ -4174,8 +4142,7 @@ declare_lint! { Deny, "never type fallback affecting unsafe function calls", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange(Edition::Edition2024), - reference: "", + reason: fcw!(EditionAndFutureReleaseSemanticsChange 2024 "never-type-fallback"), report_in_deps: true, }; @edition Edition2024 => Deny; @@ -4229,8 +4196,7 @@ declare_lint! { Deny, "never type fallback affecting unsafe function calls", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionAndFutureReleaseError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionAndFutureReleaseError 2024 "never-type-fallback"), report_in_deps: true, }; report_in_external_macro @@ -4265,8 +4231,7 @@ declare_lint! { Deny, "\"invalid_parameter\" isn't a valid argument for `#[macro_export]`", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #57571 ", + reason: fcw!(FutureReleaseError #57571), report_in_deps: true, }; } @@ -4503,8 +4468,7 @@ declare_lint! { Deny, "detects certain glob imports that require reporting an ambiguity error", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #114095 ", + reason: fcw!(FutureReleaseError #114095), report_in_deps: true, }; } @@ -4659,8 +4623,7 @@ declare_lint! { Deny, "elided lifetimes cannot be used in associated constants in impls", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #115010 ", + reason: fcw!(FutureReleaseError #115010), }; } @@ -4706,8 +4669,7 @@ declare_lint! { Deny, "detects certain macro bindings that should not be re-exported", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #120192 ", + reason: fcw!(FutureReleaseError #120192), report_in_deps: true, }; } @@ -4772,8 +4734,7 @@ declare_lint! { Warn, "impl contains type parameters that are not covered", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #124559 ", + reason: fcw!(FutureReleaseError #124559), }; } @@ -4820,8 +4781,7 @@ declare_lint! { Allow, "detects unsafe functions being used as safe functions", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "newly-unsafe-functions"), }; } @@ -4856,8 +4816,7 @@ declare_lint! { Allow, "detects missing unsafe keyword on extern declarations", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "unsafe-extern"), }; } @@ -4897,8 +4856,7 @@ declare_lint! { Allow, "detects unsafe attributes outside of unsafe", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "unsafe-attributes"), }; } @@ -4936,8 +4894,7 @@ declare_lint! { Deny, "detects out of scope calls to `macro_rules` in key-value attributes", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #124535 ", + reason: fcw!(FutureReleaseError #124535), report_in_deps: true, }; } @@ -5099,8 +5056,7 @@ declare_lint! { Allow, "Detect and warn on significant change in drop order in tail expression location", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - reference: "", + reason: fcw!(EditionSemanticsChange 2024 "temporary-tail-expr-scope"), }; } @@ -5138,8 +5094,7 @@ declare_lint! { Allow, "will be parsed as a guarded string in Rust 2024", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "reserved-syntax"), }; crate_level_only } @@ -5180,8 +5135,7 @@ declare_lint! { Warn, "detects code that could be affected by ABI issues on aarch64 softfloat targets", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #134375 ", + reason: fcw!(FutureReleaseError #134375), report_in_deps: true, }; } @@ -5316,8 +5270,7 @@ declare_lint! { Warn, "repr(C) enums with discriminant values that do not fit into a C int", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #124403 ", + reason: fcw!(FutureReleaseError #124403), report_in_deps: false, }; } @@ -5363,8 +5316,7 @@ declare_lint! { Warn, "detects usage of `...` arguments without a pattern in non-foreign items", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #145544 ", + reason: fcw!(FutureReleaseError #145544), report_in_deps: false, }; } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index bb153afecc4c6..323ea799fb68c 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -1,4 +1,5 @@ use std::borrow::Cow; +use std::fmt::Display; use rustc_ast::AttrId; use rustc_ast::attr::AttributeExt; @@ -356,8 +357,6 @@ pub struct Lint { /// Extra information for a future incompatibility lint. #[derive(Copy, Clone, Debug)] pub struct FutureIncompatibleInfo { - /// e.g., a URL for an issue/PR/RFC or error code - pub reference: &'static str, /// The reason for the lint used by diagnostics to provide /// the right help message pub reason: FutureIncompatibilityReason, @@ -380,6 +379,17 @@ pub struct FutureIncompatibleInfo { pub report_in_deps: bool, } +#[derive(Copy, Clone, Debug)] +pub struct EditionFcw { + pub edition: Edition, + pub page_slug: &'static str, +} + +#[derive(Copy, Clone, Debug)] +pub struct ReleaseFcw { + pub issue_number: usize, +} + /// The reason for future incompatibility /// /// Future-incompatible lints come in roughly two categories: @@ -409,14 +419,14 @@ pub enum FutureIncompatibilityReason { /// hard errors (and the lint removed). Preferably when there is some /// confidence that the number of impacted projects is very small (few /// should have a broken dependency in their dependency tree). - FutureReleaseError, + FutureReleaseError(ReleaseFcw), /// Code that changes meaning in some way in a /// future release. /// /// Choose this variant when the semantics of existing code is changing, /// (as opposed to [`FutureIncompatibilityReason::FutureReleaseError`], /// which is for when code is going to be rejected in the future). - FutureReleaseSemanticsChange, + FutureReleaseSemanticsChange(ReleaseFcw), /// Previously accepted code that will become an /// error in the provided edition /// @@ -437,7 +447,7 @@ pub enum FutureIncompatibilityReason { /// See also [`FutureIncompatibilityReason::EditionSemanticsChange`] if /// you have code that is changing semantics across the edition (as /// opposed to being rejected). - EditionError(Edition), + EditionError(EditionFcw), /// Code that changes meaning in some way in /// the provided edition /// @@ -445,7 +455,7 @@ pub enum FutureIncompatibilityReason { /// except for situations where the semantics change across an edition. It /// slightly changes the text of the diagnostic, but is otherwise the /// same. - EditionSemanticsChange(Edition), + EditionSemanticsChange(EditionFcw), /// This will be an error in the provided edition *and* in a future /// release. /// @@ -455,7 +465,7 @@ pub enum FutureIncompatibilityReason { /// /// [`EditionError`]: FutureIncompatibilityReason::EditionError /// [`FutureReleaseError`]: FutureIncompatibilityReason::FutureReleaseError - EditionAndFutureReleaseError(Edition), + EditionAndFutureReleaseError(EditionFcw), /// This will change meaning in the provided edition *and* in a future /// release. /// @@ -466,14 +476,29 @@ pub enum FutureIncompatibilityReason { /// /// [`EditionSemanticsChange`]: FutureIncompatibilityReason::EditionSemanticsChange /// [`FutureReleaseSemanticsChange`]: FutureIncompatibilityReason::FutureReleaseSemanticsChange - EditionAndFutureReleaseSemanticsChange(Edition), + EditionAndFutureReleaseSemanticsChange(EditionFcw), /// A custom reason. /// /// Choose this variant if the built-in text of the diagnostic of the /// other variants doesn't match your situation. This is behaviorally /// equivalent to /// [`FutureIncompatibilityReason::FutureReleaseError`]. - Custom(&'static str), + Custom(&'static str, ReleaseFcw), + + /// Using the declare_lint macro a reason always needs to be specified. + /// So, this case can't actually be reached but a variant needs to exist for it. + /// Any code panics on seeing this variant. Do not use. + Unreachable, +} + +impl FutureIncompatibleInfo { + pub const fn default_fields_for_macro() -> Self { + FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::Unreachable, + explain_reason: true, + report_in_deps: false, + } + } } impl FutureIncompatibilityReason { @@ -482,26 +507,53 @@ impl FutureIncompatibilityReason { Self::EditionError(e) | Self::EditionSemanticsChange(e) | Self::EditionAndFutureReleaseError(e) - | Self::EditionAndFutureReleaseSemanticsChange(e) => Some(e), + | Self::EditionAndFutureReleaseSemanticsChange(e) => Some(e.edition), - FutureIncompatibilityReason::FutureReleaseError - | FutureIncompatibilityReason::FutureReleaseSemanticsChange - | FutureIncompatibilityReason::Custom(_) => None, + FutureIncompatibilityReason::FutureReleaseError(_) + | FutureIncompatibilityReason::FutureReleaseSemanticsChange(_) + | FutureIncompatibilityReason::Custom(_, _) => None, + Self::Unreachable => unreachable!(), } } -} -impl FutureIncompatibleInfo { - pub const fn default_fields_for_macro() -> Self { - FutureIncompatibleInfo { - reference: "", - reason: FutureIncompatibilityReason::FutureReleaseError, - explain_reason: true, - report_in_deps: false, + pub fn reference(&self) -> String { + match self { + Self::FutureReleaseSemanticsChange(release_fcw) + | Self::FutureReleaseError(release_fcw) + | Self::Custom(_, release_fcw) => release_fcw.to_string(), + Self::EditionError(edition_fcw) + | Self::EditionSemanticsChange(edition_fcw) + | Self::EditionAndFutureReleaseError(edition_fcw) + | Self::EditionAndFutureReleaseSemanticsChange(edition_fcw) => edition_fcw.to_string(), + Self::Unreachable => unreachable!(), } } } +impl Display for ReleaseFcw { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let issue_number = self.issue_number; + write!(f, "issue #{issue_number} ") + } +} + +impl Display for EditionFcw { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "", + match self.edition { + Edition::Edition2015 => "rust-2015", + Edition::Edition2018 => "rust-2018", + Edition::Edition2021 => "rust-2021", + Edition::Edition2024 => "rust-2024", + Edition::EditionFuture => "future", + }, + self.page_slug, + ) + } +} + impl Lint { pub const fn default_fields_for_macro() -> Self { Lint { @@ -901,3 +953,53 @@ macro_rules! declare_lint_pass { $crate::impl_lint_pass!($name => [$($lint),*]); }; } + +#[macro_export] +macro_rules! fcw { + (FutureReleaseError # $issue_number: literal) => { + $crate:: FutureIncompatibilityReason::FutureReleaseError($crate::ReleaseFcw { issue_number: $issue_number }) + }; + (FutureReleaseSemanticsChange # $issue_number: literal) => { + $crate::FutureIncompatibilityReason::FutureReleaseSemanticsChange($crate::ReleaseFcw { + issue_number: $issue_number, + }) + }; + ($description: literal # $issue_number: literal) => { + $crate::FutureIncompatibilityReason::Custom($description, $crate::ReleaseFcw { + issue_number: $issue_number, + }) + }; + (EditionError $edition_name: tt $page_slug: literal) => { + $crate::FutureIncompatibilityReason::EditionError($crate::EditionFcw { + edition: fcw!(@edition $edition_name), + page_slug: $page_slug, + }) + }; + (EditionSemanticsChange $edition_name: tt $page_slug: literal) => { + $crate::FutureIncompatibilityReason::EditionSemanticsChange($crate::EditionFcw { + edition: fcw!(@edition $edition_name), + page_slug: $page_slug, + }) + }; + (EditionAndFutureReleaseSemanticsChange $edition_name: tt $page_slug: literal) => { + $crate::FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange($crate::EditionFcw { + edition: fcw!(@edition $edition_name), + page_slug: $page_slug, + }) + }; + (EditionAndFutureReleaseError $edition_name: tt $page_slug: literal) => { + $crate::FutureIncompatibilityReason::EditionAndFutureReleaseError($crate::EditionFcw { + edition: fcw!(@edition $edition_name), + page_slug: $page_slug, + }) + }; + (@edition 2024) => { + rustc_span::edition::Edition::Edition2024 + }; + (@edition 2021) => { + rustc_span::edition::Edition::Edition2021 + }; + (@edition 2018) => { + rustc_span::edition::Edition::Edition2018 + }; +} diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index f70b7b6fad7a7..bed902e8334bb 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -4,6 +4,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sorted_map::SortedMap; use rustc_errors::{Diag, MultiSpan}; use rustc_hir::{HirId, ItemLocalId}; +use rustc_lint_defs::EditionFcw; use rustc_macros::{Decodable, Encodable, HashStable}; use rustc_session::Session; use rustc_session::lint::builtin::{self, FORBIDDEN_LINT_GROUPS}; @@ -395,45 +396,52 @@ pub fn lint_level( if let Some(future_incompatible) = future_incompatible { let explanation = match future_incompatible.reason { - FutureIncompatibilityReason::FutureReleaseError => { + FutureIncompatibilityReason::FutureReleaseError(_) => { "this was previously accepted by the compiler but is being phased out; \ it will become a hard error in a future release!" .to_owned() } - FutureIncompatibilityReason::FutureReleaseSemanticsChange => { + FutureIncompatibilityReason::FutureReleaseSemanticsChange(_) => { "this will change its meaning in a future release!".to_owned() } - FutureIncompatibilityReason::EditionError(edition) => { + FutureIncompatibilityReason::EditionError(EditionFcw { edition, .. }) => { let current_edition = sess.edition(); format!( "this is accepted in the current edition (Rust {current_edition}) but is a hard error in Rust {edition}!" ) } - FutureIncompatibilityReason::EditionSemanticsChange(edition) => { + FutureIncompatibilityReason::EditionSemanticsChange(EditionFcw { + edition, .. + }) => { format!("this changes meaning in Rust {edition}") } - FutureIncompatibilityReason::EditionAndFutureReleaseError(edition) => { + FutureIncompatibilityReason::EditionAndFutureReleaseError(EditionFcw { + edition, + .. + }) => { format!( "this was previously accepted by the compiler but is being phased out; \ it will become a hard error in Rust {edition} and in a future release in all editions!" ) } - FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange(edition) => { + FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange( + EditionFcw { edition, .. }, + ) => { format!( "this changes meaning in Rust {edition} and in a future release in all editions!" ) } - FutureIncompatibilityReason::Custom(reason) => reason.to_owned(), + FutureIncompatibilityReason::Custom(reason, _) => reason.to_owned(), + FutureIncompatibilityReason::Unreachable => unreachable!(), }; if future_incompatible.explain_reason { err.warn(explanation); } - if !future_incompatible.reference.is_empty() { - let citation = - format!("for more information, see {}", future_incompatible.reference); - err.note(citation); - } + + let citation = + format!("for more information, see {}", future_incompatible.reason.reference()); + err.note(citation); } // Finally, run `decorate`. `decorate` can call `trimmed_path_str` (directly or indirectly), diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 9e7d4bca37d05..fa5e61d24d911 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3544,15 +3544,20 @@ impl<'a> Parser<'a> { self.token.is_keyword(kw::Builtin) && self.look_ahead(1, |t| *t == token::Pound) } - /// Parses a `try {...}` expression (`try` token already eaten). + /// Parses a `try {...}` or `try bikeshed Ty {...}` expression (`try` token already eaten). fn parse_try_block(&mut self, span_lo: Span) -> PResult<'a, Box> { + let annotation = + if self.eat_keyword(exp!(Bikeshed)) { Some(self.parse_ty()?) } else { None }; + let (attrs, body) = self.parse_inner_attrs_and_block(None)?; if self.eat_keyword(exp!(Catch)) { Err(self.dcx().create_err(errors::CatchAfterTry { span: self.prev_token.span })) } else { let span = span_lo.to(body.span); - self.psess.gated_spans.gate(sym::try_blocks, span); - Ok(self.mk_expr_with_attrs(span, ExprKind::TryBlock(body), attrs)) + let gate_sym = + if annotation.is_none() { sym::try_blocks } else { sym::try_blocks_heterogeneous }; + self.psess.gated_spans.gate(gate_sym, span); + Ok(self.mk_expr_with_attrs(span, ExprKind::TryBlock(body, annotation), attrs)) } } @@ -3569,7 +3574,11 @@ impl<'a> Parser<'a> { fn is_try_block(&self) -> bool { self.token.is_keyword(kw::Try) - && self.look_ahead(1, |t| *t == token::OpenBrace || t.is_metavar_block()) + && self.look_ahead(1, |t| { + *t == token::OpenBrace + || t.is_metavar_block() + || t.kind == TokenKind::Ident(sym::bikeshed, IdentIsRaw::No) + }) && self.token_uninterpolated_span().at_least_rust_2018() } @@ -4264,7 +4273,7 @@ impl MutVisitor for CondChecker<'_> { | ExprKind::Closure(_) | ExprKind::Block(_, _) | ExprKind::Gen(_, _, _, _) - | ExprKind::TryBlock(_) + | ExprKind::TryBlock(_, _) | ExprKind::Underscore | ExprKind::Path(_, _) | ExprKind::Break(_, _) diff --git a/compiler/rustc_parse/src/parser/token_type.rs b/compiler/rustc_parse/src/parser/token_type.rs index 08c5b06575cd4..e5dda7cf91041 100644 --- a/compiler/rustc_parse/src/parser/token_type.rs +++ b/compiler/rustc_parse/src/parser/token_type.rs @@ -129,6 +129,7 @@ pub enum TokenType { // Keyword-like symbols. // tidy-alphabetical-start SymAttSyntax, + SymBikeshed, SymClobberAbi, SymInlateout, SymInout, @@ -556,6 +557,7 @@ macro_rules! exp { (Yield) => { exp!(@kw, Yield, KwYield) }; (AttSyntax) => { exp!(@sym, att_syntax, SymAttSyntax) }; + (Bikeshed) => { exp!(@sym, bikeshed, SymBikeshed) }; (ClobberAbi) => { exp!(@sym, clobber_abi, SymClobberAbi) }; (Inlateout) => { exp!(@sym, inlateout, SymInlateout) }; (Inout) => { exp!(@sym, inout, SymInout) }; diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 8c70e18fb66dd..edc5ae9e6f634 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -150,7 +150,7 @@ pub fn feature_warn_issue( let future_incompatible = lint.future_incompatible.as_ref().unwrap(); err.is_lint(lint.name_lower(), /* has_future_breakage */ false); err.warn(lint.desc); - err.note(format!("for more information, see {}", future_incompatible.reference)); + err.note(format!("for more information, see {}", future_incompatible.reason.reference())); // A later feature_err call can steal and cancel this warning. err.stash(span, StashKey::EarlySyntaxWarning); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 171539b42a6e2..c9aaba6cce3bc 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -572,6 +572,7 @@ symbols! { begin_panic, bench, bevy_ecs, + bikeshed, bikeshed_guaranteed_no_drop, bin, binaryheap_iter, @@ -2284,6 +2285,7 @@ symbols! { truncf64, truncf128, try_blocks, + try_blocks_heterogeneous, try_capture, try_from, try_from_fn, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index eed7076ddaf10..722e16ab0fa49 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1310,6 +1310,7 @@ pub fn log2f128(x: f128) -> f128; /// /// The stabilized version of this intrinsic is /// [`f16::mul_add`](../../std/primitive.f16.html#method.mul_add) +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_nounwind] pub const fn fmaf16(a: f16, b: f16, c: f16) -> f16; @@ -1317,6 +1318,7 @@ pub const fn fmaf16(a: f16, b: f16, c: f16) -> f16; /// /// The stabilized version of this intrinsic is /// [`f32::mul_add`](../../std/primitive.f32.html#method.mul_add) +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_nounwind] pub const fn fmaf32(a: f32, b: f32, c: f32) -> f32; @@ -1324,6 +1326,7 @@ pub const fn fmaf32(a: f32, b: f32, c: f32) -> f32; /// /// The stabilized version of this intrinsic is /// [`f64::mul_add`](../../std/primitive.f64.html#method.mul_add) +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_nounwind] pub const fn fmaf64(a: f64, b: f64, c: f64) -> f64; @@ -1331,6 +1334,7 @@ pub const fn fmaf64(a: f64, b: f64, c: f64) -> f64; /// /// The stabilized version of this intrinsic is /// [`f128::mul_add`](../../std/primitive.f128.html#method.mul_add) +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_nounwind] pub const fn fmaf128(a: f128, b: f128, c: f128) -> f128; diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index e945cd77a75f7..68f22767d6cf0 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -860,7 +860,7 @@ impl Clone for PhantomData { #[doc(hidden)] #[unstable(feature = "trivial_clone", issue = "none")] -unsafe impl TrivialClone for PhantomData {} +unsafe impl TrivialClone for PhantomData {} #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_default", issue = "143894")] diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 31c56c44430c8..bf99fee4fc78a 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1709,7 +1709,6 @@ impl f128 { #[doc(alias = "fmaf128", alias = "fusedMultiplyAdd")] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] - #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] pub const fn mul_add(self, a: f128, b: f128) -> f128 { intrinsics::fmaf128(self, a, b) } diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 1f40175eda041..f39ee22871d5f 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1684,7 +1684,6 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] #[doc(alias = "fmaf16", alias = "fusedMultiplyAdd")] #[must_use = "method returns a new number and does not mutate the original value"] - #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] pub const fn mul_add(self, a: f16, b: f16) -> f16 { intrinsics::fmaf16(self, a, b) } diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index d304d16a6b44a..6fe4285374b23 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1845,7 +1845,6 @@ pub mod math { #[doc(alias = "fmaf", alias = "fusedMultiplyAdd")] #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "core_float_math", issue = "137578")] - #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] pub const fn mul_add(x: f32, y: f32, z: f32) -> f32 { intrinsics::fmaf32(x, y, z) } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 4394eef3c08fd..d0aca152415e2 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1843,7 +1843,6 @@ pub mod math { #[doc(alias = "fma", alias = "fusedMultiplyAdd")] #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] - #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] pub const fn mul_add(x: f64, a: f64, b: f64) -> f64 { intrinsics::fmaf64(x, a, b) } diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 998a5b031c280..1a58643168332 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -233,7 +233,7 @@ impl Clone for DynMetadata { } #[doc(hidden)] -unsafe impl TrivialClone for DynMetadata {} +unsafe impl TrivialClone for DynMetadata {} impl Eq for DynMetadata {} diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index aa3af2f185287..cb43d095f5d1a 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1656,7 +1656,7 @@ impl Copy for NonNull {} #[doc(hidden)] #[unstable(feature = "trivial_clone", issue = "none")] -unsafe impl TrivialClone for NonNull {} +unsafe impl TrivialClone for NonNull {} #[unstable(feature = "coerce_unsized", issue = "18598")] impl CoerceUnsized> for NonNull where T: Unsize {} diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index 5e7b1f7038024..1bbe3ea242f6c 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -168,7 +168,7 @@ impl Copy for Unique {} #[doc(hidden)] #[unstable(feature = "trivial_clone", issue = "none")] -unsafe impl TrivialClone for Unique {} +unsafe impl TrivialClone for Unique {} #[unstable(feature = "ptr_internals", issue = "none")] impl CoerceUnsized> for Unique where T: Unsize {} diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 1c1f2cd655085..0387b442562db 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -24,7 +24,6 @@ #![feature(const_destruct)] #![feature(const_drop_in_place)] #![feature(const_eval_select)] -#![feature(const_mul_add)] #![feature(const_ops)] #![feature(const_option_ops)] #![feature(const_ref_cell)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 0401e9b39ff49..8fb1b1b05d20c 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -323,7 +323,6 @@ #![feature(char_internals)] #![feature(clone_to_uninit)] #![feature(const_convert)] -#![feature(const_mul_add)] #![feature(core_intrinsics)] #![feature(core_io_borrowed_buf)] #![feature(drop_guard)] diff --git a/library/std/src/num/f32.rs b/library/std/src/num/f32.rs index 34827a04a699d..4126080c1552a 100644 --- a/library/std/src/num/f32.rs +++ b/library/std/src/num/f32.rs @@ -217,7 +217,7 @@ impl f32 { #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] - #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] + #[rustc_const_stable(feature = "const_mul_add", since = "CURRENT_RUSTC_VERSION")] pub const fn mul_add(self, a: f32, b: f32) -> f32 { core::f32::math::mul_add(self, a, b) } diff --git a/library/std/src/num/f64.rs b/library/std/src/num/f64.rs index 5f9d63f0c57c4..e4c388addd9af 100644 --- a/library/std/src/num/f64.rs +++ b/library/std/src/num/f64.rs @@ -217,7 +217,7 @@ impl f64 { #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] - #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] + #[rustc_const_stable(feature = "const_mul_add", since = "CURRENT_RUSTC_VERSION")] pub const fn mul_add(self, a: f64, b: f64) -> f64 { core::f64::math::mul_add(self, a, b) } diff --git a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md index 6b13c97023f54..ab5e0cd68cfa4 100644 --- a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md +++ b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md @@ -91,40 +91,46 @@ future-compatibility warnings. These are a special category of lint warning. Adding a new future-compatibility warning can be done as follows. ```rust -// 1. Define the lint in `compiler/rustc_middle/src/lint/builtin.rs`: +// 1. Define the lint in `compiler/rustc_lint/src/builtin.rs` and +// add the metadata for the future incompatibility: declare_lint! { - pub YOUR_ERROR_HERE, + pub YOUR_LINT_HERE, Warn, "illegal use of foo bar baz" + @future_incompatible = FutureIncompatibleInfo { + reason: fcw!(FutureReleaseError #1234) // your tracking issue here! + }, } -// 2. Add to the list of HardwiredLints in the same file: -impl LintPass for HardwiredLints { - fn get_lints(&self) -> LintArray { - lint_array!( - .., - YOUR_ERROR_HERE - ) - } +// 2. Add a decidacted lint pass for it. +// This step can be skipped if you emit the lint as part of an existing pass. + +#[derive(Default)] +pub struct MyLintPass { + ... } -// 3. Register the lint in `compiler/rustc_lint/src/lib.rs`: -store.register_future_incompatible(sess, vec![ - ..., - FutureIncompatibleInfo { - id: LintId::of(YOUR_ERROR_HERE), - reference: "issue #1234", // your tracking issue here! +impl {Early,Late}LintPass for MyLintPass { + ... +} + +impl_lint_pass!(MyLintPass => [YOUR_LINT_HERE]); + +// 3. emit the lint somewhere in your lint pass: +cx.emit_span_lint( + YOUR_LINT_HERE, + pat.span, + // some diagnostic struct + MyDiagnostic { + ... }, -]); - -// 4. Report the lint: -tcx.lint_node( - lint::builtin::YOUR_ERROR_HERE, - path_id, - binding.span, - format!("some helper message here")); +); + ``` +Finally, register the lint in `compiler/rustc_lint/src/lib.rs`. +There are many examples in that file that already show how to do so. + #### Helpful techniques It can often be challenging to filter out new warnings from older, pre-existing @@ -221,7 +227,10 @@ The first reference you will likely find is the lint definition [in declare_lint! { pub OVERLAPPING_INHERENT_IMPLS, Deny, // this may also say Warning - "two overlapping inherent impls define an item with the same name were erroneously allowed" + "two overlapping inherent impls define an item with the same name were erroneously allowed", + @future_incompatible = FutureIncompatibleInfo { + reason: fcw!(FutureReleaseError #1234), // your tracking issue here! + }, } ``` @@ -231,19 +240,6 @@ the file as [part of a `lint_array!`][lintarraysource]; remove it too. [lintarraysource]: https://github.com/rust-lang/rust/blob/085d71c3efe453863739c1fb68fd9bd1beff214f/src/librustc/lint/builtin.rs#L252-L290 -Next, you see [a reference to `OVERLAPPING_INHERENT_IMPLS` in -`rustc_lint/src/lib.rs`][futuresource]. This is defining the lint as a "future -compatibility lint": - -```rust -FutureIncompatibleInfo { - id: LintId::of(OVERLAPPING_INHERENT_IMPLS), - reference: "issue #36889 ", -}, -``` - -Remove this too. - #### Add the lint to the list of removed lints. In `compiler/rustc_lint/src/lib.rs` there is a list of "renamed and removed lints". @@ -269,6 +265,8 @@ self.tcx.sess.add_lint(lint::builtin::OVERLAPPING_INHERENT_IMPLS, msg); ``` +You'll also often find `node_span_lint` used for this. + We want to convert this into an error. In some cases, there may be an existing error for this scenario. In others, we will need to allocate a fresh diagnostic code. [Instructions for allocating a fresh diagnostic @@ -285,6 +283,17 @@ struct_span_code_err!(self.dcx(), self.tcx.span_of_impl(item1).unwrap(), E0592, .emit(); ``` +Or better: a structured diagnostic like this: + +```rust +#[derive(Diagnostic)] +struct MyDiagnostic { + #[label] + span: Span, + ... +} +``` + #### Update tests Finally, run the test suite. These should be some tests that used to reference diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md index 82191e0a6eaf4..89c18b8e40f11 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics.md +++ b/src/doc/rustc-dev-guide/src/diagnostics.md @@ -732,8 +732,7 @@ declare_lint! { Allow, "detects anonymous parameters", @future_incompatible = FutureIncompatibleInfo { - reference: "issue #41686 ", - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), + reason: fcw!(EditionError 2018 "slug-of-edition-guide-page") }; } ``` diff --git a/src/doc/rustc-dev-guide/src/guides/editions.md b/src/doc/rustc-dev-guide/src/guides/editions.md index 107d5e737e836..535d82f8403b4 100644 --- a/src/doc/rustc-dev-guide/src/guides/editions.md +++ b/src/doc/rustc-dev-guide/src/guides/editions.md @@ -179,8 +179,7 @@ declare_lint! { Allow, "detects edition keywords being used as an identifier", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), - reference: "issue #49716 ", + reason: fcw!(EditionError 2018 "slug-of-edition-guide-page") }; } ``` diff --git a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs index 0d809c17989de..af5e3ccb674a4 100644 --- a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs +++ b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs @@ -545,7 +545,7 @@ fn ident_difference_expr_with_base_location( | (Field(_, _), Field(_, _)) | (AssignOp(_, _, _), AssignOp(_, _, _)) | (Assign(_, _, _), Assign(_, _, _)) - | (TryBlock(_), TryBlock(_)) + | (TryBlock(_, _), TryBlock(_, _)) | (Await(_, _), Await(_, _)) | (Gen(_, _, _, _), Gen(_, _, _, _)) | (Block(_, _), Block(_, _)) diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index 27b5a57c737d3..08663782a1d55 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -199,7 +199,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { ) => eq_label(ll.as_ref(), rl.as_ref()) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) && lk == rk, (Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lt, rt), (Block(lb, ll), Block(rb, rl)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lb, rb), - (TryBlock(l), TryBlock(r)) => eq_block(l, r), + (TryBlock(lb, lt), TryBlock(rb, rt)) => eq_block(lb, rb) && both(lt.as_deref(), rt.as_deref(), eq_ty), (Yield(l), Yield(r)) => eq_expr_opt(l.expr().map(Box::as_ref), r.expr().map(Box::as_ref)) && l.same_kind(r), (Ret(l), Ret(r)) => eq_expr_opt(l.as_deref(), r.as_deref()), (Break(ll, le), Break(rl, re)) => { diff --git a/src/tools/compiletest/src/directives/needs.rs b/src/tools/compiletest/src/directives/needs.rs index 208e96166021e..92b596c70ae91 100644 --- a/src/tools/compiletest/src/directives/needs.rs +++ b/src/tools/compiletest/src/directives/needs.rs @@ -432,6 +432,10 @@ fn has_symlinks() -> bool { } fn llvm_has_zstd(config: &Config) -> bool { + // FIXME(#149764): This actually queries the compiler's _default_ backend, + // which is usually LLVM, but can be another backend depending on the value + // of `rust.codegen-backends` in bootstrap.toml. + // The compiler already knows whether LLVM was built with zstd or not, // so compiletest can just ask the compiler. let output = query_rustc_output( diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 54d6e0190ddca..79e3ecc2a9c3b 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -439,6 +439,9 @@ impl<'test> TestCx<'test> { }; let mut rustc = Command::new(&self.config.rustc_path); + + self.build_all_auxiliary(&self.aux_output_dir(), &mut rustc); + rustc .arg(input) .args(&["-Z", &format!("unpretty={}", pretty_type)]) diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index 975f9be44e4d3..de96f004dc873 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -363,12 +363,13 @@ pub(crate) fn format_expr( // Style Guide RFC for InlineAsm variant pending // https://github.com/rust-dev-tools/fmt-rfcs/issues/152 ast::ExprKind::InlineAsm(..) => Ok(context.snippet(expr.span).to_owned()), - ast::ExprKind::TryBlock(ref block) => { + ast::ExprKind::TryBlock(ref block, None) => { if let rw @ Ok(_) = rewrite_single_line_block(context, "try ", block, Some(&expr.attrs), None, shape) { rw } else { + // FIXME: 9 sounds like `"do catch ".len()`, so may predate the rename // 9 = `try ` let budget = shape.width.saturating_sub(9); Ok(format!( @@ -384,6 +385,8 @@ pub(crate) fn format_expr( )) } } + // FIXME: heterogeneous try blocks, which include a type so are harder to format + ast::ExprKind::TryBlock(_, Some(_)) => Err(RewriteError::Unknown), ast::ExprKind::Gen(capture_by, ref block, ref kind, _) => { let mover = if matches!(capture_by, ast::CaptureBy::Value { .. }) { "move " diff --git a/tests/pretty/try-blocks.rs b/tests/pretty/try-blocks.rs new file mode 100644 index 0000000000000..fc0af21147692 --- /dev/null +++ b/tests/pretty/try-blocks.rs @@ -0,0 +1,6 @@ +//@ pp-exact +//@ edition: 2024 + +#![feature(try_blocks, try_blocks_heterogeneous)] + +fn main() { try { Some(1)? }; try bikeshed Result { 3 }; } diff --git a/tests/ui/anon-params/anon-params-deprecated.stderr b/tests/ui/anon-params/anon-params-deprecated.stderr index 541cb004b5b2c..0f508bad70b4a 100644 --- a/tests/ui/anon-params/anon-params-deprecated.stderr +++ b/tests/ui/anon-params/anon-params-deprecated.stderr @@ -5,7 +5,7 @@ LL | fn foo(i32); | ^^^ help: try naming the parameter or explicitly ignoring it: `_: i32` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see note: the lint level is defined here --> $DIR/anon-params-deprecated.rs:1:9 | @@ -19,7 +19,7 @@ LL | fn bar_with_default_impl(String, String) {} | ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see warning: anonymous parameters are deprecated and will be removed in the next edition --> $DIR/anon-params-deprecated.rs:13:38 @@ -28,7 +28,7 @@ LL | fn bar_with_default_impl(String, String) {} | ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see warning: 3 warnings emitted diff --git a/tests/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr b/tests/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr index 70900e612f483..a2be230994154 100644 --- a/tests/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr +++ b/tests/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr @@ -5,7 +5,7 @@ LL | pub mod await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/2015-edition-error-various-positions.rs:3:9 | @@ -20,7 +20,7 @@ LL | pub struct await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:12:16 @@ -29,7 +29,7 @@ LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:12:23 @@ -38,7 +38,7 @@ LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:17:14 @@ -47,7 +47,7 @@ LL | struct Foo { await: () } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:21:15 @@ -56,7 +56,7 @@ LL | impl Foo { fn await() {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:25:14 @@ -65,7 +65,7 @@ LL | macro_rules! await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:32:5 @@ -74,7 +74,7 @@ LL | await!(); | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:35:11 @@ -83,7 +83,7 @@ LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:35:19 @@ -92,7 +92,7 @@ LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: aborting due to 10 previous errors diff --git a/tests/ui/async-await/await-keyword/2015-edition-warning.stderr b/tests/ui/async-await/await-keyword/2015-edition-warning.stderr index 9d19a09092b94..97c69f2e72882 100644 --- a/tests/ui/async-await/await-keyword/2015-edition-warning.stderr +++ b/tests/ui/async-await/await-keyword/2015-edition-warning.stderr @@ -5,7 +5,7 @@ LL | pub mod await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/2015-edition-warning.rs:5:9 | @@ -20,7 +20,7 @@ LL | pub struct await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-warning.rs:16:16 @@ -29,7 +29,7 @@ LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-warning.rs:16:23 @@ -38,7 +38,7 @@ LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-warning.rs:23:11 @@ -47,7 +47,7 @@ LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-warning.rs:23:19 @@ -56,7 +56,7 @@ LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: aborting due to 6 previous errors diff --git a/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr b/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr index 8e1cd800b3721..54aa756e581d5 100644 --- a/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr +++ b/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr @@ -20,7 +20,7 @@ LL | extern "C" fn read_dword(Self::Assoc<'_>) -> u16; | ^^^^^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: Self::Assoc<'_>` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default error[E0185]: method `read_dword` has a `&self` declaration in the impl, but not in the trait diff --git a/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr b/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr index 34fd29a8b50c4..df1a5ce909a17 100644 --- a/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr +++ b/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr @@ -5,7 +5,7 @@ LL | extern "C" fn read_dword(Self::Assoc<'_>) -> u16; | ^^^^^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: Self::Assoc<'_>` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default error[E0185]: method `read_dword` has a `&self` declaration in the impl, but not in the trait diff --git a/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr b/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr index 943695d75fcef..c33d5b003042e 100644 --- a/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr +++ b/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr @@ -4,6 +4,7 @@ warning: panic message is not a string literal LL | panic!({ "foo" }); | ^^^^^^^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see = note: `#[warn(non_fmt_panics)]` (part of `#[warn(rust_2021_compatibility)]`) on by default diff --git a/tests/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr b/tests/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr index 0d53fb024acab..c0e794cee2928 100644 --- a/tests/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr +++ b/tests/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr @@ -5,7 +5,7 @@ LL | pub mod dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:11:9 | @@ -20,7 +20,7 @@ LL | pub struct dyn; | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:22:16 @@ -29,7 +29,7 @@ LL | use outer_mod::dyn::dyn; | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:22:21 @@ -38,7 +38,7 @@ LL | use outer_mod::dyn::dyn; | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:29:11 @@ -47,7 +47,7 @@ LL | match dyn { dyn => {} } | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:29:17 @@ -56,7 +56,7 @@ LL | match dyn { dyn => {} } | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:34:17 @@ -65,7 +65,7 @@ LL | macro_defn::dyn(); | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:44:18 @@ -74,7 +74,7 @@ LL | macro_rules! dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:52:12 @@ -83,7 +83,7 @@ LL | pub fn dyn() -> ::outer_mod::dyn::dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:52:34 @@ -92,7 +92,7 @@ LL | pub fn dyn() -> ::outer_mod::dyn::dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:52:39 @@ -101,7 +101,7 @@ LL | pub fn dyn() -> ::outer_mod::dyn::dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:59:22 @@ -110,7 +110,7 @@ LL | ::outer_mod::dyn::dyn | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:59:27 @@ -119,7 +119,7 @@ LL | ::outer_mod::dyn::dyn | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:68:23 @@ -128,7 +128,7 @@ LL | pub fn boxed() -> dyn!( | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: aborting due to 14 previous errors diff --git a/tests/ui/editions/edition-raw-pointer-method-2015.stderr b/tests/ui/editions/edition-raw-pointer-method-2015.stderr index 3d8b3f633ce8c..ad8beb049f9fe 100644 --- a/tests/ui/editions/edition-raw-pointer-method-2015.stderr +++ b/tests/ui/editions/edition-raw-pointer-method-2015.stderr @@ -5,7 +5,7 @@ LL | let _ = y.is_null(); | ^^^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #46906 + = note: for more information, see note: the lint level is defined here --> $DIR/edition-raw-pointer-method-2015.rs:5:8 | diff --git a/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr b/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr index ed1ebe4466afd..6878bde85b8b9 100644 --- a/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr +++ b/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr @@ -8,7 +8,7 @@ LL | | )) {} | |_____^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default help: try naming the parameter or explicitly ignoring it | diff --git a/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.rs b/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.rs new file mode 100644 index 0000000000000..9f0073eac9adc --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.rs @@ -0,0 +1,9 @@ +//@ edition: 2018 + +pub fn main() { + let try_result = try bikeshed Option<_> { //~ ERROR `try bikeshed` expression is experimental + let x = 5; + x + }; + assert_eq!(try_result, Some(5)); +} diff --git a/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.stderr b/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.stderr new file mode 100644 index 0000000000000..0d31dc507fdde --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.stderr @@ -0,0 +1,17 @@ +error[E0658]: `try bikeshed` expression is experimental + --> $DIR/feature-gate-try_blocks_heterogeneous.rs:4:22 + | +LL | let try_result = try bikeshed Option<_> { + | ______________________^ +LL | | let x = 5; +LL | | x +LL | | }; + | |_____^ + | + = note: see issue #149488 for more information + = help: add `#![feature(try_blocks_heterogeneous)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/fn/error-recovery-mismatch.stderr b/tests/ui/fn/error-recovery-mismatch.stderr index 400af46e2a278..7a320c6bc695b 100644 --- a/tests/ui/fn/error-recovery-mismatch.stderr +++ b/tests/ui/fn/error-recovery-mismatch.stderr @@ -26,7 +26,7 @@ LL | fn fold(&self, _: T, &self._) {} | ^ help: try naming the parameter or explicitly ignoring it: `_: _` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default error[E0121]: the placeholder `_` is not allowed within types on item signatures for methods diff --git a/tests/ui/inference/inference-variable-behind-raw-pointer.stderr b/tests/ui/inference/inference-variable-behind-raw-pointer.stderr index 50202ea3db3e3..360d4dd22cebb 100644 --- a/tests/ui/inference/inference-variable-behind-raw-pointer.stderr +++ b/tests/ui/inference/inference-variable-behind-raw-pointer.stderr @@ -5,7 +5,7 @@ LL | if data.is_null() {} | ^^^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #46906 + = note: for more information, see = note: `#[warn(tyvar_behind_raw_pointer)]` (part of `#[warn(rust_2018_compatibility)]`) on by default warning: 1 warning emitted diff --git a/tests/ui/lang-items/issue-83471.stderr b/tests/ui/lang-items/issue-83471.stderr index 0c2b403902e2d..1d5b1c4cd3ed7 100644 --- a/tests/ui/lang-items/issue-83471.stderr +++ b/tests/ui/lang-items/issue-83471.stderr @@ -47,7 +47,7 @@ LL | fn call(export_name); | ^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: export_name` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default error[E0718]: `fn` lang item must be applied to a trait with 1 generic argument diff --git a/tests/ui/lint/future-incompatible-lint-group.stderr b/tests/ui/lint/future-incompatible-lint-group.stderr index bac24740fb4e1..ff1e54f5dea30 100644 --- a/tests/ui/lint/future-incompatible-lint-group.stderr +++ b/tests/ui/lint/future-incompatible-lint-group.stderr @@ -5,7 +5,7 @@ LL | fn f(u8) {} | ^^ help: try naming the parameter or explicitly ignoring it: `_: u8` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default error: ambiguous associated item diff --git a/tests/ui/lint/lint-pre-expansion-extern-module.stderr b/tests/ui/lint/lint-pre-expansion-extern-module.stderr index 32c76da98b525..1de1784fc9c54 100644 --- a/tests/ui/lint/lint-pre-expansion-extern-module.stderr +++ b/tests/ui/lint/lint-pre-expansion-extern-module.stderr @@ -5,7 +5,7 @@ LL | pub fn try() {} | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see = note: `-W keyword-idents-2018` implied by `-W rust-2018-compatibility` = help: to override `-W rust-2018-compatibility` add `#[allow(keyword_idents_2018)]` diff --git a/tests/ui/macros/expr_2021_cargo_fix_edition.stderr b/tests/ui/macros/expr_2021_cargo_fix_edition.stderr index 795d99449c266..17ec247bd4def 100644 --- a/tests/ui/macros/expr_2021_cargo_fix_edition.stderr +++ b/tests/ui/macros/expr_2021_cargo_fix_edition.stderr @@ -5,7 +5,7 @@ LL | ($e:expr) => { | ^^^^ | = warning: this changes meaning in Rust 2024 - = note: for more information, see Migration Guide + = note: for more information, see note: the lint level is defined here --> $DIR/expr_2021_cargo_fix_edition.rs:4:9 | @@ -23,7 +23,7 @@ LL | ($($i:expr)*) => { }; | ^^^^ | = warning: this changes meaning in Rust 2024 - = note: for more information, see Migration Guide + = note: for more information, see help: to keep the existing behavior, use the `expr_2021` fragment specifier | LL | ($($i:expr_2021)*) => { }; diff --git a/tests/ui/macros/non-fmt-panic.stderr b/tests/ui/macros/non-fmt-panic.stderr index 43f59782ee727..8a89d5ea79394 100644 --- a/tests/ui/macros/non-fmt-panic.stderr +++ b/tests/ui/macros/non-fmt-panic.stderr @@ -4,6 +4,7 @@ warning: panic message contains a brace LL | panic!("here's a brace: {"); | ^ | + = note: for more information, see = note: this message is not used as a format string, but will be in Rust 2021 = note: `#[warn(non_fmt_panics)]` (part of `#[warn(rust_2021_compatibility)]`) on by default help: add a "{}" format string to use the message literally @@ -17,6 +18,7 @@ warning: panic message contains a brace LL | unreachable!("here's a brace: {"); | ^ | + = note: for more information, see = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | @@ -29,6 +31,7 @@ warning: panic message contains a brace LL | std::panic!("another one: }"); | ^ | + = note: for more information, see = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | @@ -41,6 +44,7 @@ warning: panic message contains an unused formatting placeholder LL | core::panic!("Hello {}"); | ^^ | + = note: for more information, see = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 help: add the missing argument | @@ -57,6 +61,7 @@ warning: panic message contains unused formatting placeholders LL | assert!(false, "{:03x} {test} bla"); | ^^^^^^ ^^^^^^ | + = note: for more information, see = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 help: add the missing arguments | @@ -73,6 +78,7 @@ warning: panic message is not a string literal LL | assert!(false, S); | ^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -86,6 +92,7 @@ warning: panic message is not a string literal LL | assert!(false, 123); | ^^^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -99,6 +106,7 @@ warning: panic message is not a string literal LL | assert!(false, Some(123)); | ^^^^^^^^^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{:?}" format string to use the `Debug` implementation of `Option` @@ -112,6 +120,7 @@ warning: panic message contains braces LL | debug_assert!(false, "{{}} bla"); | ^^^^ | + = note: for more information, see = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | @@ -124,6 +133,7 @@ warning: panic message is not a string literal LL | panic!(C); | ^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -137,6 +147,7 @@ warning: panic message is not a string literal LL | panic!(S); | ^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -150,6 +161,7 @@ warning: panic message is not a string literal LL | unreachable!(S); | ^ | + = note: for more information, see = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -163,6 +175,7 @@ warning: panic message is not a string literal LL | unreachable!(S); | ^ | + = note: for more information, see = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -176,6 +189,7 @@ warning: panic message is not a string literal LL | std::panic!(123); | ^^^ | + = note: for more information, see = note: this usage of `std::panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -194,6 +208,7 @@ warning: panic message is not a string literal LL | core::panic!(&*"abc"); | ^^^^^^^ | + = note: for more information, see = note: this usage of `core::panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -207,6 +222,7 @@ warning: panic message is not a string literal LL | panic!(Some(123)); | ^^^^^^^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{:?}" format string to use the `Debug` implementation of `Option` @@ -225,6 +241,7 @@ warning: panic message contains an unused formatting placeholder LL | panic!(concat!("{", "}")); | ^^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 help: add the missing argument | @@ -241,6 +258,7 @@ warning: panic message contains braces LL | panic!(concat!("{", "{")); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | @@ -253,6 +271,7 @@ warning: panic message contains an unused formatting placeholder LL | fancy_panic::fancy_panic!("test {} 123"); | ^^ | + = note: for more information, see = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 warning: panic message is not a string literal @@ -261,6 +280,7 @@ warning: panic message is not a string literal LL | panic!(a!()); | ^^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -279,6 +299,7 @@ warning: panic message is not a string literal LL | unreachable!(a!()); | ^^^^ | + = note: for more information, see = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -292,6 +313,7 @@ warning: panic message is not a string literal LL | panic!(format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see = note: the `panic!()` macro supports formatting, so there's no need for the `format!()` macro here @@ -307,6 +329,7 @@ warning: panic message is not a string literal LL | unreachable!(format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see = note: the `unreachable!()` macro supports formatting, so there's no need for the `format!()` macro here @@ -322,6 +345,7 @@ warning: panic message is not a string literal LL | assert!(false, format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see = note: the `assert!()` macro supports formatting, so there's no need for the `format!()` macro here @@ -337,6 +361,7 @@ warning: panic message is not a string literal LL | debug_assert!(false, format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this usage of `debug_assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see = note: the `debug_assert!()` macro supports formatting, so there's no need for the `format!()` macro here @@ -352,6 +377,7 @@ warning: panic message is not a string literal LL | panic![123]; | ^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -370,6 +396,7 @@ warning: panic message is not a string literal LL | panic!{123}; | ^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -390,6 +417,7 @@ LL | panic!(v); | | | help: use std::panic::panic_any instead: `std::panic::panic_any` | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see @@ -399,6 +427,7 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see @@ -408,6 +437,7 @@ warning: panic message is not a string literal LL | panic!(v); | ^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{:?}" format string to use the `Debug` implementation of `T` @@ -426,6 +456,7 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{:?}" format string to use the `Debug` implementation of `T` @@ -439,6 +470,7 @@ warning: panic message is not a string literal LL | panic!(v); | ^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -457,6 +489,7 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -470,6 +503,7 @@ warning: panic message is not a string literal LL | panic!(v); | ^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -488,6 +522,7 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message diff --git a/tests/ui/rust-2018/async-ident-allowed.stderr b/tests/ui/rust-2018/async-ident-allowed.stderr index 378c81d3c770b..1bdfc7bae1028 100644 --- a/tests/ui/rust-2018/async-ident-allowed.stderr +++ b/tests/ui/rust-2018/async-ident-allowed.stderr @@ -5,7 +5,7 @@ LL | let async = 3; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/async-ident-allowed.rs:3:9 | diff --git a/tests/ui/rust-2018/async-ident.stderr b/tests/ui/rust-2018/async-ident.stderr index 4ab061dd6f599..2c4cb7e1d96e1 100644 --- a/tests/ui/rust-2018/async-ident.stderr +++ b/tests/ui/rust-2018/async-ident.stderr @@ -5,7 +5,7 @@ LL | fn async() {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/async-ident.rs:2:9 | @@ -20,7 +20,7 @@ LL | ($async:expr, async) => {}; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:17:6 @@ -29,7 +29,7 @@ LL | foo!(async); | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:26:11 @@ -38,7 +38,7 @@ LL | trait async {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:30:10 @@ -47,7 +47,7 @@ LL | impl async for MyStruct {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:36:12 @@ -56,7 +56,7 @@ LL | static async: u32 = 0; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:42:11 @@ -65,7 +65,7 @@ LL | const async: u32 = 0; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:48:15 @@ -74,7 +74,7 @@ LL | impl Foo { fn async() {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:53:12 @@ -83,7 +83,7 @@ LL | struct async {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:56:9 @@ -92,7 +92,7 @@ LL | let async: async = async {}; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:56:16 @@ -101,7 +101,7 @@ LL | let async: async = async {}; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:56:24 @@ -110,7 +110,7 @@ LL | let async: async = async {}; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:67:19 @@ -119,7 +119,7 @@ LL | () => (pub fn async() {}) | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:74:6 @@ -128,7 +128,7 @@ LL | (async) => (1) | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: aborting due to 14 previous errors diff --git a/tests/ui/rust-2018/dyn-keyword.stderr b/tests/ui/rust-2018/dyn-keyword.stderr index f8245bc88f573..733583f32b9b9 100644 --- a/tests/ui/rust-2018/dyn-keyword.stderr +++ b/tests/ui/rust-2018/dyn-keyword.stderr @@ -5,7 +5,7 @@ LL | let dyn = (); | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/dyn-keyword.rs:5:9 | diff --git a/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr b/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr index c0a322edcd647..b59604f6427e3 100644 --- a/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr @@ -5,7 +5,7 @@ LL | let _: ::Bar = (); | ^^^^^^^^^^ help: use `crate`: `crate::foo::Foo` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/edition-lint-fully-qualified-paths.rs:4:9 | @@ -19,7 +19,7 @@ LL | let _: ::Bar = (); | ^^^^^^^^^^ help: use `crate`: `crate::foo::Foo` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition @@ -29,7 +29,7 @@ LL | let _: <::foo::Baz as foo::Foo>::Bar = (); | ^^^^^^^^^^ help: use `crate`: `crate::foo::Baz` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: aborting due to 3 previous errors diff --git a/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr b/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr index 041572be84411..af02b30a99bde 100644 --- a/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr @@ -5,7 +5,7 @@ LL | use foo::{bar::{baz::{}}}; | ^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}}}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/edition-lint-nested-empty-paths.rs:4:9 | @@ -19,7 +19,7 @@ LL | use foo::{bar::{XX, baz::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{XX, baz::{}}}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-nested-empty-paths.rs:21:5 @@ -28,7 +28,7 @@ LL | use foo::{bar::{XX, baz::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{XX, baz::{}}}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition @@ -38,7 +38,7 @@ LL | use foo::{bar::{baz::{}, baz1::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}, baz1::{}}}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-nested-empty-paths.rs:27:5 @@ -47,7 +47,7 @@ LL | use foo::{bar::{baz::{}, baz1::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}, baz1::{}}}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 5 previous errors diff --git a/tests/ui/rust-2018/edition-lint-nested-paths.stderr b/tests/ui/rust-2018/edition-lint-nested-paths.stderr index 4a70bb7e5c875..0f60b16ac9aab 100644 --- a/tests/ui/rust-2018/edition-lint-nested-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-nested-paths.stderr @@ -5,7 +5,7 @@ LL | use foo::{a, b}; | ^^^^^^^^^^^ help: use `crate`: `crate::foo::{a, b}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/edition-lint-nested-paths.rs:4:9 | @@ -19,7 +19,7 @@ LL | use foo::{a, b}; | ^^^^^^^^^^^ help: use `crate`: `crate::foo::{a, b}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition @@ -29,7 +29,7 @@ LL | use foo::{self as x, c}; | ^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{self as x, c}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-nested-paths.rs:23:13 @@ -38,7 +38,7 @@ LL | use foo::{self as x, c}; | ^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{self as x, c}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors diff --git a/tests/ui/rust-2018/edition-lint-paths.stderr b/tests/ui/rust-2018/edition-lint-paths.stderr index fde17338d98a7..26db6e402a9e2 100644 --- a/tests/ui/rust-2018/edition-lint-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-paths.stderr @@ -5,7 +5,7 @@ LL | use bar::Bar; | ^^^^^^^^ help: use `crate`: `crate::bar::Bar` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/edition-lint-paths.rs:5:9 | @@ -19,7 +19,7 @@ LL | use bar; | ^^^ help: use `crate`: `crate::bar` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:25:9 @@ -28,7 +28,7 @@ LL | use {main, Bar as SomethingElse}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::{main, Bar as SomethingElse}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:25:9 @@ -37,7 +37,7 @@ LL | use {main, Bar as SomethingElse}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::{main, Bar as SomethingElse}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition @@ -47,7 +47,7 @@ LL | use {main, Bar as SomethingElse}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::{main, Bar as SomethingElse}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition @@ -57,7 +57,7 @@ LL | use bar::Bar; | ^^^^^^^^ help: use `crate`: `crate::bar::Bar` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:52:9 @@ -66,7 +66,7 @@ LL | use *; | ^ help: use `crate`: `crate::*` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:57:6 @@ -75,7 +75,7 @@ LL | impl ::foo::SomeTrait for u32 {} | ^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::SomeTrait` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:62:13 @@ -84,7 +84,7 @@ LL | let x = ::bar::Bar; | ^^^^^^^^^^ help: use `crate`: `crate::bar::Bar` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: aborting due to 9 previous errors diff --git a/tests/ui/rust-2018/extern-crate-rename.stderr b/tests/ui/rust-2018/extern-crate-rename.stderr index 36986c89c62bc..bce9e73ee65aa 100644 --- a/tests/ui/rust-2018/extern-crate-rename.stderr +++ b/tests/ui/rust-2018/extern-crate-rename.stderr @@ -5,7 +5,7 @@ LL | use my_crate::foo; | ^^^^^^^^^^^^^ help: use `crate`: `crate::my_crate::foo` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/extern-crate-rename.rs:8:9 | diff --git a/tests/ui/rust-2018/extern-crate-submod.stderr b/tests/ui/rust-2018/extern-crate-submod.stderr index 85e26d72a673b..ed4266d3b091f 100644 --- a/tests/ui/rust-2018/extern-crate-submod.stderr +++ b/tests/ui/rust-2018/extern-crate-submod.stderr @@ -5,7 +5,7 @@ LL | use m::edition_lint_paths::foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::m::edition_lint_paths::foo` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/extern-crate-submod.rs:9:9 | diff --git a/tests/ui/rust-2018/try-ident.stderr b/tests/ui/rust-2018/try-ident.stderr index aca623d7d4829..3af2196ce35bf 100644 --- a/tests/ui/rust-2018/try-ident.stderr +++ b/tests/ui/rust-2018/try-ident.stderr @@ -5,7 +5,7 @@ LL | try(); | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/try-ident.rs:5:9 | @@ -20,7 +20,7 @@ LL | fn try() { | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see warning: 2 warnings emitted diff --git a/tests/ui/rust-2018/try-macro.stderr b/tests/ui/rust-2018/try-macro.stderr index 20105e1868f2e..89366381c8c6e 100644 --- a/tests/ui/rust-2018/try-macro.stderr +++ b/tests/ui/rust-2018/try-macro.stderr @@ -5,7 +5,7 @@ LL | try!(x); | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/try-macro.rs:7:9 | diff --git a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr index 8bb2bb290d3dc..2521341723a22 100644 --- a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr +++ b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr @@ -11,7 +11,7 @@ LL | std::ptr::from_ref(num).cast_mut().as_deref(); | ^^^^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #46906 + = note: for more information, see = note: `#[warn(tyvar_behind_raw_pointer)]` (part of `#[warn(rust_2018_compatibility)]`) on by default warning: type annotations needed @@ -21,7 +21,7 @@ LL | std::ptr::from_ref(num).cast_mut().as_deref(); | ^^^^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #46906 + = note: for more information, see error[E0599]: no method named `as_deref` found for raw pointer `*mut _` in the current scope --> $DIR/ice-unwrap-probe-many-result-125876.rs:5:40 diff --git a/tests/ui/try-block/try-block-bad-type-heterogeneous.rs b/tests/ui/try-block/try-block-bad-type-heterogeneous.rs new file mode 100644 index 0000000000000..b099651bf8a9e --- /dev/null +++ b/tests/ui/try-block/try-block-bad-type-heterogeneous.rs @@ -0,0 +1,21 @@ +//@ edition: 2018 + +#![feature(try_blocks_heterogeneous)] + +pub fn main() { + let res = try bikeshed Result { + Err("")?; //~ ERROR `?` couldn't convert the error + 5 + }; + + let res = try bikeshed Result { + "" //~ ERROR type mismatch + }; + + let res = try bikeshed Result { }; //~ ERROR type mismatch + + let res = try bikeshed () { }; + //~^ ERROR a `try` block must return `Result` or `Option` + + let res = try bikeshed i32 { 5 }; //~ ERROR a `try` block must return `Result` or `Option` +} diff --git a/tests/ui/try-block/try-block-bad-type-heterogeneous.stderr b/tests/ui/try-block/try-block-bad-type-heterogeneous.stderr new file mode 100644 index 0000000000000..7c7cedd392e64 --- /dev/null +++ b/tests/ui/try-block/try-block-bad-type-heterogeneous.stderr @@ -0,0 +1,46 @@ +error[E0277]: `?` couldn't convert the error to `TryFromSliceError` + --> $DIR/try-block-bad-type-heterogeneous.rs:7:16 + | +LL | Err("")?; + | -------^ the trait `From<&str>` is not implemented for `TryFromSliceError` + | | + | this can't be annotated with `?` because it has type `Result<_, &str>` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait +help: the trait `From<&str>` is not implemented for `TryFromSliceError` + but trait `From` is implemented for it + --> $SRC_DIR/core/src/array/mod.rs:LL:COL + = help: for that trait implementation, expected `Infallible`, found `&str` + +error[E0271]: type mismatch resolving ` as Try>::Output == &str` + --> $DIR/try-block-bad-type-heterogeneous.rs:12:9 + | +LL | "" + | ^^ expected `&str`, found `i32` + +error[E0271]: type mismatch resolving ` as Try>::Output == ()` + --> $DIR/try-block-bad-type-heterogeneous.rs:15:47 + | +LL | let res = try bikeshed Result { }; + | ^ expected `()`, found `i32` + +error[E0277]: a `try` block must return `Result` or `Option` (or another type that implements `Try`) + --> $DIR/try-block-bad-type-heterogeneous.rs:17:33 + | +LL | let res = try bikeshed () { }; + | ^ could not wrap the final value of the block as `()` doesn't implement `Try` + | + = help: the trait `Try` is not implemented for `()` + +error[E0277]: a `try` block must return `Result` or `Option` (or another type that implements `Try`) + --> $DIR/try-block-bad-type-heterogeneous.rs:20:34 + | +LL | let res = try bikeshed i32 { 5 }; + | ^ could not wrap the final value of the block as `i32` doesn't implement `Try` + | + = help: the trait `Try` is not implemented for `i32` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/try-block/try-block-heterogeneous.rs b/tests/ui/try-block/try-block-heterogeneous.rs new file mode 100644 index 0000000000000..0b17b7c8655dc --- /dev/null +++ b/tests/ui/try-block/try-block-heterogeneous.rs @@ -0,0 +1,19 @@ +//@ check-pass +//@ edition: 2018 + +#![feature(try_blocks_heterogeneous)] + +fn foo() -> Result<(), u16> { Ok(()) } + +fn bar() -> Result<(), u32> { Ok(()) } + +fn whatever() -> Result<(), String> { + try bikeshed _ {} +} + +fn main() { + try bikeshed Result<(), u64> { + foo()?; + bar()?; + }; +} diff --git a/tests/ui/unpretty/exhaustive.expanded.stdout b/tests/ui/unpretty/exhaustive.expanded.stdout index 9e6797c727f03..1fc9e6a726936 100644 --- a/tests/ui/unpretty/exhaustive.expanded.stdout +++ b/tests/ui/unpretty/exhaustive.expanded.stdout @@ -28,6 +28,7 @@ #![feature(trace_macros)] #![feature(trait_alias)] #![feature(try_blocks)] +#![feature(try_blocks_heterogeneous)] #![feature(yeet_expr)] #![allow(incomplete_features)] #[macro_use] @@ -222,7 +223,12 @@ mod expressions { } /// ExprKind::TryBlock - fn expr_try_block() { try {} try { return; } } + fn expr_try_block() { + try {} + try { return; } + try bikeshed Option<_> {} + try bikeshed Option { None? } + } /// ExprKind::Assign fn expr_assign() { let expr; expr = true; } diff --git a/tests/ui/unpretty/exhaustive.hir.stderr b/tests/ui/unpretty/exhaustive.hir.stderr index eb5c186bd2c05..f6800fc9c1e6f 100644 --- a/tests/ui/unpretty/exhaustive.hir.stderr +++ b/tests/ui/unpretty/exhaustive.hir.stderr @@ -1,17 +1,17 @@ error[E0697]: closures cannot be static - --> $DIR/exhaustive.rs:210:9 + --> $DIR/exhaustive.rs:211:9 | LL | static || value; | ^^^^^^^^^ error[E0697]: closures cannot be static - --> $DIR/exhaustive.rs:211:9 + --> $DIR/exhaustive.rs:212:9 | LL | static move || value; | ^^^^^^^^^^^^^^ error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/exhaustive.rs:240:13 + --> $DIR/exhaustive.rs:241:13 | LL | fn expr_await() { | --------------- this is not `async` @@ -20,19 +20,19 @@ LL | fut.await; | ^^^^^ only allowed inside `async` functions and blocks error: in expressions, `_` can only be used on the left-hand side of an assignment - --> $DIR/exhaustive.rs:289:9 + --> $DIR/exhaustive.rs:292:9 | LL | _; | ^ `_` not allowed here error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:299:9 + --> $DIR/exhaustive.rs:302:9 | LL | x::(); | ^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:300:9 + --> $DIR/exhaustive.rs:303:9 | LL | x::(T, T) -> T; | ^^^^^^^^^^^^^^ only `Fn` traits may use parentheses @@ -44,31 +44,31 @@ LL + x:: -> T; | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:301:9 + --> $DIR/exhaustive.rs:304:9 | LL | crate::() -> ()::expressions::() -> ()::expr_path; | ^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:301:26 + --> $DIR/exhaustive.rs:304:26 | LL | crate::() -> ()::expressions::() -> ()::expr_path; | ^^^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:304:9 + --> $DIR/exhaustive.rs:307:9 | LL | core::()::marker::()::PhantomData; | ^^^^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:304:19 + --> $DIR/exhaustive.rs:307:19 | LL | core::()::marker::()::PhantomData; | ^^^^^^^^^^ only `Fn` traits may use parentheses error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks - --> $DIR/exhaustive.rs:391:9 + --> $DIR/exhaustive.rs:394:9 | LL | yield; | ^^^^^ @@ -79,7 +79,7 @@ LL | #[coroutine] fn expr_yield() { | ++++++++++++ error[E0703]: invalid ABI: found `C++` - --> $DIR/exhaustive.rs:471:23 + --> $DIR/exhaustive.rs:474:23 | LL | unsafe extern "C++" {} | ^^^^^ invalid ABI @@ -87,7 +87,7 @@ LL | unsafe extern "C++" {} = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions error: `..` patterns are not allowed here - --> $DIR/exhaustive.rs:678:13 + --> $DIR/exhaustive.rs:681:13 | LL | let ..; | ^^ @@ -95,13 +95,13 @@ LL | let ..; = note: only allowed in tuple, tuple struct, and slice patterns error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:793:16 + --> $DIR/exhaustive.rs:796:16 | LL | let _: T() -> !; | ^^^^^^^^ only `Fn` traits may use parentheses error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:807:16 + --> $DIR/exhaustive.rs:810:16 | LL | let _: impl Send; | ^^^^^^^^^ @@ -112,7 +112,7 @@ LL | let _: impl Send; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:808:16 + --> $DIR/exhaustive.rs:811:16 | LL | let _: impl Send + 'static; | ^^^^^^^^^^^^^^^^^^^ @@ -123,7 +123,7 @@ LL | let _: impl Send + 'static; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:809:16 + --> $DIR/exhaustive.rs:812:16 | LL | let _: impl 'static + Send; | ^^^^^^^^^^^^^^^^^^^ @@ -134,7 +134,7 @@ LL | let _: impl 'static + Send; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:810:16 + --> $DIR/exhaustive.rs:813:16 | LL | let _: impl ?Sized; | ^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | let _: impl ?Sized; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:811:16 + --> $DIR/exhaustive.rs:814:16 | LL | let _: impl [const] Clone; | ^^^^^^^^^^^^^^^^^^ @@ -156,7 +156,7 @@ LL | let _: impl [const] Clone; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:812:16 + --> $DIR/exhaustive.rs:815:16 | LL | let _: impl for<'a> Send; | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index 873febbbd84d7..9396e937d8433 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -27,6 +27,7 @@ #![feature(trace_macros)] #![feature(trait_alias)] #![feature(try_blocks)] +#![feature(try_blocks_heterogeneous)] #![feature(yeet_expr)] #![allow(incomplete_features)] #[attr = MacroUse {arguments: UseAll}] @@ -253,7 +254,19 @@ mod expressions { } /// ExprKind::TryBlock - fn expr_try_block() { { from_output(()) } { return; from_output(()) } } + fn expr_try_block() { + { from_output(()) } + { return; from_output(()) } + type_ascribe!({ from_output(()) }, Option<_>); + type_ascribe!({ + from_output(match branch(None) { + Break { 0: residual } => #[allow(unreachable_code)] + break from_residual(residual), + Continue { 0: val } => #[allow(unreachable_code)] + val, + }) + }, Option) + } /// ExprKind::Assign fn expr_assign() { let expr; expr = true; } diff --git a/tests/ui/unpretty/exhaustive.rs b/tests/ui/unpretty/exhaustive.rs index 0983a0a7e4372..0bbc87845695f 100644 --- a/tests/ui/unpretty/exhaustive.rs +++ b/tests/ui/unpretty/exhaustive.rs @@ -27,6 +27,7 @@ #![feature(trace_macros)] #![feature(trait_alias)] #![feature(try_blocks)] +#![feature(try_blocks_heterogeneous)] #![feature(yeet_expr)] #![allow(incomplete_features)] @@ -244,6 +245,8 @@ mod expressions { fn expr_try_block() { try {} try { return; } + try bikeshed Option<_> { } + try bikeshed Option { None? } } /// ExprKind::Assign