diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 09f376a480050..6c514c75a500c 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2088,15 +2088,15 @@ pub enum InlineAsmRegOrRegClass { bitflags::bitflags! { #[derive(Encodable, Decodable, HashStable_Generic)] pub struct InlineAsmOptions: u16 { - const PURE = 1 << 0; - const NOMEM = 1 << 1; - const READONLY = 1 << 2; + const PURE = 1 << 0; + const NOMEM = 1 << 1; + const READONLY = 1 << 2; const PRESERVES_FLAGS = 1 << 3; - const NORETURN = 1 << 4; - const NOSTACK = 1 << 5; - const ATT_SYNTAX = 1 << 6; - const RAW = 1 << 7; - const MAY_UNWIND = 1 << 8; + const NORETURN = 1 << 4; + const NOSTACK = 1 << 5; + const ATT_SYNTAX = 1 << 6; + const RAW = 1 << 7; + const MAY_UNWIND = 1 << 8; } } diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 4d3620ee8b0f0..bd7a85b07a09e 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -15,7 +15,7 @@ #![feature(if_let_guard)] #![cfg_attr(bootstrap, feature(label_break_value))] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(min_specialization)] #![feature(negative_impls)] #![feature(slice_internals)] diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index 5edeb54be5f0f..b40ad6f700e82 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -297,11 +297,11 @@ impl ExprPrecedence { match self { ExprPrecedence::Closure => PREC_CLOSURE, - ExprPrecedence::Break | - ExprPrecedence::Continue | - ExprPrecedence::Ret | - ExprPrecedence::Yield | - ExprPrecedence::Yeet => PREC_JUMP, + ExprPrecedence::Break + | ExprPrecedence::Continue + | ExprPrecedence::Ret + | ExprPrecedence::Yield + | ExprPrecedence::Yeet => PREC_JUMP, // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence @@ -318,43 +318,43 @@ impl ExprPrecedence { ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8, // Unary, prefix - ExprPrecedence::Box | - ExprPrecedence::AddrOf | + ExprPrecedence::Box + | ExprPrecedence::AddrOf // Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`. // However, this is not exactly right. When `let _ = a` is the LHS of a binop we // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b` // but we need to print `(let _ = a) < b` as-is with parens. - ExprPrecedence::Let | - ExprPrecedence::Unary => PREC_PREFIX, + | ExprPrecedence::Let + | ExprPrecedence::Unary => PREC_PREFIX, // Unary, postfix - ExprPrecedence::Await | - ExprPrecedence::Call | - ExprPrecedence::MethodCall | - ExprPrecedence::Field | - ExprPrecedence::Index | - ExprPrecedence::Try | - ExprPrecedence::InlineAsm | - ExprPrecedence::Mac => PREC_POSTFIX, + ExprPrecedence::Await + | ExprPrecedence::Call + | ExprPrecedence::MethodCall + | ExprPrecedence::Field + | ExprPrecedence::Index + | ExprPrecedence::Try + | ExprPrecedence::InlineAsm + | ExprPrecedence::Mac => PREC_POSTFIX, // Never need parens - ExprPrecedence::Array | - ExprPrecedence::Repeat | - ExprPrecedence::Tup | - ExprPrecedence::Lit | - ExprPrecedence::Path | - ExprPrecedence::Paren | - ExprPrecedence::If | - ExprPrecedence::While | - ExprPrecedence::ForLoop | - ExprPrecedence::Loop | - ExprPrecedence::Match | - ExprPrecedence::ConstBlock | - ExprPrecedence::Block | - ExprPrecedence::TryBlock | - ExprPrecedence::Async | - ExprPrecedence::Struct | - ExprPrecedence::Err => PREC_PAREN, + ExprPrecedence::Array + | ExprPrecedence::Repeat + | ExprPrecedence::Tup + | ExprPrecedence::Lit + | ExprPrecedence::Path + | ExprPrecedence::Paren + | ExprPrecedence::If + | ExprPrecedence::While + | ExprPrecedence::ForLoop + | ExprPrecedence::Loop + | ExprPrecedence::Match + | ExprPrecedence::ConstBlock + | ExprPrecedence::Block + | ExprPrecedence::TryBlock + | ExprPrecedence::Async + | ExprPrecedence::Struct + | ExprPrecedence::Err => PREC_PAREN, } } } diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index e0869bb1063d9..12a0cc0d25508 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -1,8 +1,6 @@ use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext}; use rustc_ast::{Block, BlockCheckMode, Local, LocalKind, Stmt, StmtKind}; use rustc_hir as hir; -use rustc_session::parse::feature_err; -use rustc_span::sym; use smallvec::SmallVec; @@ -92,15 +90,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let hir_id = self.lower_node_id(l.id); let pat = self.lower_pat(&l.pat); let els = if let LocalKind::InitElse(_, els) = &l.kind { - if !self.tcx.features().let_else { - feature_err( - &self.tcx.sess.parse_sess, - sym::let_else, - l.span, - "`let...else` statements are unstable", - ) - .emit(); - } Some(self.lower_block(els, false)) } else { None diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index cb6bf0863b387..d2ce6bdb08e58 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -32,7 +32,7 @@ #![feature(box_patterns)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(never_type)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index af25982e2887b..8aa9d57f046a9 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -9,7 +9,7 @@ #![feature(if_let_guard)] #![feature(iter_is_partitioned)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![recursion_limit = "256"] #[macro_use] diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs index 053f848aacbf7..52e65a9c7743d 100644 --- a/compiler/rustc_attr/src/lib.rs +++ b/compiler/rustc_attr/src/lib.rs @@ -5,7 +5,7 @@ //! to this crate. #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index ec652f852179a..86da87d060313 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -3,7 +3,7 @@ #![allow(rustc::potential_query_instability)] #![feature(box_patterns)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(min_specialization)] #![feature(never_type)] #![feature(rustc_attrs)] diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 280fa70451141..8aeb3b82a9cd0 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -9,7 +9,7 @@ #![feature(if_let_guard)] #![feature(is_sorted)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] #![recursion_limit = "256"] diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 3d789904707c0..a640de42a6a86 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1705,6 +1705,97 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, bitwise_red!(simd_reduce_all: vector_reduce_and, true); bitwise_red!(simd_reduce_any: vector_reduce_or, true); + if name == sym::simd_cast_ptr { + require_simd!(ret_ty, "return"); + let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); + require!( + in_len == out_len, + "expected return type with length {} (same as input type `{}`), \ + found `{}` with length {}", + in_len, + in_ty, + ret_ty, + out_len + ); + + match in_elem.kind() { + ty::RawPtr(p) => { + let (metadata, check_sized) = p.ty.ptr_metadata_ty(bx.tcx, |ty| { + bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty) + }); + assert!(!check_sized); // we are in codegen, so we shouldn't see these types + require!(metadata.is_unit(), "cannot cast fat pointer `{}`", in_elem) + } + _ => return_error!("expected pointer, got `{}`", in_elem), + } + match out_elem.kind() { + ty::RawPtr(p) => { + let (metadata, check_sized) = p.ty.ptr_metadata_ty(bx.tcx, |ty| { + bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty) + }); + assert!(!check_sized); // we are in codegen, so we shouldn't see these types + require!(metadata.is_unit(), "cannot cast to fat pointer `{}`", out_elem) + } + _ => return_error!("expected pointer, got `{}`", out_elem), + } + + if in_elem == out_elem { + return Ok(args[0].immediate()); + } else { + return Ok(bx.pointercast(args[0].immediate(), llret_ty)); + } + } + + if name == sym::simd_expose_addr { + require_simd!(ret_ty, "return"); + let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); + require!( + in_len == out_len, + "expected return type with length {} (same as input type `{}`), \ + found `{}` with length {}", + in_len, + in_ty, + ret_ty, + out_len + ); + + match in_elem.kind() { + ty::RawPtr(_) => {} + _ => return_error!("expected pointer, got `{}`", in_elem), + } + match out_elem.kind() { + ty::Uint(ty::UintTy::Usize) => {} + _ => return_error!("expected `usize`, got `{}`", out_elem), + } + + return Ok(bx.ptrtoint(args[0].immediate(), llret_ty)); + } + + if name == sym::simd_from_exposed_addr { + require_simd!(ret_ty, "return"); + let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); + require!( + in_len == out_len, + "expected return type with length {} (same as input type `{}`), \ + found `{}` with length {}", + in_len, + in_ty, + ret_ty, + out_len + ); + + match in_elem.kind() { + ty::Uint(ty::UintTy::Usize) => {} + _ => return_error!("expected `usize`, got `{}`", in_elem), + } + match out_elem.kind() { + ty::RawPtr(_) => {} + _ => return_error!("expected pointer, got `{}`", out_elem), + } + + return Ok(bx.inttoptr(args[0].immediate(), llret_ty)); + } + if name == sym::simd_cast || name == sym::simd_as { require_simd!(ret_ty, "return"); let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 334425ae55b43..42c65e04e3b6b 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -7,7 +7,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(hash_raw_entry)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(extern_types)] #![feature(once_cell)] #![feature(iter_intersperse)] diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 4ea75dba47120..e736b2aba9c14 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -1,7 +1,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(box_patterns)] #![feature(try_blocks)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(once_cell)] #![feature(associated_type_bounds)] #![feature(strict_provenance)] diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 72ac6af685dc4..9f47d302a0c3d 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -10,7 +10,7 @@ Rust MIR: a lowered representation of Rust. #![feature(decl_macro)] #![feature(exact_size_is_empty)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(map_try_insert)] #![feature(min_specialization)] #![feature(slice_ptr_get)] diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index a7429ed008fb8..56f7823efe0c2 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -13,7 +13,7 @@ #![feature(cell_leak)] #![feature(control_flow_enum)] #![feature(extend_one)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(hash_raw_entry)] #![feature(hasher_prefixfree_extras)] #![feature(maybe_uninit_uninit_array)] diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index d6f51d7eee1af..8fb9508194b68 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -5,7 +5,7 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(once_cell)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] diff --git a/compiler/rustc_error_messages/locales/en-US/privacy.ftl b/compiler/rustc_error_messages/locales/en-US/privacy.ftl index da987152ff660..a26d1b2b381e8 100644 --- a/compiler/rustc_error_messages/locales/en-US/privacy.ftl +++ b/compiler/rustc_error_messages/locales/en-US/privacy.ftl @@ -11,7 +11,7 @@ privacy_in_public_interface = {$vis_descr} {$kind} `{$descr}` in public interfac .label = can't leak {$vis_descr} {$kind} .visibility_label = `{$descr}` declared as {$vis_descr} -privacy_report_access_level = {$descr} +privacy_report_effective_visibility = {$descr} privacy_from_private_dep_in_public_interface = {$kind} `{$descr}` from private dependency '{$krate}' in public interface diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 1b24f07e689bb..c3e7820961256 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -7,7 +7,7 @@ #![feature(if_let_guard)] #![feature(adt_const_params)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(never_type)] #![feature(result_option_inspect)] #![feature(rustc_attrs)] diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index ac0e200b1b73e..ffc9abe64d2ea 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -3,7 +3,7 @@ #![feature(associated_type_defaults)] #![feature(if_let_guard)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(macro_metavar_expr)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_internals)] diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 100000f4cd629..5f7de94e72657 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -190,6 +190,8 @@ declare_features! ( (accepted, item_like_imports, "1.15.0", Some(35120), None), /// Allows `'a: { break 'a; }`. (accepted, label_break_value, "CURRENT_RUSTC_VERSION", Some(48594), None), + /// Allows `let...else` statements. + (accepted, let_else, "CURRENT_RUSTC_VERSION", Some(87335), None), /// Allows `break {expr}` with a value inside `loop`s. (accepted, loop_break_value, "1.19.0", Some(37339), None), /// Allows use of `?` as the Kleene "at most one" operator in macros. diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index c28fa654a6c52..ad28595ca82b3 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -430,8 +430,6 @@ declare_features! ( (active, large_assignments, "1.52.0", Some(83518), None), /// Allows `if/while p && let q = r && ...` chains. (active, let_chains, "1.37.0", Some(53667), None), - /// Allows `let...else` statements. - (active, let_else, "1.56.0", Some(87335), None), /// Allows `#[link(..., cfg(..))]`. (active, link_cfg, "1.14.0", Some(37406), None), /// Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index b50c972e6f6c0..0f6d7ed9edc16 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -762,7 +762,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Internal attributes, Testing: // ========================================================================== - rustc_attr!(TEST, rustc_access_level, Normal, template!(Word), WarnFollowing), + rustc_attr!(TEST, rustc_effective_visibility, Normal, template!(Word), WarnFollowing), rustc_attr!(TEST, rustc_outlives, Normal, template!(Word), WarnFollowing), rustc_attr!(TEST, rustc_capture_analysis, Normal, template!(Word), WarnFollowing), rustc_attr!(TEST, rustc_insignificant_dtor, Normal, template!(Word), WarnFollowing), diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 037cbc1be9adf..a8436ea64f8d7 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -139,11 +139,10 @@ impl LifetimeName { match self { LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Infer => true, - // It might seem surprising that `Fresh` counts as - // *not* elided -- but this is because, as far as the code - // in the compiler is concerned -- `Fresh` variants act - // equivalently to "some fresh name". They correspond to - // early-bound regions on an impl, in other words. + // It might seem surprising that `Fresh` counts as not *elided* + // -- but this is because, as far as the code in the compiler is + // concerned -- `Fresh` variants act equivalently to "some fresh name". + // They correspond to early-bound regions on an impl, in other words. LifetimeName::Error | LifetimeName::Param(..) | LifetimeName::Static => false, } } diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 1b33cb9c2da9c..946da9265ba09 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -5,7 +5,7 @@ #![feature(associated_type_defaults)] #![feature(closure_track_caller)] #![feature(const_btree_new)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(once_cell)] #![feature(min_specialization)] #![feature(never_type)] diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 1e88e8091c373..2c9e21f769fb1 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -2,7 +2,7 @@ #![deny(missing_docs)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index aa34673de81d7..a00d7bd680147 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -3,7 +3,7 @@ #![feature(allow_internal_unstable)] #![feature(bench_black_box)] #![feature(extend_one)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(min_specialization)] #![feature(new_uninit)] #![feature(step_trait)] diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 931ebca7d0145..ef60d2c918845 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -19,7 +19,7 @@ #![feature(extend_one)] #![cfg_attr(bootstrap, feature(label_break_value))] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(min_specialization)] #![feature(never_type)] #![feature(try_blocks)] diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 1a8d619fafb62..41cd7b0e9b1d6 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -1,5 +1,5 @@ #![feature(box_patterns)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(internal_output_capture)] #![feature(thread_spawn_unchecked)] #![feature(once_cell)] diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 2a22a6e5be1ba..c760e435699c6 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -34,7 +34,7 @@ #![feature(iter_intersperse)] #![feature(iter_order_by)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(min_specialization)] #![feature(never_type)] #![recursion_limit = "256"] diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 20ee5dfc72798..2c027d754da4d 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -1,5 +1,5 @@ #![feature(allow_internal_unstable)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(never_type)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_span)] diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index ba6f1e4a3a5ca..6f5604b7e11f0 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -5,7 +5,7 @@ #![cfg_attr(bootstrap, feature(generic_associated_types))] #![feature(iter_from_generator)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(once_cell)] #![feature(proc_macro_internals)] #![feature(macro_metavar_expr)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index ea08879cb53cc..01b9277b98362 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -40,7 +40,7 @@ #![feature(new_uninit)] #![feature(once_cell)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(min_specialization)] #![feature(trusted_len)] #![feature(type_alias_impl_trait)] diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index 751c7f4648225..c595fbec0dd5c 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -1,7 +1,7 @@ //! A pass that checks to make sure private fields and methods aren't used //! outside their scopes. This pass will also generate a set of exported items //! which are available for use externally when compiled as a library. - +use crate::ty::Visibility; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::HashStable; @@ -27,26 +27,107 @@ pub enum AccessLevel { Public, } +#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable, Default)] +pub struct EffectiveVisibility { + public: Option, + exported: Option, + reachable: Option, + reachable_from_impl_trait: Option, +} + +impl EffectiveVisibility { + pub fn get(&self, tag: AccessLevel) -> Option<&Visibility> { + match tag { + AccessLevel::Public => &self.public, + AccessLevel::Exported => &self.exported, + AccessLevel::Reachable => &self.reachable, + AccessLevel::ReachableFromImplTrait => &self.reachable_from_impl_trait, + } + .as_ref() + } + + fn get_mut(&mut self, tag: AccessLevel) -> &mut Option { + match tag { + AccessLevel::Public => &mut self.public, + AccessLevel::Exported => &mut self.exported, + AccessLevel::Reachable => &mut self.reachable, + AccessLevel::ReachableFromImplTrait => &mut self.reachable_from_impl_trait, + } + } + + pub fn is_public_at_level(&self, tag: AccessLevel) -> bool { + self.get(tag).map_or(false, |vis| vis.is_public()) + } +} + /// Holds a map of accessibility levels for reachable HIR nodes. #[derive(Debug, Clone)] pub struct AccessLevels { - pub map: FxHashMap, + map: FxHashMap, } -impl AccessLevels { +impl AccessLevels { + pub fn is_public_at_level(&self, id: Id, tag: AccessLevel) -> bool { + self.get_effective_vis(id) + .map_or(false, |effective_vis| effective_vis.is_public_at_level(tag)) + } + /// See `AccessLevel::Reachable`. pub fn is_reachable(&self, id: Id) -> bool { - self.map.get(&id) >= Some(&AccessLevel::Reachable) + self.is_public_at_level(id, AccessLevel::Reachable) } /// See `AccessLevel::Exported`. pub fn is_exported(&self, id: Id) -> bool { - self.map.get(&id) >= Some(&AccessLevel::Exported) + self.is_public_at_level(id, AccessLevel::Exported) } /// See `AccessLevel::Public`. pub fn is_public(&self, id: Id) -> bool { - self.map.get(&id) >= Some(&AccessLevel::Public) + self.is_public_at_level(id, AccessLevel::Public) + } + + pub fn get_access_level(&self, id: Id) -> Option { + self.get_effective_vis(id).and_then(|effective_vis| { + for level in [ + AccessLevel::Public, + AccessLevel::Exported, + AccessLevel::Reachable, + AccessLevel::ReachableFromImplTrait, + ] { + if effective_vis.is_public_at_level(level) { + return Some(level); + } + } + None + }) + } + + pub fn set_access_level(&mut self, id: Id, tag: AccessLevel) { + let mut effective_vis = self.get_effective_vis(id).copied().unwrap_or_default(); + for level in [ + AccessLevel::Public, + AccessLevel::Exported, + AccessLevel::Reachable, + AccessLevel::ReachableFromImplTrait, + ] { + if level <= tag { + *effective_vis.get_mut(level) = Some(Visibility::Public); + } + } + self.map.insert(id, effective_vis); + } + + pub fn get_effective_vis(&self, id: Id) -> Option<&EffectiveVisibility> { + self.map.get(&id) + } + + pub fn iter(&self) -> impl Iterator { + self.map.iter() + } + + pub fn map_id(&self, f: impl Fn(Id) -> OutId) -> AccessLevels { + AccessLevels { map: self.map.iter().map(|(k, v)| (f(*k), *v)).collect() } } } diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 11cd2a9aa4dea..0c0a2fe9c9ed6 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -6,7 +6,7 @@ #![feature(control_flow_enum)] #![feature(if_let_guard)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(min_specialization)] #![feature(once_cell)] #![recursion_limit = "256"] diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 69a8c98b27a3d..d45b886903bbf 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -491,8 +491,8 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { err.span_suggestion_verbose( semi_span.shrink_to_lo(), &format!( - "alternatively, on nightly, you might want to use \ - `#![feature(let_else)]` to handle the variant{} that {} matched", + "alternatively, you might want to use \ + let else to handle the variant{} that {} matched", pluralize!(witnesses.len()), match witnesses.len() { 1 => "isn't", diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index 62b712f7b8dbd..b45c32ee986b6 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -1,7 +1,7 @@ #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(exact_size_is_empty)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(min_specialization)] #![feature(once_cell)] #![feature(stmt_expr_attributes)] diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 162f7d969b181..e6fc85595714b 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -1,7 +1,7 @@ #![allow(rustc::potential_query_instability)] #![feature(box_patterns)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(map_try_insert)] #![feature(min_specialization)] #![feature(never_type)] diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 3afff7bcabf7d..ba6ce9fd40f63 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -1,6 +1,6 @@ #![feature(array_windows)] #![feature(control_flow_enum)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] #![deny(rustc::untranslatable_diagnostic)] diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 3c88e1ef377e2..a37327f42942a 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -4,7 +4,7 @@ #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(never_type)] #![feature(rustc_attrs)] #![recursion_limit = "256"] diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ebe4d2e9dd0bd..b3f15ba7cbf25 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1666,7 +1666,8 @@ impl CheckAttrVisitor<'_> { E0552, "unrecognized representation hint" ) - .help("valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`") + .help("valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, \ + `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`") .emit(); continue; diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index f141d7beeb921..57f7c379d0490 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -11,7 +11,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Node, PatKind, TyKind}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use rustc_middle::middle::privacy; +use rustc_middle::middle::privacy::AccessLevel; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, DefIdTree, TyCtxt}; use rustc_session::lint; @@ -619,13 +619,10 @@ fn create_and_seed_worklist<'tcx>( // see `MarkSymbolVisitor::struct_constructors` let mut struct_constructors = Default::default(); let mut worklist = access_levels - .map .iter() - .filter_map( - |(&id, &level)| { - if level >= privacy::AccessLevel::Reachable { Some(id) } else { None } - }, - ) + .filter_map(|(&id, effective_vis)| { + effective_vis.is_public_at_level(AccessLevel::Reachable).then_some(id) + }) // Seed entry point .chain(tcx.entry_fn(()).and_then(|(def_id, _)| def_id.as_local())) .collect::>(); diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 7b2f83958af85..39ebb8db21cbc 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -8,7 +8,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(iter_intersperse)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(map_try_insert)] #![feature(min_specialization)] #![feature(try_blocks)] diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index f7e3fac6b2e20..75244124e20ef 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -12,7 +12,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::Node; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; -use rustc_middle::middle::privacy; +use rustc_middle::middle::privacy::{self, AccessLevel}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, DefIdTree, TyCtxt}; use rustc_session::config::CrateType; @@ -373,7 +373,13 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashSet { // If other crates link to us, they're going to expect to be able to // use the lang items, so we need to be sure to mark them as // exported. - reachable_context.worklist.extend(access_levels.map.keys()); + reachable_context.worklist = access_levels + .iter() + .filter_map(|(&id, effective_vis)| { + effective_vis.is_public_at_level(AccessLevel::ReachableFromImplTrait).then_some(id) + }) + .collect::>(); + for item in tcx.lang_items().items().iter() { if let Some(def_id) = *item { if let Some(def_id) = def_id.as_local() { diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index 63f83f8965ec5..705ad567aa779 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -76,8 +76,8 @@ pub struct InPublicInterface<'a> { } #[derive(SessionDiagnostic)] -#[diag(privacy::report_access_level)] -pub struct ReportAccessLevel { +#[diag(privacy::report_effective_visibility)] +pub struct ReportEffectiveVisibility { #[primary_span] pub span: Span, pub descr: String, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 92ef61fe64c37..8f5ee51e6cfbb 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1,7 +1,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(associated_type_defaults)] #![feature(control_flow_enum)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(rustc_private)] #![feature(try_blocks)] #![recursion_limit = "256"] @@ -42,7 +42,7 @@ use std::{cmp, fmt, mem}; use errors::{ FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface, - InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, ReportAccessLevel, + InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, ReportEffectiveVisibility, UnnamedItemIsPrivate, }; @@ -376,7 +376,7 @@ impl VisibilityLike for Option { // (which require reaching the `DefId`s in them). const SHALLOW: bool = true; fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self { - cmp::min(find.access_levels.map.get(&def_id).copied(), find.min) + cmp::min(find.access_levels.get_access_level(def_id), find.min) } } @@ -416,7 +416,7 @@ struct ReachEverythingInTheInterfaceVisitor<'a, 'tcx> { impl<'tcx> EmbargoVisitor<'tcx> { fn get(&self, def_id: LocalDefId) -> Option { - self.access_levels.map.get(&def_id).copied() + self.access_levels.get_access_level(def_id) } fn update_with_hir_id( @@ -433,7 +433,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { let old_level = self.get(def_id); // Accessibility levels can only grow. if level > old_level { - self.access_levels.map.insert(def_id, level.unwrap()); + self.access_levels.set_access_level(def_id, level.unwrap()); self.changed = true; level } else { @@ -914,10 +914,31 @@ pub struct TestReachabilityVisitor<'tcx, 'a> { impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> { fn access_level_diagnostic(&mut self, def_id: LocalDefId) { - if self.tcx.has_attr(def_id.to_def_id(), sym::rustc_access_level) { - let access_level = format!("{:?}", self.access_levels.map.get(&def_id)); - let span = self.tcx.def_span(def_id.to_def_id()); - self.tcx.sess.emit_err(ReportAccessLevel { span, descr: access_level }); + let span = self.tcx.def_span(def_id.to_def_id()); + if self.tcx.has_attr(def_id.to_def_id(), sym::rustc_effective_visibility) { + let mut error_msg = String::new(); + + let effective_vis = + self.access_levels.get_effective_vis(def_id).copied().unwrap_or_default(); + for level in [ + AccessLevel::Public, + AccessLevel::Exported, + AccessLevel::Reachable, + AccessLevel::ReachableFromImplTrait, + ] { + let vis_str = match effective_vis.get(level) { + Some(ty::Visibility::Restricted(restricted_id)) => { + format!("pub({})", self.tcx.item_name(restricted_id.to_def_id())) + } + Some(ty::Visibility::Public) => "pub".to_string(), + None => "pub(self)".to_string(), + }; + if level != AccessLevel::Public { + error_msg.push_str(", "); + } + error_msg.push_str(&format!("{:?}: {}", level, vis_str)); + } + self.tcx.sess.emit_err(ReportEffectiveVisibility { span, descr: error_msg }); } } } diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index 8a88b5c334078..f92c3831f2689 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -1,7 +1,7 @@ #![feature(assert_matches)] #![feature(core_intrinsics)] #![feature(hash_raw_entry)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(min_specialization)] #![feature(extern_types)] #![allow(rustc::potential_query_instability)] diff --git a/compiler/rustc_resolve/src/access_levels.rs b/compiler/rustc_resolve/src/access_levels.rs index 0a3add2e0f532..9b1111c02c73f 100644 --- a/compiler/rustc_resolve/src/access_levels.rs +++ b/compiler/rustc_resolve/src/access_levels.rs @@ -46,7 +46,7 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { /// This will also follow `use` chains (see PrivacyVisitor::set_import_binding_access_level). fn set_bindings_access_level(&mut self, module_id: LocalDefId) { assert!(self.r.module_map.contains_key(&&module_id.to_def_id())); - let module_level = self.r.access_levels.map.get(&module_id).copied(); + let module_level = self.r.access_levels.get_access_level(module_id); if !module_level.is_some() { return; } @@ -103,9 +103,9 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> { def_id: LocalDefId, access_level: Option, ) -> Option { - let old_level = self.r.access_levels.map.get(&def_id).copied(); + let old_level = self.r.access_levels.get_access_level(def_id); if old_level < access_level { - self.r.access_levels.map.insert(def_id, access_level.unwrap()); + self.r.access_levels.set_access_level(def_id, access_level.unwrap()); self.changed = true; access_level } else { @@ -131,7 +131,7 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> { // Foreign modules inherit level from parents. ast::ItemKind::ForeignMod(..) => { let parent_level = - self.r.access_levels.map.get(&self.r.local_parent(def_id)).copied(); + self.r.access_levels.get_access_level(self.r.local_parent(def_id)); self.set_access_level(item.id, parent_level); } @@ -151,7 +151,7 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> { self.set_bindings_access_level(def_id); for variant in variants { let variant_def_id = self.r.local_def_id(variant.id); - let variant_level = self.r.access_levels.map.get(&variant_def_id).copied(); + let variant_level = self.r.access_levels.get_access_level(variant_def_id); for field in variant.data.fields() { self.set_access_level(field.id, variant_level); } @@ -159,7 +159,7 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> { } ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => { - let inherited_level = self.r.access_levels.map.get(&def_id).copied(); + let inherited_level = self.r.access_levels.get_access_level(def_id); for field in def.fields() { if field.vis.kind.is_pub() { self.set_access_level(field.id, inherited_level); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 749a78a7552ed..54a7f416ce64c 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -12,7 +12,7 @@ #![feature(if_let_guard)] #![feature(iter_intersperse)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(never_type)] #![recursion_limit = "256"] #![allow(rustdoc::private_intra_doc_links)] diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index ebe44a56449d3..ce03c2a8ad05f 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -1,6 +1,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(if_let_guard)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] #![feature(never_type)] diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 91f4cfaf5acaa..fa9c7bd54c395 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -14,7 +14,7 @@ Core encoding and decoding interfaces. #![feature(min_specialization)] #![feature(core_intrinsics)] #![feature(maybe_uninit_slice)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(new_uninit)] #![feature(allocator_api)] #![cfg_attr(test, feature(test))] diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index b9b243f6f0840..f6bab775e76b3 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -1,6 +1,6 @@ #![feature(if_let_guard)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(min_specialization)] #![feature(never_type)] #![feature(once_cell)] diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 26b4ebeab1b39..ada3bae61502f 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -15,7 +15,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(array_windows)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(if_let_guard)] #![feature(negative_impls)] #![feature(min_specialization)] diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index fcc22e22cc18c..562360130e92f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1214,7 +1214,6 @@ symbols! { rust_eh_unregister_frames, rust_oom, rustc, - rustc_access_level, rustc_allocator, rustc_allocator_nounwind, rustc_allocator_zeroed, @@ -1242,6 +1241,7 @@ symbols! { rustc_dump_program_clauses, rustc_dump_user_substs, rustc_dump_vtable, + rustc_effective_visibility, rustc_error, rustc_evaluate_where_clauses, rustc_expected_cgu_reuse, @@ -1322,9 +1322,11 @@ symbols! { simd_as, simd_bitmask, simd_cast, + simd_cast_ptr, simd_ceil, simd_div, simd_eq, + simd_expose_addr, simd_extract, simd_fabs, simd_fcos, @@ -1340,6 +1342,7 @@ symbols! { simd_fmin, simd_fpow, simd_fpowi, + simd_from_exposed_addr, simd_fsin, simd_fsqrt, simd_gather, diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index 9c9e297849ed5..a7deab9d2efc8 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -11,7 +11,7 @@ #![feature(assert_matches)] #![feature(associated_type_bounds)] #![feature(exhaustive_patterns)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(min_specialization)] #![feature(never_type)] #![feature(rustc_attrs)] diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index f039b1fca1817..d35f74974fdd9 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -18,7 +18,7 @@ #![feature(hash_drain_filter)] #![cfg_attr(bootstrap, feature(label_break_value))] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(if_let_guard)] #![feature(never_type)] #![feature(type_alias_impl_trait)] diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index 318e76c79f18b..2d39e973ed9bb 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -3,7 +3,7 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![recursion_limit = "256"] #[macro_use] diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 6931b15b1ba57..8524e57cb58a3 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -6,7 +6,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(control_flow_enum)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(never_type)] #![feature(box_patterns)] #![recursion_limit = "256"] diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index 4fa33da50c9e0..c7425ff7865f7 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -477,7 +477,11 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) sym::simd_scatter => (3, vec![param(0), param(1), param(2)], tcx.mk_unit()), sym::simd_insert => (2, vec![param(0), tcx.types.u32, param(1)], param(0)), sym::simd_extract => (2, vec![param(0), tcx.types.u32], param(1)), - sym::simd_cast | sym::simd_as => (2, vec![param(0)], param(1)), + sym::simd_cast + | sym::simd_as + | sym::simd_cast_ptr + | sym::simd_expose_addr + | sym::simd_from_exposed_addr => (2, vec![param(0)], param(1)), sym::simd_bitmask => (2, vec![param(0)], param(1)), sym::simd_select | sym::simd_select_bitmask => { (2, vec![param(0), param(1), param(1)], param(1)) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index fe74ed28aa5cc..60bd91c867e7a 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1604,6 +1604,13 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { _ => None, }; + enum Defaults { + Allowed, + // See #36887 + FutureCompatDisallowed, + Deny, + } + let no_generics = hir::Generics::empty(); let ast_generics = node.generics().unwrap_or(&no_generics); let (opt_self, allow_defaults) = match node { @@ -1625,17 +1632,26 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { }, }); - (opt_self, true) + (opt_self, Defaults::Allowed) } ItemKind::TyAlias(..) | ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::OpaqueTy(..) - | ItemKind::Union(..) => (None, true), - _ => (None, false), + | ItemKind::Union(..) => (None, Defaults::Allowed), + _ => (None, Defaults::FutureCompatDisallowed), } } - _ => (None, false), + + // GATs + Node::TraitItem(item) if matches!(item.kind, TraitItemKind::Type(..)) => { + (None, Defaults::Deny) + } + Node::ImplItem(item) if matches!(item.kind, ImplItemKind::TyAlias(..)) => { + (None, Defaults::Deny) + } + + _ => (None, Defaults::FutureCompatDisallowed), }; let has_self = opt_self.is_some(); @@ -1668,23 +1684,30 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { let type_start = own_start - has_self as u32 + params.len() as u32; let mut i = 0; + const TYPE_DEFAULT_NOT_ALLOWED: &'static str = "defaults for type parameters are only allowed in \ + `struct`, `enum`, `type`, or `trait` definitions"; + params.extend(ast_generics.params.iter().filter_map(|param| match param.kind { GenericParamKind::Lifetime { .. } => None, GenericParamKind::Type { ref default, synthetic, .. } => { - if !allow_defaults && default.is_some() { - if !tcx.features().default_type_parameter_fallback { - tcx.struct_span_lint_hir( - lint::builtin::INVALID_TYPE_PARAM_DEFAULT, - param.hir_id, - param.span, - |lint| { - lint.build( - "defaults for type parameters are only allowed in \ - `struct`, `enum`, `type`, or `trait` definitions", - ) - .emit(); - }, - ); + if default.is_some() { + match allow_defaults { + Defaults::Allowed => {} + Defaults::FutureCompatDisallowed + if tcx.features().default_type_parameter_fallback => {} + Defaults::FutureCompatDisallowed => { + tcx.struct_span_lint_hir( + lint::builtin::INVALID_TYPE_PARAM_DEFAULT, + param.hir_id, + param.span, + |lint| { + lint.build(TYPE_DEFAULT_NOT_ALLOWED).emit(); + }, + ); + } + Defaults::Deny => { + tcx.sess.span_err(param.span, TYPE_DEFAULT_NOT_ALLOWED); + } } } @@ -1701,7 +1724,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { Some(param_def) } GenericParamKind::Const { default, .. } => { - if !allow_defaults && default.is_some() { + if !matches!(allow_defaults, Defaults::Allowed) && default.is_some() { tcx.sess.span_err( param.span, "defaults for const parameters are only allowed in \ diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index ac66819d2836f..b1ce972e1d682 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -66,7 +66,7 @@ This API is completely unstable and subject to change. #![feature(iter_intersperse)] #![cfg_attr(bootstrap, feature(label_break_value))] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(min_specialization)] #![feature(never_type)] #![feature(once_cell)] diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index e5cf9033c8603..8619467c2d928 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -169,7 +169,7 @@ #![cfg_attr(not(test), feature(generator_trait))] #![feature(hashmap_internals)] #![feature(lang_items)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(min_specialization)] #![feature(negative_impls)] #![feature(never_type)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index f13500de01431..bc4f1b27c2aaa 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -255,7 +255,7 @@ #![cfg_attr(bootstrap, feature(label_break_value))] #![feature(lang_items)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(linkage)] #![feature(link_cfg)] #![feature(min_specialization)] diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 14e8ebd6876b4..3d5933f1f1400 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -708,6 +708,7 @@ impl<'a> Builder<'a> { Kind::Dist => describe!( dist::Docs, dist::RustcDocs, + dist::JsonDocs, dist::Mingw, dist::Rustc, dist::Std, diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index 280eba75f0c19..88bbcc93d072c 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -236,7 +236,7 @@ mod defaults { fn doc_default() { let mut config = configure("doc", &["A"], &["A"]); config.compiler_docs = true; - config.cmd = Subcommand::Doc { paths: Vec::new(), open: false }; + config.cmd = Subcommand::Doc { paths: Vec::new(), open: false, json: false }; let mut cache = run_build(&[], config); let a = TargetSelection::from_user("A"); @@ -587,7 +587,7 @@ mod dist { fn doc_ci() { let mut config = configure(&["A"], &["A"]); config.compiler_docs = true; - config.cmd = Subcommand::Doc { paths: Vec::new(), open: false }; + config.cmd = Subcommand::Doc { paths: Vec::new(), open: false, json: false }; let build = Build::new(config); let mut builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]); diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 1a59b3958f106..c9ee3c1c7d65d 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -87,6 +87,45 @@ impl Step for Docs { } } +#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] +pub struct JsonDocs { + pub host: TargetSelection, +} + +impl Step for JsonDocs { + type Output = Option; + const DEFAULT: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + let default = run.builder.config.docs; + run.alias("rust-json-docs").default_condition(default) + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(JsonDocs { host: run.target }); + } + + /// Builds the `rust-json-docs` installer component. + fn run(self, builder: &Builder<'_>) -> Option { + // This prevents JSON docs from being built for "dist" or "install" + // on the stable/beta channels. The JSON format is not stable yet and + // should not be included in stable/beta toolchains. + if !builder.build.unstable_features() { + return None; + } + + let host = self.host; + builder.ensure(crate::doc::JsonStd { stage: builder.top_stage, target: host }); + + let dest = "share/doc/rust/json"; + + let mut tarball = Tarball::new(builder, "rust-json-docs", &host.triple); + tarball.set_product_name("Rust Documentation In JSON Format"); + tarball.add_bulk_dir(&builder.json_doc_out(host), dest); + Some(tarball.generate()) + } +} + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct RustcDocs { pub host: TargetSelection, diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index f909ecc0ab858..8de41c806807b 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -7,6 +7,7 @@ //! Everything here is basically just a shim around calling either `rustbook` or //! `rustdoc`. +use std::ffi::OsStr; use std::fs; use std::io; use std::path::{Path, PathBuf}; @@ -432,48 +433,24 @@ impl Step for Std { let stage = self.stage; let target = self.target; builder.info(&format!("Documenting stage{} std ({})", stage, target)); - if builder.no_std(target) == Some(true) { - panic!( - "building std documentation for no_std target {target} is not supported\n\ - Set `docs = false` in the config to disable documentation." - ); - } let out = builder.doc_out(target); t!(fs::create_dir_all(&out)); - let compiler = builder.compiler(stage, builder.config.build); - - let out_dir = builder.stage_out(compiler, Mode::Std).join(target.triple).join("doc"); - t!(fs::copy(builder.src.join("src/doc/rust.css"), out.join("rust.css"))); - let run_cargo_rustdoc_for = |package: &str| { - let mut cargo = - builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "rustdoc"); - compile::std_cargo(builder, target, compiler.stage, &mut cargo); - - cargo - .arg("-p") - .arg(package) - .arg("-Zskip-rustdoc-fingerprint") - .arg("--") - .arg("--markdown-css") - .arg("rust.css") - .arg("--markdown-no-toc") - .arg("-Z") - .arg("unstable-options") - .arg("--resource-suffix") - .arg(&builder.version) - .arg("--index-page") - .arg(&builder.src.join("src/doc/index.md")); - - if !builder.config.docs_minification { - cargo.arg("--disable-minification"); - } - - builder.run(&mut cargo.into()); - }; + let index_page = builder.src.join("src/doc/index.md").into_os_string(); + let mut extra_args = vec![ + OsStr::new("--markdown-css"), + OsStr::new("rust.css"), + OsStr::new("--markdown-no-toc"), + OsStr::new("--index-page"), + &index_page, + ]; + + if !builder.config.docs_minification { + extra_args.push(OsStr::new("--disable-minification")); + } - let paths = builder + let requested_crates = builder .paths .iter() .map(components_simplified) @@ -491,30 +468,20 @@ impl Step for Std { }) .collect::>(); - // Only build the following crates. While we could just iterate over the - // folder structure, that would also build internal crates that we do - // not want to show in documentation. These crates will later be visited - // by the rustc step, so internal documentation will show them. - // - // Note that the order here is important! The crates need to be - // processed starting from the leaves, otherwise rustdoc will not - // create correct links between crates because rustdoc depends on the - // existence of the output directories to know if it should be a local - // or remote link. - let krates = ["core", "alloc", "std", "proc_macro", "test"]; - for krate in &krates { - run_cargo_rustdoc_for(krate); - if paths.iter().any(|p| p == krate) { - // No need to document more of the libraries if we have the one we want. - break; - } - } - builder.cp_r(&out_dir, &out); + doc_std( + builder, + DocumentationFormat::HTML, + stage, + target, + &out, + &extra_args, + &requested_crates, + ); // Look for library/std, library/core etc in the `x.py doc` arguments and // open the corresponding rendered docs. - for requested_crate in paths { - if krates.iter().any(|k| *k == requested_crate.as_str()) { + for requested_crate in requested_crates { + if STD_PUBLIC_CRATES.iter().any(|k| *k == requested_crate.as_str()) { let index = out.join(requested_crate).join("index.html"); open(builder, &index); } @@ -522,6 +489,132 @@ impl Step for Std { } } +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct JsonStd { + pub stage: u32, + pub target: TargetSelection, +} + +impl Step for JsonStd { + type Output = (); + const DEFAULT: bool = false; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + let default = run.builder.config.docs && run.builder.config.cmd.json(); + run.all_krates("test").path("library").default_condition(default) + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(Std { stage: run.builder.top_stage, target: run.target }); + } + + /// Build JSON documentation for the standard library crates. + /// + /// This is largely just a wrapper around `cargo doc`. + fn run(self, builder: &Builder<'_>) { + let stage = self.stage; + let target = self.target; + let out = builder.json_doc_out(target); + t!(fs::create_dir_all(&out)); + let extra_args = [OsStr::new("--output-format"), OsStr::new("json")]; + doc_std(builder, DocumentationFormat::JSON, stage, target, &out, &extra_args, &[]) + } +} + +/// Name of the crates that are visible to consumers of the standard library. +/// Documentation for internal crates is handled by the rustc step, so internal crates will show +/// up there. +/// +/// Order here is important! +/// Crates need to be processed starting from the leaves, otherwise rustdoc will not +/// create correct links between crates because rustdoc depends on the +/// existence of the output directories to know if it should be a local +/// or remote link. +const STD_PUBLIC_CRATES: [&str; 5] = ["core", "alloc", "std", "proc_macro", "test"]; + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +enum DocumentationFormat { + HTML, + JSON, +} + +impl DocumentationFormat { + fn as_str(&self) -> &str { + match self { + DocumentationFormat::HTML => "HTML", + DocumentationFormat::JSON => "JSON", + } + } +} + +/// Build the documentation for public standard library crates. +/// +/// `requested_crates` can be used to build only a subset of the crates. If empty, all crates will +/// be built. +fn doc_std( + builder: &Builder<'_>, + format: DocumentationFormat, + stage: u32, + target: TargetSelection, + out: &Path, + extra_args: &[&OsStr], + requested_crates: &[String], +) { + builder.info(&format!( + "Documenting stage{} std ({}) in {} format", + stage, + target, + format.as_str() + )); + if builder.no_std(target) == Some(true) { + panic!( + "building std documentation for no_std target {target} is not supported\n\ + Set `docs = false` in the config to disable documentation." + ); + } + let compiler = builder.compiler(stage, builder.config.build); + // This is directory where the compiler will place the output of the command. + // We will then copy the files from this directory into the final `out` directory, the specified + // as a function parameter. + let out_dir = builder.stage_out(compiler, Mode::Std).join(target.triple).join("doc"); + // `cargo` uses the same directory for both JSON docs and HTML docs. + // This could lead to cross-contamination when copying files into the specified `out` directory. + // For example: + // ```bash + // x doc std + // x doc std --json + // ``` + // could lead to HTML docs being copied into the JSON docs output directory. + // To avoid this issue, we clean the doc folder before invoking `cargo`. + builder.remove_dir(&out_dir); + + let run_cargo_rustdoc_for = |package: &str| { + let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "rustdoc"); + compile::std_cargo(builder, target, compiler.stage, &mut cargo); + cargo + .arg("-p") + .arg(package) + .arg("-Zskip-rustdoc-fingerprint") + .arg("--") + .arg("-Z") + .arg("unstable-options") + .arg("--resource-suffix") + .arg(&builder.version) + .args(extra_args); + builder.run(&mut cargo.into()); + }; + + for krate in STD_PUBLIC_CRATES { + run_cargo_rustdoc_for(krate); + if requested_crates.iter().any(|p| p == krate) { + // No need to document more of the libraries if we have the one we want. + break; + } + } + + builder.cp_r(&out_dir, &out); +} + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Rustc { pub stage: u32, diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 789da74810035..802b49d748ac6 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -107,6 +107,7 @@ pub enum Subcommand { Doc { paths: Vec, open: bool, + json: bool, }, Test { paths: Vec, @@ -325,6 +326,11 @@ To learn more about a subcommand, run `./x.py -h`", } Kind::Doc => { opts.optflag("", "open", "open the docs in a browser"); + opts.optflag( + "", + "json", + "render the documentation in JSON format in addition to the usual HTML format", + ); } Kind::Clean => { opts.optflag("", "all", "clean all build artifacts"); @@ -493,6 +499,7 @@ Arguments: ./x.py doc src/doc/book ./x.py doc src/doc/nomicon ./x.py doc src/doc/book library/std + ./x.py doc library/std --json ./x.py doc library/std --open If no arguments are passed then everything is documented: @@ -581,7 +588,11 @@ Arguments: }, }, Kind::Bench => Subcommand::Bench { paths, test_args: matches.opt_strs("test-args") }, - Kind::Doc => Subcommand::Doc { paths, open: matches.opt_present("open") }, + Kind::Doc => Subcommand::Doc { + paths, + open: matches.opt_present("open"), + json: matches.opt_present("json"), + }, Kind::Clean => { if !paths.is_empty() { println!("\nclean does not take a path argument\n"); @@ -787,6 +798,13 @@ impl Subcommand { _ => false, } } + + pub fn json(&self) -> bool { + match *self { + Subcommand::Doc { json, .. } => json, + _ => false, + } + } } fn split(s: &[String]) -> Vec { diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index cc0cf12bd187a..868ec10bc15d8 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -825,6 +825,11 @@ impl Build { self.out.join(&*target.triple).join("doc") } + /// Output directory for all JSON-formatted documentation for a target + fn json_doc_out(&self, target: TargetSelection) -> PathBuf { + self.out.join(&*target.triple).join("json-doc") + } + fn test_out(&self, target: TargetSelection) -> PathBuf { self.out.join(&*target.triple).join("test") } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index c48b25aea4a37..76562d26a5502 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -10,7 +10,6 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{HirId, Path, TraitCandidate}; use rustc_interface::interface; use rustc_middle::hir::nested_filter; -use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_resolve as resolve; use rustc_session::config::{self, CrateType, ErrorOutputType}; @@ -364,9 +363,7 @@ pub(crate) fn run_global_ctxt( .copied() .filter(|&trait_def_id| tcx.trait_is_auto(trait_def_id)) .collect(); - let access_levels = AccessLevels { - map: tcx.privacy_access_levels(()).map.iter().map(|(k, v)| (k.to_def_id(), *v)).collect(), - }; + let access_levels = tcx.privacy_access_levels(()).map_id(Into::into); let mut ctxt = DocContext { tcx, diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 74de113495c2e..c292a8a7ef70b 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -118,8 +118,7 @@ pre, .rustdoc.source .example-wrap { .content span.primitive, .content a.primitive { color: #ffa0a5; } .content span.traitalias, .content a.traitalias { color: #39AFD7; } .content span.keyword, .content a.keyword { color: #39AFD7; } - -.content span.externcrate, .content span.mod, .content a.mod { +.content span.mod, .content a.mod { color: #39AFD7; } .content span.struct, .content a.struct { @@ -131,20 +130,10 @@ pre, .rustdoc.source .example-wrap { .content span.trait, .content a.trait { color: #39AFD7; } -.content span.type, .content a.type { - color: #39AFD7; -} -.content span.type, -.content a.type, -.block a.current.type { color: #39AFD7; } -.content span.associatedtype, -.content a.associatedtype, -.block a.current.associatedtype { color: #39AFD7; } -.content span.fn, .content a.fn, .content span.method, -.content a.method, .content span.tymethod, -.content a.tymethod, .content .fnname { - color: #fdd687; -} +.content span.type, .content a.type { color: #39AFD7; } +.content span.associatedtype, .content a.associatedtype { color: #39AFD7; } +.content span.fn, .content a.fn, +.content .fnname { color: #fdd687; } .content span.attr, .content a.attr, .content span.derive, .content a.derive, .content span.macro, .content a.macro { color: #a37acc; @@ -152,7 +141,6 @@ pre, .rustdoc.source .example-wrap { .sidebar a { color: #53b1db; } .sidebar a.current.type { color: #53b1db; } -.sidebar a.current.associatedtype { color: #53b1db; } pre.rust .comment { color: #788797; } pre.rust .doccomment { color: #a1ac88; } @@ -290,34 +278,11 @@ individually rather than as a group) */ /* FIXME: these rules should be at the bottom of the file but currently must be above the `@media (max-width: 700px)` rules due to a bug in the css checker */ /* see https://github.com/rust-lang/rust/pull/71237#issuecomment-618170143 */ -.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive, -.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro {} -.content span.struct,.content a.struct,.block a.current.struct {} -#titles>button:hover,#titles>button.selected {} -.content span.typedef,.content a.typedef,.block a.current.typedef {} -.content span.union,.content a.union,.block a.current.union {} pre.rust .lifetime {} -.stab.unstable {} -h2, -h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) {} -.content span.enum,.content a.enum,.block a.current.enum {} -.content span.constant,.content a.constant,.block a.current.constant,.content span.static, -.content a.static, .block a.current.static {} -.content span.keyword,.content a.keyword,.block a.current.keyword {} -.content span.traitalias,.content a.traitalias,.block a.current.traitalias {} -.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method, -.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod, -.content .fnname {} pre.rust .kw {} -pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute {} -.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype {} -.stab.deprecated {} -.content a.attr,.content a.derive,.content a.macro {} -.stab.portability {} -.content span.primitive,.content a.primitive,.block a.current.primitive {} -.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod {} -pre.rust .kw-2,pre.rust .prelude-ty {} -.content span.trait,.content a.trait,.block a.current.trait {} +#titles > button:hover, #titles > button.selected {} +pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val, pre.rust .attribute {} +pre.rust .kw-2, pre.rust .prelude-ty {} .search-results a:focus span {} a.result-trait:focus {} @@ -353,13 +318,9 @@ a.result-keyword:focus {} .sidebar a.current.constant .sidebar a.current.static {} .sidebar a.current.primitive {} -.sidebar a.current.externcrate -.sidebar a.current.mod {} .sidebar a.current.trait {} .sidebar a.current.traitalias {} -.sidebar a.current.fn, -.sidebar a.current.method, -.sidebar a.current.tymethod {} +.sidebar a.current.fn {} .sidebar a.current.keyword {} kbd { diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index 153b40f05d8de..68542d3305ca0 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -83,35 +83,29 @@ a.result-keyword:focus { background-color: #884719; } .content .item-info::before { color: #ccc; } -.content span.enum, .content a.enum, .block a.current.enum { color: #2dbfb8; } -.content span.struct, .content a.struct, .block a.current.struct { color: #2dbfb8; } -.content span.type, .content a.type, .block a.current.type { color: #2dbfb8; } -.content span.associatedtype, -.content a.associatedtype, -.block a.current.associatedtype { color: #D2991D; } -.content span.foreigntype, .content a.foreigntype, .block a.current.foreigntype { color: #2dbfb8; } -.content span.attr, .content a.attr, .block a.current.attr, -.content span.derive, .content a.derive, .block a.current.derive, -.content span.macro, .content a.macro, .block a.current.macro { color: #09bd00; } -.content span.union, .content a.union, .block a.current.union { color: #2dbfb8; } -.content span.constant, .content a.constant, .block a.current.constant, -.content span.static, .content a.static, .block a.current.static { color: #D2991D; } -.content span.primitive, .content a.primitive, .block a.current.primitive { color: #2dbfb8; } -.content span.externcrate, -.content span.mod, .content a.mod, .block a.current.mod { color: #D2991D; } -.content span.trait, .content a.trait, .block a.current.trait { color: #b78cf2; } -.content span.traitalias, .content a.traitalias, .block a.current.traitalias { color: #b78cf2; } -.content span.fn, .content a.fn, .block a.current.fn, -.content span.method, .content a.method, .block a.current.method, -.content span.tymethod, .content a.tymethod, .block a.current.tymethod, -.content .fnname{ color: #2BAB63; } -.content span.keyword, .content a.keyword, .block a.current.keyword { color: #D2991D; } +.content span.enum, .content a.enum { color: #2dbfb8; } +.content span.struct, .content a.struct { color: #2dbfb8; } +.content span.type, .content a.type { color: #2dbfb8; } +.content span.associatedtype, .content a.associatedtype { color: #D2991D; } +.content span.foreigntype, .content a.foreigntype { color: #2dbfb8; } +.content span.attr, .content a.attr, +.content span.derive, .content a.derive, +.content span.macro, .content a.macro { color: #09bd00; } +.content span.union, .content a.union { color: #2dbfb8; } +.content span.constant, .content a.constant, +.content span.static, .content a.static { color: #D2991D; } +.content span.primitive, .content a.primitive { color: #2dbfb8; } +.content span.mod, .content a.mod { color: #D2991D; } +.content span.trait, .content a.trait { color: #b78cf2; } +.content span.traitalias, .content a.traitalias { color: #b78cf2; } +.content span.fn, .content a.fn, +.content .fnname { color: #2BAB63; } +.content span.keyword, .content a.keyword { color: #D2991D; } .sidebar a { color: #fdbf35; } .sidebar a.current.enum { color: #12ece2; } .sidebar a.current.struct { color: #12ece2; } .sidebar a.current.type { color: #12ece2; } -.sidebar a.current.associatedtype { color: #fdbf35; } .sidebar a.current.foreigntype { color: #12ece2; } .sidebar a.current.attr, .sidebar a.current.derive, @@ -120,13 +114,9 @@ a.result-keyword:focus { background-color: #884719; } .sidebar a.current.constant .sidebar a.current.static { color: #fdbf35; } .sidebar a.current.primitive { color: #12ece2; } -.sidebar a.current.externcrate -.sidebar a.current.mod { color: #fdbf35; } .sidebar a.current.trait { color: #cca7ff; } .sidebar a.current.traitalias { color: #cca7ff; } -.sidebar a.current.fn, -.sidebar a.current.method, -.sidebar a.current.tymethod { color: #32d479; } +.sidebar a.current.fn { color: #32d479; } .sidebar a.current.keyword { color: #fdbf35; } pre.rust .comment { color: #8d8d8b; } diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index 9ced9e7b5ce32..0b7d1600e7aa4 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -82,35 +82,29 @@ a.result-keyword:focus { background-color: #afc6e4; } .content .item-info::before { color: #ccc; } -.content span.enum, .content a.enum, .block a.current.enum { color: #AD378A; } -.content span.struct, .content a.struct, .block a.current.struct { color: #AD378A; } -.content span.type, .content a.type, .block a.current.type { color: #AD378A; } -.content span.foreigntype, .content a.foreigntype, .block a.current.foreigntype { color: #3873AD; } -.content span.associatedtype, -.content a.associatedtype, -.block a.current.associatedtype { color: #3873AD; } -.content span.attr, .content a.attr, .block a.current.attr, -.content span.derive, .content a.derive, .block a.current.derive, -.content span.macro, .content a.macro, .block a.current.macro { color: #068000; } -.content span.union, .content a.union, .block a.current.union { color: #AD378A; } -.content span.constant, .content a.constant, .block a.current.constant, -.content span.static, .content a.static, .block a.current.static { color: #3873AD; } -.content span.primitive, .content a.primitive, .block a.current.primitive { color: #AD378A; } -.content span.externcrate, -.content span.mod, .content a.mod, .block a.current.mod { color: #3873AD; } -.content span.trait, .content a.trait, .block a.current.trait { color: #6E4FC9; } -.content span.traitalias, .content a.traitalias, .block a.current.traitalias { color: #5137AD; } -.content span.fn, .content a.fn, .block a.current.fn, -.content span.method, .content a.method, .block a.current.method, -.content span.tymethod, .content a.tymethod, .block a.current.tymethod, +.content span.enum, .content a.enum { color: #AD378A; } +.content span.struct, .content a.struct { color: #AD378A; } +.content span.type, .content a.type { color: #AD378A; } +.content span.associatedtype, .content a.associatedtype { color: #3873AD; } +.content span.foreigntype, .content a.foreigntype { color: #3873AD; } +.content span.attr, .content a.attr, +.content span.derive, .content a.derive, +.content span.macro, .content a.macro { color: #068000; } +.content span.union, .content a.union { color: #AD378A; } +.content span.constant, .content a.constant, +.content span.static, .content a.static { color: #3873AD; } +.content span.primitive, .content a.primitive { color: #AD378A; } +.content span.mod, .content a.mod { color: #3873AD; } +.content span.trait, .content a.trait { color: #6E4FC9; } +.content span.traitalias, .content a.traitalias { color: #5137AD; } +.content span.fn, .content a.fn, .content .fnname { color: #AD7C37; } -.content span.keyword, .content a.keyword, .block a.current.keyword { color: #3873AD; } +.content span.keyword, .content a.keyword { color: #3873AD; } .sidebar a { color: #356da4; } .sidebar a.current.enum { color: #a63283; } .sidebar a.current.struct { color: #a63283; } .sidebar a.current.type { color: #a63283; } -.sidebar a.current.associatedtype { color: #356da4; } .sidebar a.current.foreigntype { color: #356da4; } .sidebar a.current.attr, .sidebar a.current.derive, @@ -119,13 +113,9 @@ a.result-keyword:focus { background-color: #afc6e4; } .sidebar a.current.constant .sidebar a.current.static { color: #356da4; } .sidebar a.current.primitive { color: #a63283; } -.sidebar a.current.externcrate -.sidebar a.current.mod { color: #356da4; } .sidebar a.current.trait { color: #6849c3; } .sidebar a.current.traitalias { color: #4b349e; } -.sidebar a.current.fn, -.sidebar a.current.method, -.sidebar a.current.tymethod { color: #a67736; } +.sidebar a.current.fn { color: #a67736; } .sidebar a.current.keyword { color: #356da4; } a { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index f6c648140b856..14d695582b0f8 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -9,7 +9,7 @@ #![feature(control_flow_enum)] #![feature(drain_filter)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(test)] #![feature(never_type)] #![feature(once_cell)] diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index c27ac0ac40e1d..e6cef4a326ac0 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -230,7 +230,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } else { // All items need to be handled here in case someone wishes to link // to them with intra-doc links - self.cx.cache.access_levels.map.insert(did, AccessLevel::Public); + self.cx.cache.access_levels.set_access_level(did, AccessLevel::Public); } } } diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index f01ec38665c01..8221e0998d79a 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -38,10 +38,10 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> { fn update(&mut self, did: DefId, level: Option) -> Option { let is_hidden = self.tcx.is_doc_hidden(did); - let old_level = self.access_levels.map.get(&did).cloned(); + let old_level = self.access_levels.get_access_level(did); // Accessibility levels can only grow if level > old_level && !is_hidden { - self.access_levels.map.insert(did, level.unwrap()); + self.access_levels.set_access_level(did, level.unwrap()); level } else { old_level diff --git a/src/test/ui/async-await/async-await-let-else.rs b/src/test/ui/async-await/async-await-let-else.rs index 4b287159d13e7..3fb2142b9e5d8 100644 --- a/src/test/ui/async-await/async-await-let-else.rs +++ b/src/test/ui/async-await/async-await-let-else.rs @@ -2,7 +2,7 @@ // revisions: drop-tracking no-drop-tracking // [drop-tracking] compile-flags: -Zdrop-tracking=yes // [no-drop-tracking] compile-flags: -Zdrop-tracking=no -#![feature(let_else)] + use std::rc::Rc; async fn foo(x: Option) { diff --git a/src/test/ui/empty/empty-never-array.stderr b/src/test/ui/empty/empty-never-array.stderr index 8c80b05ee3aea..adf7827436805 100644 --- a/src/test/ui/empty/empty-never-array.stderr +++ b/src/test/ui/empty/empty-never-array.stderr @@ -18,7 +18,7 @@ help: you might want to use `if let` to ignore the variant that isn't matched | LL | let u = if let Helper::U(u) = Helper::T(t, []) { u } else { todo!() }; | ++++++++++ ++++++++++++++++++++++ -help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched +help: alternatively, you might want to use let else to handle the variant that isn't matched | LL | let Helper::U(u) = Helper::T(t, []) else { todo!() }; | ++++++++++++++++ diff --git a/src/test/ui/error-codes/E0005.stderr b/src/test/ui/error-codes/E0005.stderr index f01a77bd374b6..de8e6bac486c1 100644 --- a/src/test/ui/error-codes/E0005.stderr +++ b/src/test/ui/error-codes/E0005.stderr @@ -19,7 +19,7 @@ help: you might want to use `if let` to ignore the variant that isn't matched | LL | let y = if let Some(y) = x { y } else { todo!() }; | ++++++++++ ++++++++++++++++++++++ -help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched +help: alternatively, you might want to use let else to handle the variant that isn't matched | LL | let Some(y) = x else { todo!() }; | ++++++++++++++++ diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr index f8349391a0fe7..5ced344f13f38 100644 --- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr @@ -19,7 +19,7 @@ help: you might want to use `if let` to ignore the variant that isn't matched | LL | let _x = if let Ok(_x) = foo() { _x } else { todo!() }; | +++++++++++ +++++++++++++++++++++++ -help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched +help: alternatively, you might want to use let else to handle the variant that isn't matched | LL | let Ok(_x) = foo() else { todo!() }; | ++++++++++++++++ diff --git a/src/test/ui/feature-gates/feature-gate-let_else.rs b/src/test/ui/feature-gates/feature-gate-let_else.rs deleted file mode 100644 index 3f04a9dabfd1f..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-let_else.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - let Some(x) = Some(1) else { //~ ERROR `let...else` statements are unstable - return; - }; -} diff --git a/src/test/ui/feature-gates/feature-gate-let_else.stderr b/src/test/ui/feature-gates/feature-gate-let_else.stderr deleted file mode 100644 index 8625260415467..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-let_else.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0658]: `let...else` statements are unstable - --> $DIR/feature-gate-let_else.rs:2:5 - | -LL | / let Some(x) = Some(1) else { -LL | | return; -LL | | }; - | |______^ - | - = note: see issue #87335 for more information - = help: add `#![feature(let_else)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/generic-associated-types/type-param-defaults.rs b/src/test/ui/generic-associated-types/type-param-defaults.rs new file mode 100644 index 0000000000000..f034076b01093 --- /dev/null +++ b/src/test/ui/generic-associated-types/type-param-defaults.rs @@ -0,0 +1,34 @@ +// Check that we disallow GAT param defaults, even with `invalid_type_param_default` allowed + +#![allow(invalid_type_param_default)] + +trait Trait { + type Assoc; + //~^ defaults for type parameters are only allowed +} + +impl Trait for () { + type Assoc = u64; + //~^ defaults for type parameters are only allowed +} + +impl Trait for u32 { + type Assoc = T; + //~^ defaults for type parameters are only allowed +} + +trait Other {} +impl Other for u32 {} + +fn foo() +where + T: Trait, + T::Assoc: Other { + } + +fn main() { + // errors + foo::<()>(); + // works + foo::(); +} diff --git a/src/test/ui/generic-associated-types/type-param-defaults.stderr b/src/test/ui/generic-associated-types/type-param-defaults.stderr new file mode 100644 index 0000000000000..85ccaba0e69e7 --- /dev/null +++ b/src/test/ui/generic-associated-types/type-param-defaults.stderr @@ -0,0 +1,20 @@ +error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + --> $DIR/type-param-defaults.rs:6:16 + | +LL | type Assoc; + | ^^^^^^^ + +error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + --> $DIR/type-param-defaults.rs:11:16 + | +LL | type Assoc = u64; + | ^^^^^^^ + +error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + --> $DIR/type-param-defaults.rs:16:16 + | +LL | type Assoc = T; + | ^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/let-else/issue-100103.rs b/src/test/ui/let-else/issue-100103.rs index e393deab764f3..f5f9b2f5f0634 100644 --- a/src/test/ui/let-else/issue-100103.rs +++ b/src/test/ui/let-else/issue-100103.rs @@ -2,7 +2,7 @@ // check-pass #![feature(try_blocks)] -#![feature(let_else)] + fn main() { let _: Result = try { diff --git a/src/test/ui/let-else/issue-94176.rs b/src/test/ui/let-else/issue-94176.rs index e35bbd8883062..f76dfc15bc15d 100644 --- a/src/test/ui/let-else/issue-94176.rs +++ b/src/test/ui/let-else/issue-94176.rs @@ -1,6 +1,6 @@ // Issue #94176: wrong span for the error message of a mismatched type error, // if the function uses a `let else` construct. -#![feature(let_else)] + pub fn test(a: Option) -> Option { //~ ERROR mismatched types let Some(_) = a else { return None; }; diff --git a/src/test/ui/let-else/issue-99975.rs b/src/test/ui/let-else/issue-99975.rs index 80f6355619412..5b164f347e7dd 100644 --- a/src/test/ui/let-else/issue-99975.rs +++ b/src/test/ui/let-else/issue-99975.rs @@ -1,7 +1,7 @@ // run-pass // compile-flags: -C opt-level=3 -Zvalidate-mir -#![feature(let_else)] + fn return_result() -> Option { Some("ok".to_string()) diff --git a/src/test/ui/let-else/let-else-allow-in-expr.rs b/src/test/ui/let-else/let-else-allow-in-expr.rs index 39f4c9060fea5..33acb6c6a29c5 100644 --- a/src/test/ui/let-else/let-else-allow-in-expr.rs +++ b/src/test/ui/let-else/let-else-allow-in-expr.rs @@ -1,5 +1,3 @@ -#![feature(let_else)] - #![deny(unused_variables)] fn main() { diff --git a/src/test/ui/let-else/let-else-allow-in-expr.stderr b/src/test/ui/let-else/let-else-allow-in-expr.stderr index e86bcbc850029..3b2b9066c90d6 100644 --- a/src/test/ui/let-else/let-else-allow-in-expr.stderr +++ b/src/test/ui/let-else/let-else-allow-in-expr.stderr @@ -1,17 +1,17 @@ error: unused variable: `x` - --> $DIR/let-else-allow-in-expr.rs:7:13 + --> $DIR/let-else-allow-in-expr.rs:5:13 | LL | let x = 1; | ^ help: if this is intentional, prefix it with an underscore: `_x` | note: the lint level is defined here - --> $DIR/let-else-allow-in-expr.rs:3:9 + --> $DIR/let-else-allow-in-expr.rs:1:9 | LL | #![deny(unused_variables)] | ^^^^^^^^^^^^^^^^ error: unused variable: `x` - --> $DIR/let-else-allow-in-expr.rs:29:9 + --> $DIR/let-else-allow-in-expr.rs:27:9 | LL | let x = 1; | ^ help: if this is intentional, prefix it with an underscore: `_x` diff --git a/src/test/ui/let-else/let-else-allow-unused.rs b/src/test/ui/let-else/let-else-allow-unused.rs index 86ebacfa7b7d1..bbb1c7beaf8d3 100644 --- a/src/test/ui/let-else/let-else-allow-unused.rs +++ b/src/test/ui/let-else/let-else-allow-unused.rs @@ -1,6 +1,6 @@ // issue #89807 -#![feature(let_else)] + #[deny(unused_variables)] diff --git a/src/test/ui/let-else/let-else-binding-explicit-mut-annotated.rs b/src/test/ui/let-else/let-else-binding-explicit-mut-annotated.rs index b65fa13c1de1e..955f33ee134d2 100644 --- a/src/test/ui/let-else/let-else-binding-explicit-mut-annotated.rs +++ b/src/test/ui/let-else/let-else-binding-explicit-mut-annotated.rs @@ -1,6 +1,6 @@ // from rfc2005 test suite -#![feature(let_else)] + // Verify the binding mode shifts - only when no `&` are auto-dereferenced is the // final default binding mode mutable. diff --git a/src/test/ui/let-else/let-else-binding-explicit-mut-borrow.rs b/src/test/ui/let-else/let-else-binding-explicit-mut-borrow.rs index 63b35df76aa04..1524d01023331 100644 --- a/src/test/ui/let-else/let-else-binding-explicit-mut-borrow.rs +++ b/src/test/ui/let-else/let-else-binding-explicit-mut-borrow.rs @@ -1,8 +1,8 @@ -#![feature(let_else)] - // Slightly different from explicit-mut-annotated -- this won't show an error until borrowck. // Should it show a type error instead? + + fn main() { let Some(n): &mut Option = &mut &Some(5i32) else { //~^ ERROR cannot borrow data in a `&` reference as mutable diff --git a/src/test/ui/let-else/let-else-binding-explicit-mut-pass.rs b/src/test/ui/let-else/let-else-binding-explicit-mut-pass.rs index 305be92219214..b0a6264a10d45 100644 --- a/src/test/ui/let-else/let-else-binding-explicit-mut-pass.rs +++ b/src/test/ui/let-else/let-else-binding-explicit-mut-pass.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(let_else)] + fn main() { let Some(n) = &mut &mut Some(5i32) else { return; }; diff --git a/src/test/ui/let-else/let-else-binding-explicit-mut.rs b/src/test/ui/let-else/let-else-binding-explicit-mut.rs index dbe4715b1a975..a153b3af0de1c 100644 --- a/src/test/ui/let-else/let-else-binding-explicit-mut.rs +++ b/src/test/ui/let-else/let-else-binding-explicit-mut.rs @@ -1,6 +1,6 @@ // from rfc2005 test suite -#![feature(let_else)] + // Verify the binding mode shifts - only when no `&` are auto-dereferenced is the // final default binding mode mutable. diff --git a/src/test/ui/let-else/let-else-binding-immutable.rs b/src/test/ui/let-else/let-else-binding-immutable.rs index 96de0ffe26e6b..ff2d9f240a094 100644 --- a/src/test/ui/let-else/let-else-binding-immutable.rs +++ b/src/test/ui/let-else/let-else-binding-immutable.rs @@ -1,6 +1,6 @@ // from rfc2005 test suite -#![feature(let_else)] + pub fn main() { let Some(x) = &Some(3) else { diff --git a/src/test/ui/let-else/let-else-bindings.rs b/src/test/ui/let-else/let-else-bindings.rs index d5121e744dad3..7d2cad978fc02 100644 --- a/src/test/ui/let-else/let-else-bindings.rs +++ b/src/test/ui/let-else/let-else-bindings.rs @@ -1,6 +1,6 @@ // run-pass // adapted from src/test/ui/binding/if-let.rs -#![feature(let_else)] + #![allow(dead_code)] fn none() -> bool { diff --git a/src/test/ui/let-else/let-else-bool-binop-init.fixed b/src/test/ui/let-else/let-else-bool-binop-init.fixed index e47f7f23d7e07..20e558ca909cf 100644 --- a/src/test/ui/let-else/let-else-bool-binop-init.fixed +++ b/src/test/ui/let-else/let-else-bool-binop-init.fixed @@ -1,6 +1,6 @@ // run-rustfix -#![feature(let_else)] + fn main() { let true = (true && false) else { return }; //~ ERROR a `&&` expression cannot be directly assigned in `let...else` diff --git a/src/test/ui/let-else/let-else-bool-binop-init.rs b/src/test/ui/let-else/let-else-bool-binop-init.rs index e443fb0d6a376..f88179a940b5d 100644 --- a/src/test/ui/let-else/let-else-bool-binop-init.rs +++ b/src/test/ui/let-else/let-else-bool-binop-init.rs @@ -1,6 +1,6 @@ // run-rustfix -#![feature(let_else)] + fn main() { let true = true && false else { return }; //~ ERROR a `&&` expression cannot be directly assigned in `let...else` diff --git a/src/test/ui/let-else/let-else-brace-before-else.fixed b/src/test/ui/let-else/let-else-brace-before-else.fixed index fb4fd77791e03..a75c770ddf299 100644 --- a/src/test/ui/let-else/let-else-brace-before-else.fixed +++ b/src/test/ui/let-else/let-else-brace-before-else.fixed @@ -1,6 +1,6 @@ // run-rustfix -#![feature(let_else)] + fn main() { let Some(1) = ({ Some(1) }) else { diff --git a/src/test/ui/let-else/let-else-brace-before-else.rs b/src/test/ui/let-else/let-else-brace-before-else.rs index c4c5a1ca28bbe..5603b946f3883 100644 --- a/src/test/ui/let-else/let-else-brace-before-else.rs +++ b/src/test/ui/let-else/let-else-brace-before-else.rs @@ -1,6 +1,6 @@ // run-rustfix -#![feature(let_else)] + fn main() { let Some(1) = { Some(1) } else { diff --git a/src/test/ui/let-else/let-else-check.rs b/src/test/ui/let-else/let-else-check.rs index 9e32cbef742a2..713fd986e9792 100644 --- a/src/test/ui/let-else/let-else-check.rs +++ b/src/test/ui/let-else/let-else-check.rs @@ -1,5 +1,3 @@ -#![feature(let_else)] - #![deny(unused_variables)] fn main() { diff --git a/src/test/ui/let-else/let-else-check.stderr b/src/test/ui/let-else/let-else-check.stderr index 3d647a4c05d86..bdecbf708f9d2 100644 --- a/src/test/ui/let-else/let-else-check.stderr +++ b/src/test/ui/let-else/let-else-check.stderr @@ -1,17 +1,17 @@ error: unused variable: `x` - --> $DIR/let-else-check.rs:14:13 + --> $DIR/let-else-check.rs:12:13 | LL | let x = 1; | ^ help: if this is intentional, prefix it with an underscore: `_x` | note: the lint level is defined here - --> $DIR/let-else-check.rs:3:9 + --> $DIR/let-else-check.rs:1:9 | LL | #![deny(unused_variables)] | ^^^^^^^^^^^^^^^^ error: unused variable: `x` - --> $DIR/let-else-check.rs:18:9 + --> $DIR/let-else-check.rs:16:9 | LL | let x = 1; | ^ help: if this is intentional, prefix it with an underscore: `_x` diff --git a/src/test/ui/let-else/let-else-deref-coercion-annotated.rs b/src/test/ui/let-else/let-else-deref-coercion-annotated.rs index 65d88a6d82827..60fdf825a336a 100644 --- a/src/test/ui/let-else/let-else-deref-coercion-annotated.rs +++ b/src/test/ui/let-else/let-else-deref-coercion-annotated.rs @@ -6,7 +6,7 @@ // Deref/DerefMut to Bar. You can do this with an irrefutable binding, so it should work with // let-else too. -#![feature(let_else)] + use std::ops::{Deref, DerefMut}; struct Foo(Bar); diff --git a/src/test/ui/let-else/let-else-deref-coercion.rs b/src/test/ui/let-else/let-else-deref-coercion.rs index 87489d84bbf3d..052a5a8c73cc4 100644 --- a/src/test/ui/let-else/let-else-deref-coercion.rs +++ b/src/test/ui/let-else/let-else-deref-coercion.rs @@ -3,7 +3,7 @@ // We attempt to `let Bar::Present(_) = foo else { ... }` where foo is meant to Deref/DerefMut to // Bar. This fails, you must add a type annotation like `let _: &mut Bar = _ else { ... }` -#![feature(let_else)] + use std::ops::{Deref, DerefMut}; struct Foo(Bar); diff --git a/src/test/ui/let-else/let-else-destructuring.rs b/src/test/ui/let-else/let-else-destructuring.rs index 9a09c414ac80f..d1f1a69bfc254 100644 --- a/src/test/ui/let-else/let-else-destructuring.rs +++ b/src/test/ui/let-else/let-else-destructuring.rs @@ -1,4 +1,3 @@ -#![feature(let_else)] #[derive(Debug)] enum Foo { Done, diff --git a/src/test/ui/let-else/let-else-destructuring.stderr b/src/test/ui/let-else/let-else-destructuring.stderr index 95efb7116829e..7d6cb2386440d 100644 --- a/src/test/ui/let-else/let-else-destructuring.stderr +++ b/src/test/ui/let-else/let-else-destructuring.stderr @@ -1,11 +1,11 @@ error: ... else { ... } is not allowed - --> $DIR/let-else-destructuring.rs:11:9 + --> $DIR/let-else-destructuring.rs:10:9 | LL | &Foo::Nested(Some(value)) = value else { break }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0070]: invalid left-hand side of assignment - --> $DIR/let-else-destructuring.rs:11:35 + --> $DIR/let-else-destructuring.rs:10:35 | LL | &Foo::Nested(Some(value)) = value else { break }; | ------------------------- ^ diff --git a/src/test/ui/let-else/let-else-drop-order.rs b/src/test/ui/let-else/let-else-drop-order.rs index 0054f3d4182ec..e91e5de84e4bd 100644 --- a/src/test/ui/let-else/let-else-drop-order.rs +++ b/src/test/ui/let-else/let-else-drop-order.rs @@ -16,7 +16,7 @@ // This is important as it's easy to update the stdout file // with a --bless and miss the impact of that change. -#![feature(let_else)] + #![allow(irrefutable_let_patterns)] use std::cell::RefCell; diff --git a/src/test/ui/let-else/let-else-if.rs b/src/test/ui/let-else/let-else-if.rs index c3a17330d6e2f..e8c54ca7ab293 100644 --- a/src/test/ui/let-else/let-else-if.rs +++ b/src/test/ui/let-else/let-else-if.rs @@ -1,5 +1,3 @@ -#![feature(let_else)] - fn main() { let Some(_) = Some(()) else if true { //~^ ERROR conditional `else if` is not supported for `let...else` diff --git a/src/test/ui/let-else/let-else-if.stderr b/src/test/ui/let-else/let-else-if.stderr index 746738bbd939b..c63fd61c5dec9 100644 --- a/src/test/ui/let-else/let-else-if.stderr +++ b/src/test/ui/let-else/let-else-if.stderr @@ -1,5 +1,5 @@ error: conditional `else if` is not supported for `let...else` - --> $DIR/let-else-if.rs:4:33 + --> $DIR/let-else-if.rs:2:33 | LL | let Some(_) = Some(()) else if true { | ^^ expected `{` diff --git a/src/test/ui/let-else/let-else-irrefutable.rs b/src/test/ui/let-else/let-else-irrefutable.rs index b1e09a1248ff7..1cb68ecb8a6bf 100644 --- a/src/test/ui/let-else/let-else-irrefutable.rs +++ b/src/test/ui/let-else/let-else-irrefutable.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(let_else)] + fn main() { let x = 1 else { return }; //~ WARN irrefutable `let...else` pattern diff --git a/src/test/ui/let-else/let-else-missing-semicolon.rs b/src/test/ui/let-else/let-else-missing-semicolon.rs index ed9d79f1ebde9..d87ac90c1a772 100644 --- a/src/test/ui/let-else/let-else-missing-semicolon.rs +++ b/src/test/ui/let-else/let-else-missing-semicolon.rs @@ -1,5 +1,3 @@ -#![feature(let_else)] - fn main() { let Some(x) = Some(1) else { return; diff --git a/src/test/ui/let-else/let-else-missing-semicolon.stderr b/src/test/ui/let-else/let-else-missing-semicolon.stderr index 1818a0b126348..99029ff33fe0c 100644 --- a/src/test/ui/let-else/let-else-missing-semicolon.stderr +++ b/src/test/ui/let-else/let-else-missing-semicolon.stderr @@ -1,5 +1,5 @@ error: expected `;`, found keyword `let` - --> $DIR/let-else-missing-semicolon.rs:6:6 + --> $DIR/let-else-missing-semicolon.rs:4:6 | LL | } | ^ help: add `;` here @@ -7,7 +7,7 @@ LL | let _ = ""; | --- unexpected token error: expected `;`, found `}` - --> $DIR/let-else-missing-semicolon.rs:10:6 + --> $DIR/let-else-missing-semicolon.rs:8:6 | LL | } | ^ help: add `;` here diff --git a/src/test/ui/let-else/let-else-no-double-error.rs b/src/test/ui/let-else/let-else-no-double-error.rs index 35dcdd3f6be3c..91fcc5d7e91e8 100644 --- a/src/test/ui/let-else/let-else-no-double-error.rs +++ b/src/test/ui/let-else/let-else-no-double-error.rs @@ -1,6 +1,6 @@ // from rfc2005 test suite -#![feature(let_else)] + // Without caching type lookups in FnCtxt.resolve_ty_and_def_ufcs // the error below would be reported twice (once when checking diff --git a/src/test/ui/let-else/let-else-non-copy.rs b/src/test/ui/let-else/let-else-non-copy.rs index 79ed82dd124bd..08c07dd1a43ac 100644 --- a/src/test/ui/let-else/let-else-non-copy.rs +++ b/src/test/ui/let-else/let-else-non-copy.rs @@ -10,7 +10,7 @@ // // The move was due to mir::Place being Copy, but mir::VarDebugInfoContents not being Copy. -#![feature(let_else)] + #[derive(Copy, Clone)] struct Copyable; diff --git a/src/test/ui/let-else/let-else-non-diverging.rs b/src/test/ui/let-else/let-else-non-diverging.rs index a1cee335aeeba..b5bd91ceb9e75 100644 --- a/src/test/ui/let-else/let-else-non-diverging.rs +++ b/src/test/ui/let-else/let-else-non-diverging.rs @@ -1,5 +1,3 @@ -#![feature(let_else)] - fn main() { let Some(x) = Some(1) else { //~ ERROR does not diverge Some(2) diff --git a/src/test/ui/let-else/let-else-non-diverging.stderr b/src/test/ui/let-else/let-else-non-diverging.stderr index 05e45f689890d..c999a54952560 100644 --- a/src/test/ui/let-else/let-else-non-diverging.stderr +++ b/src/test/ui/let-else/let-else-non-diverging.stderr @@ -1,5 +1,5 @@ error[E0308]: `else` clause of `let...else` does not diverge - --> $DIR/let-else-non-diverging.rs:4:32 + --> $DIR/let-else-non-diverging.rs:2:32 | LL | let Some(x) = Some(1) else { | ________________________________^ @@ -13,7 +13,7 @@ LL | | }; = help: ...or use `match` instead of `let...else` error[E0308]: `else` clause of `let...else` does not diverge - --> $DIR/let-else-non-diverging.rs:7:32 + --> $DIR/let-else-non-diverging.rs:5:32 | LL | let Some(x) = Some(1) else { | ________________________________^ @@ -29,7 +29,7 @@ LL | | }; = help: ...or use `match` instead of `let...else` error[E0308]: `else` clause of `let...else` does not diverge - --> $DIR/let-else-non-diverging.rs:12:32 + --> $DIR/let-else-non-diverging.rs:10:32 | LL | let Some(x) = Some(1) else { Some(2) }; | ^^^^^^^^^^^ expected `!`, found enum `Option` diff --git a/src/test/ui/let-else/let-else-ref-bindings-pass.rs b/src/test/ui/let-else/let-else-ref-bindings-pass.rs index f4abd6cc2df25..62fc65731cd2f 100644 --- a/src/test/ui/let-else/let-else-ref-bindings-pass.rs +++ b/src/test/ui/let-else/let-else-ref-bindings-pass.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(let_else)] + #![allow(unused_variables)] fn ref_() { diff --git a/src/test/ui/let-else/let-else-ref-bindings.rs b/src/test/ui/let-else/let-else-ref-bindings.rs index a4cd8e8c47d46..687e235d47e78 100644 --- a/src/test/ui/let-else/let-else-ref-bindings.rs +++ b/src/test/ui/let-else/let-else-ref-bindings.rs @@ -1,6 +1,6 @@ -#![feature(let_else)] #![allow(unused_variables)] + fn ref_() { let bytes: Vec = b"Hello"[..].to_vec(); let some = Some(bytes); diff --git a/src/test/ui/let-else/let-else-run-pass.rs b/src/test/ui/let-else/let-else-run-pass.rs index 5d96623236dab..a0fb6c683f8ce 100644 --- a/src/test/ui/let-else/let-else-run-pass.rs +++ b/src/test/ui/let-else/let-else-run-pass.rs @@ -1,6 +1,6 @@ // run-pass -#![feature(let_else)] + fn main() { #[allow(dead_code)] diff --git a/src/test/ui/let-else/let-else-scope.rs b/src/test/ui/let-else/let-else-scope.rs index f17682db4c3bd..78a67769ef284 100644 --- a/src/test/ui/let-else/let-else-scope.rs +++ b/src/test/ui/let-else/let-else-scope.rs @@ -1,5 +1,3 @@ -#![feature(let_else)] - fn main() { let Some(x) = Some(2) else { panic!("{}", x); //~ ERROR cannot find value `x` in this scope diff --git a/src/test/ui/let-else/let-else-scope.stderr b/src/test/ui/let-else/let-else-scope.stderr index 4b3936eac4bd5..3b4f0982940e8 100644 --- a/src/test/ui/let-else/let-else-scope.stderr +++ b/src/test/ui/let-else/let-else-scope.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `x` in this scope - --> $DIR/let-else-scope.rs:5:22 + --> $DIR/let-else-scope.rs:3:22 | LL | panic!("{}", x); | ^ not found in this scope diff --git a/src/test/ui/let-else/let-else-slicing-error.rs b/src/test/ui/let-else/let-else-slicing-error.rs index 4022656a8f53d..25770094bce99 100644 --- a/src/test/ui/let-else/let-else-slicing-error.rs +++ b/src/test/ui/let-else/let-else-slicing-error.rs @@ -1,5 +1,5 @@ // issue #92069 -#![feature(let_else)] + fn main() { let nums = vec![5, 4, 3, 2, 1]; diff --git a/src/test/ui/let-else/let-else-source-expr-nomove-pass.rs b/src/test/ui/let-else/let-else-source-expr-nomove-pass.rs index 2aa17ae8ceb1a..ee378abcf2bad 100644 --- a/src/test/ui/let-else/let-else-source-expr-nomove-pass.rs +++ b/src/test/ui/let-else/let-else-source-expr-nomove-pass.rs @@ -1,7 +1,7 @@ // run-pass // issue #89688 -#![feature(let_else)] + fn example_let_else(value: Option) { let Some(inner) = value else { diff --git a/src/test/ui/let-else/let-else-temp-borrowck.rs b/src/test/ui/let-else/let-else-temp-borrowck.rs index 3910d35e77676..6b4642d2f9852 100644 --- a/src/test/ui/let-else/let-else-temp-borrowck.rs +++ b/src/test/ui/let-else/let-else-temp-borrowck.rs @@ -3,7 +3,7 @@ // from issue #93951, where borrowck complained the temporary that `foo(&x)` was stored in was to // be dropped sometime after `x` was. It then suggested adding a semicolon that was already there. -#![feature(let_else)] + use std::fmt::Debug; fn foo<'a>(x: &'a str) -> Result { diff --git a/src/test/ui/let-else/let-else-temporary-lifetime.rs b/src/test/ui/let-else/let-else-temporary-lifetime.rs index 8542c3496b045..c23eaa997fe4d 100644 --- a/src/test/ui/let-else/let-else-temporary-lifetime.rs +++ b/src/test/ui/let-else/let-else-temporary-lifetime.rs @@ -1,6 +1,5 @@ // run-pass // compile-flags: -Zvalidate-mir -#![feature(let_else)] use std::fmt::Display; use std::rc::Rc; diff --git a/src/test/ui/let-else/let-else-then-diverge.rs b/src/test/ui/let-else/let-else-then-diverge.rs index 49633d943beea..1c8f7d758e8a6 100644 --- a/src/test/ui/let-else/let-else-then-diverge.rs +++ b/src/test/ui/let-else/let-else-then-diverge.rs @@ -2,7 +2,7 @@ // popped up in in #94012, where an alternative desugaring was // causing unreachable code errors -#![feature(let_else)] + #![deny(unused_variables)] #![deny(unreachable_code)] diff --git a/src/test/ui/let-else/let-else.rs b/src/test/ui/let-else/let-else.rs new file mode 100644 index 0000000000000..3505533e63f14 --- /dev/null +++ b/src/test/ui/let-else/let-else.rs @@ -0,0 +1,8 @@ +// run-pass + +fn main() { + let Some(x) = Some(1) else { + return; + }; + assert_eq!(x, 1); +} diff --git a/src/test/ui/pattern/usefulness/issue-31561.stderr b/src/test/ui/pattern/usefulness/issue-31561.stderr index 46aebccc5ffff..20f2f09500aa2 100644 --- a/src/test/ui/pattern/usefulness/issue-31561.stderr +++ b/src/test/ui/pattern/usefulness/issue-31561.stderr @@ -21,7 +21,7 @@ help: you might want to use `if let` to ignore the variants that aren't matched | LL | let y = if let Thing::Foo(y) = Thing::Foo(1) { y } else { todo!() }; | ++++++++++ ++++++++++++++++++++++ -help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variants that aren't matched +help: alternatively, you might want to use let else to handle the variants that aren't matched | LL | let Thing::Foo(y) = Thing::Foo(1) else { todo!() }; | ++++++++++++++++ diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr index ac2a9713e7d24..678c9b2ab58c3 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr +++ b/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr @@ -187,7 +187,7 @@ help: you might want to use `if let` to ignore the variant that isn't matched | LL | let _x = if let Opt::Some(ref _x) = e { _x } else { todo!() }; | +++++++++++ +++++++++++++++++++++++ -help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched +help: alternatively, you might want to use let else to handle the variant that isn't matched | LL | let Opt::Some(ref _x) = e else { todo!() }; | ++++++++++++++++ diff --git a/src/test/ui/pattern/usefulness/top-level-alternation.rs b/src/test/ui/pattern/usefulness/top-level-alternation.rs index 076de846129e6..e8cd12ea4a2c4 100644 --- a/src/test/ui/pattern/usefulness/top-level-alternation.rs +++ b/src/test/ui/pattern/usefulness/top-level-alternation.rs @@ -1,5 +1,3 @@ -#![feature(let_else)] - #![deny(unreachable_patterns)] fn main() { diff --git a/src/test/ui/pattern/usefulness/top-level-alternation.stderr b/src/test/ui/pattern/usefulness/top-level-alternation.stderr index dd5936fdcc429..17fa951c53905 100644 --- a/src/test/ui/pattern/usefulness/top-level-alternation.stderr +++ b/src/test/ui/pattern/usefulness/top-level-alternation.stderr @@ -1,71 +1,71 @@ error: unreachable pattern - --> $DIR/top-level-alternation.rs:6:23 + --> $DIR/top-level-alternation.rs:4:23 | LL | while let 0..=2 | 1 = 0 {} | ^ | note: the lint level is defined here - --> $DIR/top-level-alternation.rs:3:9 + --> $DIR/top-level-alternation.rs:1:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:7:20 + --> $DIR/top-level-alternation.rs:5:20 | LL | if let 0..=2 | 1 = 0 {} | ^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:11:15 + --> $DIR/top-level-alternation.rs:9:15 | LL | | 0 => {} | ^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:16:15 + --> $DIR/top-level-alternation.rs:14:15 | LL | | Some(0) => {} | ^^^^^^^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:21:9 + --> $DIR/top-level-alternation.rs:19:9 | LL | (0, 0) => {} | ^^^^^^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:41:9 + --> $DIR/top-level-alternation.rs:39:9 | LL | _ => {} | ^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:45:9 + --> $DIR/top-level-alternation.rs:43:9 | LL | Some(_) => {} | ^^^^^^^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:46:9 + --> $DIR/top-level-alternation.rs:44:9 | LL | None => {} | ^^^^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:51:9 + --> $DIR/top-level-alternation.rs:49:9 | LL | None | Some(_) => {} | ^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:55:9 + --> $DIR/top-level-alternation.rs:53:9 | LL | 1..=2 => {}, | ^^^^^ error: unreachable pattern - --> $DIR/top-level-alternation.rs:58:14 + --> $DIR/top-level-alternation.rs:56:14 | LL | let (0 | 0) = 0 else { return }; | ^ diff --git a/src/test/ui/privacy/access_levels.rs b/src/test/ui/privacy/access_levels.rs index d51d2b57267b6..aa718ab9254df 100644 --- a/src/test/ui/privacy/access_levels.rs +++ b/src/test/ui/privacy/access_levels.rs @@ -1,49 +1,62 @@ #![feature(rustc_attrs)] -#[rustc_access_level] mod outer { //~ ERROR None - #[rustc_access_level] pub mod inner { //~ ERROR Some(Exported) - #[rustc_access_level] - extern "C" { //~ ERROR Some(Exported) - #[rustc_access_level] static a: u8; //~ ERROR None - #[rustc_access_level] pub fn b(); //~ ERROR Some(Exported) - } - #[rustc_access_level] - pub trait Trait { //~ ERROR Some(Exported) - #[rustc_access_level] const A: i32; //~ ERROR Some(Exported) - #[rustc_access_level] type B; //~ ERROR Some(Exported) +#[rustc_effective_visibility] +mod outer { //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) + #[rustc_effective_visibility] + pub mod inner1 { //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + + #[rustc_effective_visibility] + extern "C" {} //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + + #[rustc_effective_visibility] + pub trait PubTrait { //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + #[rustc_effective_visibility] + const A: i32; //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + #[rustc_effective_visibility] + type B; //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub } - #[rustc_access_level] - pub struct Struct { //~ ERROR Some(Exported) - #[rustc_access_level] a: u8, //~ ERROR None - #[rustc_access_level] pub b: u8, //~ ERROR Some(Exported) - } + #[rustc_effective_visibility] + struct PrivStruct; //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) - #[rustc_access_level] - pub union Union { //~ ERROR Some(Exported) - #[rustc_access_level] a: u8, //~ ERROR None - #[rustc_access_level] pub b: u8, //~ ERROR Some(Exported) + #[rustc_effective_visibility] + pub union PubUnion { //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + #[rustc_effective_visibility] + a: u8, //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) + #[rustc_effective_visibility] + pub b: u8, //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub } - #[rustc_access_level] - pub enum Enum { //~ ERROR Some(Exported) - #[rustc_access_level] A( //~ ERROR Some(Exported) - #[rustc_access_level] Struct, //~ ERROR Some(Exported) - #[rustc_access_level] Union, //~ ERROR Some(Exported) + #[rustc_effective_visibility] + pub enum Enum { //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + #[rustc_effective_visibility] + A( //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + #[rustc_effective_visibility] + PubUnion, //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub ), } } - #[rustc_access_level] macro_rules! none_macro { //~ ERROR None + #[rustc_effective_visibility] + macro_rules! none_macro { //~ Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) () => {}; } #[macro_export] - #[rustc_access_level] macro_rules! public_macro { //~ ERROR Some(Public) + #[rustc_effective_visibility] + macro_rules! public_macro { //~ Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub () => {}; } + + #[rustc_effective_visibility] + pub struct ReachableStruct { //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub, ReachableFromImplTrait: pub + #[rustc_effective_visibility] + pub a: u8, //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub, ReachableFromImplTrait: pub + } } -pub use outer::inner; +pub use outer::inner1; + +pub fn foo() -> outer::ReachableStruct { outer::ReachableStruct {a: 0} } fn main() {} diff --git a/src/test/ui/privacy/access_levels.stderr b/src/test/ui/privacy/access_levels.stderr index f326293c384a5..2ed6c330a2f97 100644 --- a/src/test/ui/privacy/access_levels.stderr +++ b/src/test/ui/privacy/access_levels.stderr @@ -1,125 +1,104 @@ -error: None - --> $DIR/access_levels.rs:3:23 +error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) + --> $DIR/access_levels.rs:4:1 | -LL | #[rustc_access_level] mod outer { - | ^^^^^^^^^ +LL | mod outer { + | ^^^^^^^^^ -error: Some(Exported) - --> $DIR/access_levels.rs:4:27 +error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + --> $DIR/access_levels.rs:6:5 | -LL | #[rustc_access_level] pub mod inner { - | ^^^^^^^^^^^^^ +LL | pub mod inner1 { + | ^^^^^^^^^^^^^^ -error: Some(Exported) - --> $DIR/access_levels.rs:6:9 +error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + --> $DIR/access_levels.rs:9:9 | -LL | / extern "C" { -LL | | #[rustc_access_level] static a: u8; -LL | | #[rustc_access_level] pub fn b(); -LL | | } - | |_________^ +LL | extern "C" {} + | ^^^^^^^^^^^^^ -error: Some(Exported) - --> $DIR/access_levels.rs:11:9 +error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + --> $DIR/access_levels.rs:12:9 | -LL | pub trait Trait { - | ^^^^^^^^^^^^^^^ +LL | pub trait PubTrait { + | ^^^^^^^^^^^^^^^^^^ -error: Some(Exported) - --> $DIR/access_levels.rs:17:9 +error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) + --> $DIR/access_levels.rs:20:9 | -LL | pub struct Struct { +LL | struct PrivStruct; | ^^^^^^^^^^^^^^^^^ -error: None - --> $DIR/access_levels.rs:18:35 - | -LL | #[rustc_access_level] a: u8, - | ^^^^^ - -error: Some(Exported) - --> $DIR/access_levels.rs:19:35 - | -LL | #[rustc_access_level] pub b: u8, - | ^^^^^^^^^ - -error: Some(Exported) +error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub --> $DIR/access_levels.rs:23:9 | -LL | pub union Union { - | ^^^^^^^^^^^^^^^ +LL | pub union PubUnion { + | ^^^^^^^^^^^^^^^^^^ -error: None - --> $DIR/access_levels.rs:24:35 +error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) + --> $DIR/access_levels.rs:25:13 | -LL | #[rustc_access_level] a: u8, - | ^^^^^ +LL | a: u8, + | ^^^^^ -error: Some(Exported) - --> $DIR/access_levels.rs:25:35 +error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + --> $DIR/access_levels.rs:27:13 | -LL | #[rustc_access_level] pub b: u8, - | ^^^^^^^^^ +LL | pub b: u8, + | ^^^^^^^^^ -error: Some(Exported) - --> $DIR/access_levels.rs:29:9 +error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + --> $DIR/access_levels.rs:31:9 | LL | pub enum Enum { | ^^^^^^^^^^^^^ -error: Some(Exported) - --> $DIR/access_levels.rs:30:35 - | -LL | #[rustc_access_level] A( - | ^ - -error: Some(Exported) - --> $DIR/access_levels.rs:31:39 +error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + --> $DIR/access_levels.rs:33:13 | -LL | #[rustc_access_level] Struct, - | ^^^^^^ +LL | A( + | ^ -error: Some(Exported) - --> $DIR/access_levels.rs:32:39 +error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + --> $DIR/access_levels.rs:35:17 | -LL | #[rustc_access_level] Union, - | ^^^^^ +LL | PubUnion, + | ^^^^^^^^ -error: None - --> $DIR/access_levels.rs:37:27 +error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) + --> $DIR/access_levels.rs:41:5 | -LL | #[rustc_access_level] macro_rules! none_macro { - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | macro_rules! none_macro { + | ^^^^^^^^^^^^^^^^^^^^^^^ -error: Some(Public) - --> $DIR/access_levels.rs:42:27 +error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + --> $DIR/access_levels.rs:47:5 | -LL | #[rustc_access_level] macro_rules! public_macro { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | macro_rules! public_macro { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Some(Exported) - --> $DIR/access_levels.rs:12:35 +error: Public: pub(self), Exported: pub(self), Reachable: pub, ReachableFromImplTrait: pub + --> $DIR/access_levels.rs:52:5 | -LL | #[rustc_access_level] const A: i32; - | ^^^^^^^^^^^^ +LL | pub struct ReachableStruct { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Some(Exported) - --> $DIR/access_levels.rs:13:35 +error: Public: pub(self), Exported: pub(self), Reachable: pub, ReachableFromImplTrait: pub + --> $DIR/access_levels.rs:54:9 | -LL | #[rustc_access_level] type B; - | ^^^^^^ +LL | pub a: u8, + | ^^^^^^^^^ -error: None - --> $DIR/access_levels.rs:7:35 +error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + --> $DIR/access_levels.rs:14:13 | -LL | #[rustc_access_level] static a: u8; - | ^^^^^^^^^^^^ +LL | const A: i32; + | ^^^^^^^^^^^^ -error: Some(Exported) - --> $DIR/access_levels.rs:8:35 +error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub + --> $DIR/access_levels.rs:16:13 | -LL | #[rustc_access_level] pub fn b(); - | ^^^^^^^^^^ +LL | type B; + | ^^^^^^ -error: aborting due to 20 previous errors +error: aborting due to 17 previous errors diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr index acbd0d05984f1..321ee0a36942e 100644 --- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr +++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr @@ -19,7 +19,7 @@ help: you might want to use `if let` to ignore the variant that isn't matched | LL | let x = if let Ok(x) = res { x } else { todo!() }; | ++++++++++ ++++++++++++++++++++++ -help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched +help: alternatively, you might want to use let else to handle the variant that isn't matched | LL | let Ok(x) = res else { todo!() }; | ++++++++++++++++ diff --git a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs index 12befc637c787..2a6c144350a7a 100644 --- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs +++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs @@ -1,4 +1,4 @@ -#![feature(let_chains, let_else)] +#![feature(let_chains)] fn main() { let opt = Some(1i32); diff --git a/src/test/ui/simd/intrinsic/ptr-cast.rs b/src/test/ui/simd/intrinsic/ptr-cast.rs new file mode 100644 index 0000000000000..1d13720bcd31e --- /dev/null +++ b/src/test/ui/simd/intrinsic/ptr-cast.rs @@ -0,0 +1,33 @@ +// run-pass + +#![feature(repr_simd, platform_intrinsics)] + +extern "platform-intrinsic" { + fn simd_cast_ptr(x: T) -> U; + fn simd_expose_addr(x: T) -> U; + fn simd_from_exposed_addr(x: T) -> U; +} + +#[derive(Copy, Clone)] +#[repr(simd)] +struct V([T; 2]); + +fn main() { + unsafe { + let mut foo = 4i8; + let ptr = &mut foo as *mut i8; + + let ptrs = V::<*mut i8>([ptr, core::ptr::null_mut()]); + + // change constness and type + let const_ptrs: V<*const u8> = simd_cast_ptr(ptrs); + + let exposed_addr: V = simd_expose_addr(const_ptrs); + + let from_exposed_addr: V<*mut i8> = simd_from_exposed_addr(exposed_addr); + + assert!(const_ptrs.0 == [ptr as *const u8, core::ptr::null()]); + assert!(exposed_addr.0 == [ptr as usize, 0]); + assert!(from_exposed_addr.0 == ptrs.0); + } +} diff --git a/src/test/ui/uninhabited/uninhabited-irrefutable.stderr b/src/test/ui/uninhabited/uninhabited-irrefutable.stderr index feeaa89e76f11..32f287a18188c 100644 --- a/src/test/ui/uninhabited/uninhabited-irrefutable.stderr +++ b/src/test/ui/uninhabited/uninhabited-irrefutable.stderr @@ -18,7 +18,7 @@ help: you might want to use `if let` to ignore the variant that isn't matched | LL | let (_y, _z) = if let Foo::D(_y, _z) = x { (_y, _z) } else { todo!() }; | +++++++++++++++++ +++++++++++++++++++++++++++++ -help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched +help: alternatively, you might want to use let else to handle the variant that isn't matched | LL | let Foo::D(_y, _z) = x else { todo!() }; | ++++++++++++++++ diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr index 2c107b1f7a47b..c7882963407f7 100644 --- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr +++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr @@ -122,7 +122,7 @@ help: you might want to use `if let` to ignore the variant that isn't matched | LL | let x = if let Ok(x) = x { x } else { todo!() }; | ++++++++++ ++++++++++++++++++++++ -help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched +help: alternatively, you might want to use let else to handle the variant that isn't matched | LL | let Ok(x) = x else { todo!() }; | ++++++++++++++++ diff --git a/src/test/ui/unpretty/pretty-let-else.rs b/src/test/ui/unpretty/pretty-let-else.rs index 5abfa2523b74e..b5ae529699da2 100644 --- a/src/test/ui/unpretty/pretty-let-else.rs +++ b/src/test/ui/unpretty/pretty-let-else.rs @@ -1,7 +1,7 @@ // compile-flags: -Zunpretty=hir // check-pass -#![feature(let_else)] + fn foo(x: Option) { let Some(_) = x else { panic!() }; diff --git a/src/test/ui/unpretty/pretty-let-else.stdout b/src/test/ui/unpretty/pretty-let-else.stdout index ffe1d1657aa15..35ad1cd1b1812 100644 --- a/src/test/ui/unpretty/pretty-let-else.stdout +++ b/src/test/ui/unpretty/pretty-let-else.stdout @@ -1,11 +1,11 @@ -// compile-flags: -Zunpretty=hir -// check-pass - -#![feature(let_else)] #[prelude_import] use ::std::prelude::rust_2015::*; #[macro_use] extern crate std; +// compile-flags: -Zunpretty=hir +// check-pass + + fn foo(x: Option) { diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs index 82574a8e64b0a..54c7456a2a3b0 100644 --- a/src/tools/clippy/clippy_dev/src/lib.rs +++ b/src/tools/clippy/clippy_dev/src/lib.rs @@ -1,5 +1,5 @@ #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(once_cell)] #![feature(rustc_private)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index e984254bf2919..ceaaf5c6d6ed6 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -5,7 +5,7 @@ #![feature(drain_filter)] #![feature(iter_intersperse)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(lint_reasons)] #![feature(never_type)] #![feature(once_cell)] diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 23b51ec2d0849..62da850a15e70 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1,9 +1,9 @@ #![feature(array_chunks)] #![feature(box_patterns)] #![feature(control_flow_enum)] -#![feature(let_else)] #![feature(let_chains)] #![feature(lint_reasons)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(once_cell)] #![feature(rustc_private)] #![recursion_limit = "512"] diff --git a/src/tools/clippy/tests/ui/needless_return.fixed b/src/tools/clippy/tests/ui/needless_return.fixed index 87c8fc03b3c36..695883e8dff77 100644 --- a/src/tools/clippy/tests/ui/needless_return.fixed +++ b/src/tools/clippy/tests/ui/needless_return.fixed @@ -1,7 +1,6 @@ // run-rustfix #![feature(lint_reasons)] -#![feature(let_else)] #![allow(unused)] #![allow( clippy::if_same_then_else, diff --git a/src/tools/clippy/tests/ui/needless_return.rs b/src/tools/clippy/tests/ui/needless_return.rs index 5a86e656255dd..63d9fe9ecdf8e 100644 --- a/src/tools/clippy/tests/ui/needless_return.rs +++ b/src/tools/clippy/tests/ui/needless_return.rs @@ -1,7 +1,6 @@ // run-rustfix #![feature(lint_reasons)] -#![feature(let_else)] #![allow(unused)] #![allow( clippy::if_same_then_else, diff --git a/src/tools/clippy/tests/ui/needless_return.stderr b/src/tools/clippy/tests/ui/needless_return.stderr index 83ff07638693c..cadee6e00dff2 100644 --- a/src/tools/clippy/tests/ui/needless_return.stderr +++ b/src/tools/clippy/tests/ui/needless_return.stderr @@ -1,5 +1,5 @@ error: unneeded `return` statement - --> $DIR/needless_return.rs:27:5 + --> $DIR/needless_return.rs:26:5 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` @@ -7,217 +7,217 @@ LL | return true; = note: `-D clippy::needless-return` implied by `-D warnings` error: unneeded `return` statement - --> $DIR/needless_return.rs:31:5 + --> $DIR/needless_return.rs:30:5 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:36:9 + --> $DIR/needless_return.rs:35:9 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:38:9 + --> $DIR/needless_return.rs:37:9 | LL | return false; | ^^^^^^^^^^^^^ help: remove `return`: `false` error: unneeded `return` statement - --> $DIR/needless_return.rs:44:17 + --> $DIR/needless_return.rs:43:17 | LL | true => return false, | ^^^^^^^^^^^^ help: remove `return`: `false` error: unneeded `return` statement - --> $DIR/needless_return.rs:46:13 + --> $DIR/needless_return.rs:45:13 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:53:9 + --> $DIR/needless_return.rs:52:9 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:55:16 + --> $DIR/needless_return.rs:54:16 | LL | let _ = || return true; | ^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:59:5 + --> $DIR/needless_return.rs:58:5 | LL | return the_answer!(); | ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `the_answer!()` error: unneeded `return` statement - --> $DIR/needless_return.rs:63:5 + --> $DIR/needless_return.rs:62:5 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:68:9 + --> $DIR/needless_return.rs:67:9 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:70:9 + --> $DIR/needless_return.rs:69:9 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:77:14 + --> $DIR/needless_return.rs:76:14 | LL | _ => return, | ^^^^^^ help: replace `return` with a unit value: `()` error: unneeded `return` statement - --> $DIR/needless_return.rs:86:13 + --> $DIR/needless_return.rs:85:13 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:88:14 + --> $DIR/needless_return.rs:87:14 | LL | _ => return, | ^^^^^^ help: replace `return` with a unit value: `()` error: unneeded `return` statement - --> $DIR/needless_return.rs:101:9 + --> $DIR/needless_return.rs:100:9 | LL | return String::from("test"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::from("test")` error: unneeded `return` statement - --> $DIR/needless_return.rs:103:9 + --> $DIR/needless_return.rs:102:9 | LL | return String::new(); | ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::new()` error: unneeded `return` statement - --> $DIR/needless_return.rs:125:32 + --> $DIR/needless_return.rs:124:32 | LL | bar.unwrap_or_else(|_| return) | ^^^^^^ help: replace `return` with an empty block: `{}` error: unneeded `return` statement - --> $DIR/needless_return.rs:130:13 + --> $DIR/needless_return.rs:129:13 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:132:20 + --> $DIR/needless_return.rs:131:20 | LL | let _ = || return; | ^^^^^^ help: replace `return` with an empty block: `{}` error: unneeded `return` statement - --> $DIR/needless_return.rs:138:32 + --> $DIR/needless_return.rs:137:32 | LL | res.unwrap_or_else(|_| return Foo) | ^^^^^^^^^^ help: remove `return`: `Foo` error: unneeded `return` statement - --> $DIR/needless_return.rs:147:5 + --> $DIR/needless_return.rs:146:5 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:151:5 + --> $DIR/needless_return.rs:150:5 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:156:9 + --> $DIR/needless_return.rs:155:9 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:158:9 + --> $DIR/needless_return.rs:157:9 | LL | return false; | ^^^^^^^^^^^^^ help: remove `return`: `false` error: unneeded `return` statement - --> $DIR/needless_return.rs:164:17 + --> $DIR/needless_return.rs:163:17 | LL | true => return false, | ^^^^^^^^^^^^ help: remove `return`: `false` error: unneeded `return` statement - --> $DIR/needless_return.rs:166:13 + --> $DIR/needless_return.rs:165:13 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:173:9 + --> $DIR/needless_return.rs:172:9 | LL | return true; | ^^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:175:16 + --> $DIR/needless_return.rs:174:16 | LL | let _ = || return true; | ^^^^^^^^^^^ help: remove `return`: `true` error: unneeded `return` statement - --> $DIR/needless_return.rs:179:5 + --> $DIR/needless_return.rs:178:5 | LL | return the_answer!(); | ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `the_answer!()` error: unneeded `return` statement - --> $DIR/needless_return.rs:183:5 + --> $DIR/needless_return.rs:182:5 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:188:9 + --> $DIR/needless_return.rs:187:9 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:190:9 + --> $DIR/needless_return.rs:189:9 | LL | return; | ^^^^^^^ help: remove `return` error: unneeded `return` statement - --> $DIR/needless_return.rs:197:14 + --> $DIR/needless_return.rs:196:14 | LL | _ => return, | ^^^^^^ help: replace `return` with a unit value: `()` error: unneeded `return` statement - --> $DIR/needless_return.rs:210:9 + --> $DIR/needless_return.rs:209:9 | LL | return String::from("test"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::from("test")` error: unneeded `return` statement - --> $DIR/needless_return.rs:212:9 + --> $DIR/needless_return.rs:211:9 | LL | return String::new(); | ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::new()` error: unneeded `return` statement - --> $DIR/needless_return.rs:228:5 + --> $DIR/needless_return.rs:227:5 | LL | return format!("Hello {}", "world!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `format!("Hello {}", "world!")` diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs index c3235f06779b3..c4dfbd9210e0d 100644 --- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs +++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs @@ -1,6 +1,5 @@ #![warn(clippy::semicolon_if_nothing_returned)] #![allow(clippy::redundant_closure)] -#![feature(let_else)] fn get_unit() {} diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr index 78813e7cc1c39..8d9a67585cf12 100644 --- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr +++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr @@ -1,5 +1,5 @@ error: consider adding a `;` to the last statement for consistent formatting - --> $DIR/semicolon_if_nothing_returned.rs:9:5 + --> $DIR/semicolon_if_nothing_returned.rs:8:5 | LL | println!("Hello") | ^^^^^^^^^^^^^^^^^ help: add a `;` here: `println!("Hello");` @@ -7,25 +7,25 @@ LL | println!("Hello") = note: `-D clippy::semicolon-if-nothing-returned` implied by `-D warnings` error: consider adding a `;` to the last statement for consistent formatting - --> $DIR/semicolon_if_nothing_returned.rs:13:5 + --> $DIR/semicolon_if_nothing_returned.rs:12:5 | LL | get_unit() | ^^^^^^^^^^ help: add a `;` here: `get_unit();` error: consider adding a `;` to the last statement for consistent formatting - --> $DIR/semicolon_if_nothing_returned.rs:18:5 + --> $DIR/semicolon_if_nothing_returned.rs:17:5 | LL | y = x + 1 | ^^^^^^^^^ help: add a `;` here: `y = x + 1;` error: consider adding a `;` to the last statement for consistent formatting - --> $DIR/semicolon_if_nothing_returned.rs:24:9 + --> $DIR/semicolon_if_nothing_returned.rs:23:9 | LL | hello() | ^^^^^^^ help: add a `;` here: `hello();` error: consider adding a `;` to the last statement for consistent formatting - --> $DIR/semicolon_if_nothing_returned.rs:35:9 + --> $DIR/semicolon_if_nothing_returned.rs:34:9 | LL | ptr::drop_in_place(s.as_mut_ptr()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `ptr::drop_in_place(s.as_mut_ptr());`