diff options
251 files changed, 3878 insertions, 3081 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a4ba1a5c9bf..a6d1ef33f40 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -153,6 +153,7 @@ trait ResolverAstLoweringExt { fn get_label_res(&self, id: NodeId) -> Option<NodeId>; fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes>; fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)>; + fn remap_extra_lifetime_params(&mut self, from: NodeId, to: NodeId); fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind; } @@ -213,6 +214,11 @@ impl ResolverAstLoweringExt for ResolverAstLowering { self.extra_lifetime_params_map.remove(&id).unwrap_or_default() } + fn remap_extra_lifetime_params(&mut self, from: NodeId, to: NodeId) { + let lifetimes = self.extra_lifetime_params_map.remove(&from).unwrap_or_default(); + self.extra_lifetime_params_map.insert(to, lifetimes); + } + fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind { self.builtin_macro_kinds.get(&def_id).copied().unwrap_or(MacroKind::Bang) } @@ -1089,6 +1095,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // constructing the HIR for `impl bounds...` and then lowering that. let impl_trait_node_id = self.next_node_id(); + // Shift `impl Trait` lifetime captures from the associated type bound's + // node id to the opaque node id, so that the opaque can actually use + // these lifetime bounds. + self.resolver + .remap_extra_lifetime_params(constraint.id, impl_trait_node_id); self.with_dyn_type_scope(false, |this| { let node_id = this.next_node_id(); diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index b8cd94e5422..1049e7a8bbe 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -2249,7 +2249,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { } pub(crate) fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { - self.universe_causes[&universe].clone() + // Query canonicalization can create local superuniverses (for example in + // `InferCtx::query_response_substitution_guess`), but they don't have an associated + // `UniverseInfo` explaining why they were created. + // This can cause ICEs if these causes are accessed in diagnostics, for example in issue + // #114907 where this happens via liveness and dropck outlives results. + // Therefore, we return a default value in case that happens, which should at worst emit a + // suboptimal error, instead of the ICE. + self.universe_causes.get(&universe).cloned().unwrap_or_else(|| UniverseInfo::other()) } /// Tries to find the terminator of the loop in which the region 'r' resides. diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 16f5e68a06f..b7adc314f07 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -9,7 +9,7 @@ use rustc_span::Span; use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput}; use rustc_trait_selection::traits::ObligationCause; -use crate::diagnostics::{ToUniverseInfo, UniverseInfo}; +use crate::diagnostics::ToUniverseInfo; use super::{Locations, NormalizeLocation, TypeChecker}; @@ -46,13 +46,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.push_region_constraints(locations, category, data); } + // If the query has created new universes and errors are going to be emitted, register the + // cause of these new universes for improved diagnostics. let universe = self.infcx.universe(); - - if old_universe != universe { - let universe_info = match error_info { - Some(error_info) => error_info.to_universe_info(old_universe), - None => UniverseInfo::other(), - }; + if old_universe != universe && let Some(error_info) = error_info { + let universe_info = error_info.to_universe_info(old_universe); for u in (old_universe + 1)..=universe { self.borrowck_context.constraints.universe_causes.insert(u, universe_info.clone()); } @@ -69,15 +67,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { where T: TypeFoldable<TyCtxt<'tcx>>, { - let old_universe = self.infcx.universe(); - let (instantiated, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical); - - for u in (old_universe + 1)..=self.infcx.universe() { - self.borrowck_context.constraints.universe_causes.insert(u, UniverseInfo::other()); - } - instantiated } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 3004291c3e7..28286243e82 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -163,10 +163,6 @@ pub(crate) fn type_check<'mir, 'tcx>( debug!(?normalized_inputs_and_output); - for u in ty::UniverseIndex::ROOT..=infcx.universe() { - constraints.universe_causes.insert(u, UniverseInfo::other()); - } - let mut borrowck_context = BorrowCheckContext { universal_regions, location_table, diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index a82d2c5771a..f33075a8879 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -367,7 +367,7 @@ impl<'a> LlvmArchiveBuilder<'a> { match addition { Addition::File { path, name_in_archive } => { let path = CString::new(path.to_str().unwrap())?; - let name = CString::new(name_in_archive.clone())?; + let name = CString::new(name_in_archive.as_bytes())?; members.push(llvm::LLVMRustArchiveMemberNew( path.as_ptr(), name.as_ptr(), diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index b2d28cef899..c1d3392386c 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -441,7 +441,7 @@ fn thin_lto( for (i, (name, buffer)) in modules.into_iter().enumerate() { info!("local module: {} - {}", i, name); - let cname = CString::new(name.clone()).unwrap(); + let cname = CString::new(name.as_bytes()).unwrap(); thin_modules.push(llvm::ThinLTOModule { identifier: cname.as_ptr(), data: buffer.data().as_ptr(), diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index a016bfa5cf8..ca66c4cfb63 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -254,6 +254,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } /// Find the wrapped inner type of a transparent wrapper. + /// Must not be called on 1-ZST (as they don't have a uniquely defined "wrapped field"). fn unfold_transparent(&self, layout: TyAndLayout<'tcx>) -> TyAndLayout<'tcx> { match layout.ty.kind() { ty::Adt(adt_def, _) if adt_def.repr().transparent() => { @@ -263,11 +264,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let field = layout.field(self, idx); if field.is_1zst() { None } else { Some(field) } }); - let Some(first) = non_1zst_fields.next() else { - // All fields are 1-ZST, so this is basically the same as `()`. - // (We still also compare the `PassMode`, so if this target does something strange with 1-ZST there, we'll know.) - return self.layout_of(self.tcx.types.unit).unwrap(); - }; + let first = non_1zst_fields.next().expect("`unfold_transparent` called on 1-ZST"); assert!( non_1zst_fields.next().is_none(), "more than one non-1-ZST field in a transparent type" @@ -289,17 +286,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { caller_layout: TyAndLayout<'tcx>, callee_layout: TyAndLayout<'tcx>, ) -> bool { - fn primitive_abi_compat(a1: abi::Primitive, a2: abi::Primitive) -> bool { - match (a1, a2) { - // For integers, ignore the sign. - (abi::Primitive::Int(int_ty1, _sign1), abi::Primitive::Int(int_ty2, _sign2)) => { - int_ty1 == int_ty2 - } - // For everything else we require full equality. - _ => a1 == a2, - } - } - if caller_layout.ty == callee_layout.ty { // Fast path: equal types are definitely compatible. return true; @@ -308,27 +294,40 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match (caller_layout.abi, callee_layout.abi) { // If both sides have Scalar/Vector/ScalarPair ABI, we can easily directly compare them. // Different valid ranges are okay (the validity check will complain if this leads to - // invalid transmutes). + // invalid transmutes). Different signs are *not* okay on some targets (e.g. `extern + // "C"` on `s390x` where small integers are passed zero/sign-extended in large + // registers), so we generally reject them to increase portability. + // NOTE: this is *not* a stable guarantee! It just reflects a property of our current + // ABIs. It's also fragile; the same pair of types might be considered ABI-compatible + // when used directly by-value but not considered compatible as a struct field or array + // element. (abi::Abi::Scalar(caller), abi::Abi::Scalar(callee)) => { - primitive_abi_compat(caller.primitive(), callee.primitive()) + caller.primitive() == callee.primitive() } ( abi::Abi::Vector { element: caller_element, count: caller_count }, abi::Abi::Vector { element: callee_element, count: callee_count }, ) => { - primitive_abi_compat(caller_element.primitive(), callee_element.primitive()) + caller_element.primitive() == callee_element.primitive() && caller_count == callee_count } (abi::Abi::ScalarPair(caller1, caller2), abi::Abi::ScalarPair(callee1, callee2)) => { - primitive_abi_compat(caller1.primitive(), callee1.primitive()) - && primitive_abi_compat(caller2.primitive(), callee2.primitive()) + caller1.primitive() == callee1.primitive() + && caller2.primitive() == callee2.primitive() } (abi::Abi::Aggregate { .. }, abi::Abi::Aggregate { .. }) => { - // Aggregates are compatible only if they newtype-wrap the same type. + // Aggregates are compatible only if they newtype-wrap the same type, or if they are both 1-ZST. + // (The latter part is needed to ensure e.g. that `struct Zst` is compatible with `struct Wrap((), Zst)`.) // This is conservative, but also means that our check isn't quite so heavily dependent on the `PassMode`, // which means having ABI-compatibility on one target is much more likely to imply compatibility for other targets. - self.unfold_transparent(caller_layout).ty - == self.unfold_transparent(callee_layout).ty + if caller_layout.is_1zst() || callee_layout.is_1zst() { + // If either is a 1-ZST, both must be. + caller_layout.is_1zst() && callee_layout.is_1zst() + } else { + // Neither is a 1-ZST, so we can check what they are wrapping. + self.unfold_transparent(caller_layout).ty + == self.unfold_transparent(callee_layout).ty + } } // What remains is `Abi::Uninhabited` (which can never be passed anyway) and // mismatching ABIs, that should all be rejected. diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 2ec509b9118..e82b0f6d496 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -273,7 +273,7 @@ cfg_if! { pub use std::cell::RefMut as MappedWriteGuard; pub use std::cell::RefMut as MappedLockGuard; - pub use std::cell::OnceCell; + pub use std::cell::OnceCell as OnceLock; use std::cell::RefCell as InnerRwLock; @@ -327,7 +327,7 @@ cfg_if! { pub use parking_lot::MappedMutexGuard as MappedLockGuard; - pub use std::sync::OnceLock as OnceCell; + pub use std::sync::OnceLock; pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64}; diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 2daf591bd65..89c44c6ec8a 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -608,6 +608,7 @@ E0794: include_str!("./error_codes/E0794.md"), // E0420, // merged into 532 // E0421, // merged into 531 // E0427, // merged into 530 +// E0445, // merged into 446 and type privacy lints // E0456, // plugin `..` is not available for triple `..` // E0465, // removed: merged with E0464 // E0467, // removed diff --git a/compiler/rustc_error_codes/src/error_codes/E0445.md b/compiler/rustc_error_codes/src/error_codes/E0445.md index e6a28a9c2c4..d47393194c5 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0445.md +++ b/compiler/rustc_error_codes/src/error_codes/E0445.md @@ -1,10 +1,10 @@ -A private trait was used on a public type parameter bound. +#### Note: this error code is no longer emitted by the compiler. -Erroneous code examples: +A private trait was used on a public type parameter bound. -```compile_fail,E0445 -#![deny(private_in_public)] +Previously erroneous code examples: +``` trait Foo { fn dummy(&self) { } } diff --git a/compiler/rustc_error_codes/src/error_codes/E0446.md b/compiler/rustc_error_codes/src/error_codes/E0446.md index 6ec47c4962c..ebbd83c683c 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0446.md +++ b/compiler/rustc_error_codes/src/error_codes/E0446.md @@ -1,16 +1,16 @@ -A private type was used in a public type signature. +A private type or trait was used in a public associated type signature. Erroneous code example: ```compile_fail,E0446 -#![deny(private_in_public)] -struct Bar(u32); - -mod foo { - use crate::Bar; - pub fn bar() -> Bar { // error: private type in public interface - Bar(0) - } +struct Bar; + +pub trait PubTr { + type Alias; +} + +impl PubTr for u8 { + type Alias = Bar; // error private type in public interface } fn main() {} @@ -22,13 +22,14 @@ This is done by using pub(crate) or pub(in crate::my_mod::etc) Example: ``` -struct Bar(u32); +struct Bar; + +pub(crate) trait PubTr { // only public to crate root + type Alias; +} -mod foo { - use crate::Bar; - pub(crate) fn bar() -> Bar { // only public to crate root - Bar(0) - } +impl PubTr for u8 { + type Alias = Bar; } fn main() {} @@ -38,12 +39,15 @@ The other way to solve this error is to make the private type public. Example: ``` -pub struct Bar(u32); // we set the Bar type public -mod foo { - use crate::Bar; - pub fn bar() -> Bar { // ok! - Bar(0) - } + +pub struct Bar; // we set the Bar trait public + +pub trait PubTr { + type Alias; +} + +impl PubTr for u8 { + type Alias = Bar; } fn main() {} diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index c2fe942fe37..9bb1a6a2b14 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -55,6 +55,8 @@ use std::num::NonZeroUsize; use std::panic; use std::path::{Path, PathBuf}; +// Used by external projects such as `rust-gpu`. +// See https://github.com/rust-lang/rust/pull/115393. pub use termcolor::{Color, ColorSpec, WriteColor}; pub mod annotate_snippet_emitter_writer; diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index b1f74643b69..afcf30d0b29 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -54,7 +54,7 @@ declare_features! ( /// instead of just the platforms on which it is the C ABI. (accepted, abi_sysv64, "1.24.0", Some(36167), None), /// Allows using the `thiscall` ABI. - (accepted, abi_thiscall, "1.19.0", None, None), + (accepted, abi_thiscall, "1.73.0", None, None), /// Allows using ADX intrinsics from `core::arch::{x86, x86_64}`. (accepted, adx_target_feature, "1.61.0", Some(44839), None), /// Allows explicit discriminants on non-unit enum variants. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 0bfd62d68b2..a9b25a390b3 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3729,6 +3729,8 @@ impl<'hir> Node<'hir> { Node::Lifetime(lt) => Some(lt.ident), Node::GenericParam(p) => Some(p.name.ident()), Node::TypeBinding(b) => Some(b.ident), + Node::PatField(f) => Some(f.ident), + Node::ExprField(f) => Some(f.ident), Node::Param(..) | Node::AnonConst(..) | Node::ConstBlock(..) @@ -3737,8 +3739,6 @@ impl<'hir> Node<'hir> { | Node::Block(..) | Node::Ctor(..) | Node::Pat(..) - | Node::PatField(..) - | Node::ExprField(..) | Node::Arm(..) | Node::Local(..) | Node::Crate(..) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 668763f9bf6..7a6856fb1f4 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -910,19 +910,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) -> Ty<'tcx> { let tcx = self.tcx(); let args = self.ast_path_args_for_ty(span, did, item_segment); - let ty = tcx.at(span).type_of(did); - if let DefKind::TyAlias { lazy } = tcx.def_kind(did) - && (lazy || ty.skip_binder().has_opaque_types()) - { - // Type aliases referring to types that contain opaque types (but aren't just directly - // referencing a single opaque type) as well as those defined in crates that have the + if let DefKind::TyAlias { lazy: true } = tcx.def_kind(did) { + // Type aliases defined in crates that have the // feature `lazy_type_alias` enabled get encoded as a type alias that normalization will // then actually instantiate the where bounds of. let alias_ty = tcx.mk_alias_ty(did, args); Ty::new_alias(tcx, ty::Weak, alias_ty) } else { - ty.instantiate(tcx, args) + let ty = tcx.at(span).type_of(did); + if ty.skip_binder().has_opaque_types() { + // Type aliases referring to types that contain opaque types (but aren't just directly + // referencing a single opaque type) get encoded as a type alias that normalization will + // then actually instantiate the where bounds of. + let alias_ty = tcx.mk_alias_ty(did, args); + Ty::new_alias(tcx, ty::Weak, alias_ty) + } else { + ty.instantiate(tcx, args) + } } } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 334e0541c76..01e40c62a8b 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -38,6 +38,7 @@ use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName; use rustc_trait_selection::traits::ObligationCtxt; use std::iter; +use std::ops::Bound; mod generics_of; mod item_bounds; @@ -1144,15 +1145,15 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig< } Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => { - let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id)).instantiate_identity(); + let adt_def_id = tcx.hir().get_parent_item(hir_id).def_id.to_def_id(); + let ty = tcx.type_of(adt_def_id).instantiate_identity(); let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).instantiate_identity()); - ty::Binder::dummy(tcx.mk_fn_sig( - inputs, - ty, - false, - hir::Unsafety::Normal, - abi::Abi::Rust, - )) + // constructors for structs with `layout_scalar_valid_range` are unsafe to call + let safety = match tcx.layout_scalar_valid_range(adt_def_id) { + (Bound::Unbounded, Bound::Unbounded) => hir::Unsafety::Normal, + _ => hir::Unsafety::Unsafe, + }; + ty::Binder::dummy(tcx.mk_fn_sig(inputs, ty, false, safety, abi::Abi::Rust)) } Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => { diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index 372539d73b1..445f68160d2 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -266,12 +266,10 @@ impl<T> Trait<T> for X { } } } - (ty::FnPtr(_), ty::FnDef(def, _)) - if let hir::def::DefKind::Fn = tcx.def_kind(def) => { - diag.note( - "when the arguments and return types match, functions can be coerced \ - to function pointers", - ); + (ty::FnPtr(sig), ty::FnDef(def_id, _)) | (ty::FnDef(def_id, _), ty::FnPtr(sig)) => { + if tcx.fn_sig(*def_id).skip_binder().unsafety() < sig.unsafety() { + diag.note("unsafe functions cannot be coerced into safe function pointers"); + } } _ => {} } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index c8b1ba5694e..9fcaf643179 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -8,7 +8,7 @@ use rustc_borrowck as mir_borrowck; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::parallel; use rustc_data_structures::steal::Steal; -use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal}; +use rustc_data_structures::sync::{Lrc, OnceLock, WorkerLocal}; use rustc_errors::PResult; use rustc_expand::base::{ExtCtxt, LintStoreExpand}; use rustc_feature::Features; @@ -689,7 +689,7 @@ pub fn create_global_ctxt<'tcx>( lint_store: Lrc<LintStore>, dep_graph: DepGraph, untracked: Untracked, - gcx_cell: &'tcx OnceCell<GlobalCtxt<'tcx>>, + gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>, arena: &'tcx WorkerLocal<Arena<'tcx>>, hir_arena: &'tcx WorkerLocal<rustc_hir::Arena<'tcx>>, ) -> &'tcx GlobalCtxt<'tcx> { diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index fc71c6c7e9a..2db7aa0e367 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -7,7 +7,7 @@ use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::CodegenResults; use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::{AppendOnlyIndexVec, Lrc, OnceCell, RwLock, WorkerLocal}; +use rustc_data_structures::sync::{AppendOnlyIndexVec, Lrc, OnceLock, RwLock, WorkerLocal}; use rustc_hir::def_id::{StableCrateId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::Definitions; use rustc_incremental::DepGraphFuture; @@ -78,7 +78,7 @@ impl<T> Default for Query<T> { pub struct Queries<'tcx> { compiler: &'tcx Compiler, - gcx_cell: OnceCell<GlobalCtxt<'tcx>>, + gcx_cell: OnceLock<GlobalCtxt<'tcx>>, arena: WorkerLocal<Arena<'tcx>>, hir_arena: WorkerLocal<rustc_hir::Arena<'tcx>>, @@ -93,7 +93,7 @@ impl<'tcx> Queries<'tcx> { pub fn new(compiler: &'tcx Compiler) -> Queries<'tcx> { Queries { compiler, - gcx_cell: OnceCell::new(), + gcx_cell: OnceLock::new(), arena: WorkerLocal::new(|_| Arena::default()), hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()), parse: Default::default(), diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 211ea8f4347..d102e3a6c15 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -228,6 +228,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> }) => self.check_id(closure_id), _ => {} } + lint_callback!(self, check_expr_post, e); } fn visit_generic_arg(&mut self, arg: &'a ast::GenericArg) { diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index e578f09b58f..84434d585d3 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -500,6 +500,11 @@ fn register_builtins(store: &mut LintStore) { "converted into hard error, see issue #82523 \ <https://github.com/rust-lang/rust/issues/82523> for more information", ); + store.register_removed( + "private_in_public", + "replaced with another group of lints, see RFC \ + <https://rust-lang.github.io/rfcs/2145-type-privacy.html> for more information", + ); } fn register_internals(store: &mut LintStore) { diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index 16964565b01..fca0eeeecc4 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -153,6 +153,7 @@ macro_rules! early_lint_methods { fn check_pat(a: &ast::Pat); fn check_pat_post(a: &ast::Pat); fn check_expr(a: &ast::Expr); + fn check_expr_post(a: &ast::Expr); fn check_ty(a: &ast::Ty); fn check_generic_arg(a: &ast::GenericArg); fn check_generic_param(a: &ast::GenericParam); diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 6041f80753b..39e6fb805ae 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -955,11 +955,14 @@ declare_lint! { pub struct UnusedParens { with_self_ty_parens: bool, + /// `1 as (i32) < 2` parses to ExprKind::Lt + /// `1 as i32 < 2` parses to i32::<2[missing angle bracket] + parens_in_cast_in_lt: Vec<ast::NodeId>, } impl UnusedParens { pub fn new() -> Self { - Self { with_self_ty_parens: false } + Self { with_self_ty_parens: false, parens_in_cast_in_lt: Vec::new() } } } @@ -1055,6 +1058,14 @@ impl UnusedParens { impl EarlyLintPass for UnusedParens { #[inline] fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { + if let ExprKind::Binary(op, lhs, _rhs) = &e.kind && + (op.node == ast::BinOpKind::Lt || op.node == ast::BinOpKind::Shl) && + let ExprKind::Cast(_expr, ty) = &lhs.kind && + let ast::TyKind::Paren(_) = &ty.kind + { + self.parens_in_cast_in_lt.push(ty.id); + } + match e.kind { ExprKind::Let(ref pat, _, _) | ExprKind::ForLoop(ref pat, ..) => { self.check_unused_parens_pat(cx, pat, false, false, (true, true)); @@ -1101,6 +1112,17 @@ impl EarlyLintPass for UnusedParens { <Self as UnusedDelimLint>::check_expr(self, cx, e) } + fn check_expr_post(&mut self, _cx: &EarlyContext<'_>, e: &ast::Expr) { + if let ExprKind::Binary(op, lhs, _rhs) = &e.kind && + (op.node == ast::BinOpKind::Lt || op.node == ast::BinOpKind::Shl) && + let ExprKind::Cast(_expr, ty) = &lhs.kind && + let ast::TyKind::Paren(_) = &ty.kind + { + let id = self.parens_in_cast_in_lt.pop().expect("check_expr and check_expr_post must balance"); + assert_eq!(id, ty.id, "check_expr, check_ty, and check_expr_post are called, in that order, by the visitor"); + } + } + fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) { use ast::{Mutability, PatKind::*}; let keep_space = (false, false); @@ -1141,6 +1163,11 @@ impl EarlyLintPass for UnusedParens { } fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) { + if let ast::TyKind::Paren(_) = ty.kind && + Some(&ty.id) == self.parens_in_cast_in_lt.last() + { + return; + } match &ty.kind { ast::TyKind::Array(_, len) => { self.check_unused_delims_expr( diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 0aa37642b74..7e745de4f1a 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -983,44 +983,6 @@ declare_lint! { } declare_lint! { - /// The `private_in_public` lint detects private items in public - /// interfaces not caught by the old implementation. - /// - /// ### Example - /// - /// ```rust - /// # #![allow(unused)] - /// struct SemiPriv; - /// - /// mod m1 { - /// struct Priv; - /// impl super::SemiPriv { - /// pub fn f(_: Priv) {} - /// } - /// } - /// # fn main() {} - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// The visibility rules are intended to prevent exposing private items in - /// public interfaces. This is a [future-incompatible] lint to transition - /// this to a hard error in the future. See [issue #34537] for more - /// details. - /// - /// [issue #34537]: https://github.com/rust-lang/rust/issues/34537 - /// [future-incompatible]: ../index.md#future-incompatible-lints - pub PRIVATE_IN_PUBLIC, - Warn, - "detect private items in public interfaces not caught by the old implementation", - @future_incompatible = FutureIncompatibleInfo { - reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>", - }; -} - -declare_lint! { /// The `invalid_alignment` lint detects dereferences of misaligned pointers during /// constant evaluation. /// @@ -3415,7 +3377,6 @@ declare_lint_pass! { PATTERNS_IN_FNS_WITHOUT_BODY, POINTER_STRUCTURAL_MATCH, PRIVATE_BOUNDS, - PRIVATE_IN_PUBLIC, PRIVATE_INTERFACES, PROC_MACRO_BACK_COMPAT, PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, @@ -4334,9 +4295,7 @@ declare_lint! { /// ### Example /// /// ```rust,compile_fail - /// # #![feature(type_privacy_lints)] /// # #![allow(unused)] - /// # #![allow(private_in_public)] /// #![deny(private_interfaces)] /// struct SemiPriv; /// @@ -4357,9 +4316,8 @@ declare_lint! { /// Having something private in primary interface guarantees that /// the item will be unusable from outer modules due to type privacy. pub PRIVATE_INTERFACES, - Allow, + Warn, "private type in primary interface of an item", - @feature_gate = sym::type_privacy_lints; } declare_lint! { @@ -4370,8 +4328,6 @@ declare_lint! { /// ### Example /// /// ```rust,compile_fail - /// # #![feature(type_privacy_lints)] - /// # #![allow(private_in_public)] /// # #![allow(unused)] /// #![deny(private_bounds)] /// @@ -4389,9 +4345,8 @@ declare_lint! { /// Having private types or traits in item bounds makes it less clear what interface /// the item actually provides. pub PRIVATE_BOUNDS, - Allow, + Warn, "private type in secondary interface of an item", - @feature_gate = sym::type_privacy_lints; } declare_lint! { diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 4302b161833..f606fa483ca 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -252,7 +252,10 @@ fn main() { } else if target.contains("windows-gnu") { println!("cargo:rustc-link-lib=shell32"); println!("cargo:rustc-link-lib=uuid"); - } else if target.contains("haiku") || target.contains("darwin") { + } else if target.contains("haiku") + || target.contains("darwin") + || (is_crossed && (target.contains("dragonfly") || target.contains("solaris"))) + { println!("cargo:rustc-link-lib=z"); } else if target.contains("netbsd") { println!("cargo:rustc-link-lib=z"); diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 87373d99743..99fef84931e 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -42,6 +42,6 @@ pub mod locator; pub use fs::{emit_wrapper_file, METADATA_FILENAME}; pub use native_libs::find_native_static_library; -pub use rmeta::{encode_metadata, EncodedMetadata, METADATA_HEADER}; +pub use rmeta::{encode_metadata, rendered_const, EncodedMetadata, METADATA_HEADER}; fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 05e608c0d1a..43c1d321f81 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -9,7 +9,7 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::owned_slice::OwnedSlice; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::{AppendOnlyVec, AtomicBool, Lock, Lrc, OnceCell}; +use rustc_data_structures::sync::{AppendOnlyVec, AtomicBool, Lock, Lrc, OnceLock}; use rustc_data_structures::unhash::UnhashMap; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro}; @@ -93,7 +93,7 @@ pub(crate) struct CrateMetadata { /// For every definition in this crate, maps its `DefPathHash` to its `DefIndex`. def_path_hash_map: DefPathHashMapRef<'static>, /// Likewise for ExpnHash. - expn_hash_map: OnceCell<UnhashMap<ExpnHash, ExpnIndex>>, + expn_hash_map: OnceLock<UnhashMap<ExpnHash, ExpnIndex>>, /// Used for decoding interpret::AllocIds in a cached & thread-safe manner. alloc_decoding_state: AllocDecodingState, /// Caches decoded `DefKey`s. diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index ecb15c41eef..4f4351633a2 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -17,8 +17,8 @@ use rustc_hir::def_id::{ CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE, }; use rustc_hir::definitions::DefPathData; -use rustc_hir::intravisit; use rustc_hir::lang_items::LangItem; +use rustc_hir_pretty::id_to_string; use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols::{ @@ -1615,7 +1615,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs); let body_id = tcx.hir().maybe_body_owned_by(def_id); if let Some(body_id) = body_id { - let const_data = self.encode_rendered_const_for_body(body_id); + let const_data = rendered_const(self.tcx, body_id); record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data); } } @@ -1683,14 +1683,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } - fn encode_rendered_const_for_body(&mut self, body_id: hir::BodyId) -> String { - let hir = self.tcx.hir(); - let body = hir.body(body_id); - rustc_hir_pretty::to_string(&(&hir as &dyn intravisit::Map<'_>), |s| { - s.print_expr(&body.value) - }) - } - #[instrument(level = "debug", skip(self))] fn encode_info_for_macro(&mut self, def_id: LocalDefId) { let tcx = self.tcx; @@ -2292,3 +2284,97 @@ pub fn provide(providers: &mut Providers) { ..*providers } } + +/// Build a textual representation of an unevaluated constant expression. +/// +/// If the const expression is too complex, an underscore `_` is returned. +/// For const arguments, it's `{ _ }` to be precise. +/// This means that the output is not necessarily valid Rust code. +/// +/// Currently, only +/// +/// * literals (optionally with a leading `-`) +/// * unit `()` +/// * blocks (`{ … }`) around simple expressions and +/// * paths without arguments +/// +/// are considered simple enough. Simple blocks are included since they are +/// necessary to disambiguate unit from the unit type. +/// This list might get extended in the future. +/// +/// Without this censoring, in a lot of cases the output would get too large +/// and verbose. Consider `match` expressions, blocks and deeply nested ADTs. +/// Further, private and `doc(hidden)` fields of structs would get leaked +/// since HIR datatypes like the `body` parameter do not contain enough +/// semantic information for this function to be able to hide them – +/// at least not without significant performance overhead. +/// +/// Whenever possible, prefer to evaluate the constant first and try to +/// use a different method for pretty-printing. Ideally this function +/// should only ever be used as a fallback. +pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: hir::BodyId) -> String { + let hir = tcx.hir(); + let value = &hir.body(body).value; + + #[derive(PartialEq, Eq)] + enum Classification { + Literal, + Simple, + Complex, + } + + use Classification::*; + + fn classify(expr: &hir::Expr<'_>) -> Classification { + match &expr.kind { + hir::ExprKind::Unary(hir::UnOp::Neg, expr) => { + if matches!(expr.kind, hir::ExprKind::Lit(_)) { Literal } else { Complex } + } + hir::ExprKind::Lit(_) => Literal, + hir::ExprKind::Tup([]) => Simple, + hir::ExprKind::Block(hir::Block { stmts: [], expr: Some(expr), .. }, _) => { + if classify(expr) == Complex { Complex } else { Simple } + } + // Paths with a self-type or arguments are too “complex” following our measure since + // they may leak private fields of structs (with feature `adt_const_params`). + // Consider: `<Self as Trait<{ Struct { private: () } }>>::CONSTANT`. + // Paths without arguments are definitely harmless though. + hir::ExprKind::Path(hir::QPath::Resolved(_, hir::Path { segments, .. })) => { + if segments.iter().all(|segment| segment.args.is_none()) { Simple } else { Complex } + } + // FIXME: Claiming that those kinds of QPaths are simple is probably not true if the Ty + // contains const arguments. Is there a *concise* way to check for this? + hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => Simple, + // FIXME: Can they contain const arguments and thus leak private struct fields? + hir::ExprKind::Path(hir::QPath::LangItem(..)) => Simple, + _ => Complex, + } + } + + let classification = classify(value); + + if classification == Literal + && !value.span.from_expansion() + && let Ok(snippet) = tcx.sess.source_map().span_to_snippet(value.span) { + // For literals, we avoid invoking the pretty-printer and use the source snippet instead to + // preserve certain stylistic choices the user likely made for the sake legibility like + // + // * hexadecimal notation + // * underscores + // * character escapes + // + // FIXME: This passes through `-/*spacer*/0` verbatim. + snippet + } else if classification == Simple { + // Otherwise we prefer pretty-printing to get rid of extraneous whitespace, comments and + // other formatting artifacts. + id_to_string(&hir, body.hir_id) + } else if tcx.def_kind(hir.body_owner_def_id(body).to_def_id()) == DefKind::AnonConst { + // FIXME: Omit the curly braces if the enclosing expression is an array literal + // with a repeated element (an `ExprKind::Repeat`) as in such case it + // would not actually need any disambiguation. + "{ _ }".to_owned() + } else { + "_".to_owned() + } +} diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 1f68e83e0ab..71269779d42 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -42,7 +42,7 @@ pub use decoder::provide_extern; use decoder::DecodeContext; pub(crate) use decoder::{CrateMetadata, CrateNumMap, MetadataBlob}; use encoder::EncodeContext; -pub use encoder::{encode_metadata, EncodedMetadata}; +pub use encoder::{encode_metadata, rendered_const, EncodedMetadata}; use rustc_span::hygiene::SyntaxContextData; mod decoder; diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 81de70c03d4..3e8f07ed233 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1226,7 +1226,6 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { tcx.stable_crate_id(LOCAL_CRATE).hash_stable(&mut hcx, &mut stable_hasher); // Hash visibility information since it does not appear in HIR. resolutions.visibilities.hash_stable(&mut hcx, &mut stable_hasher); - resolutions.has_pub_restricted.hash_stable(&mut hcx, &mut stable_hasher); stable_hasher.finish() }); diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index 0ad17e819c7..70d8f3bd54b 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph; use rustc_data_structures::graph::dominators::{dominators, Dominators}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::OnceCell; +use rustc_data_structures::sync::OnceLock; use rustc_index::{IndexSlice, IndexVec}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use smallvec::SmallVec; @@ -23,11 +23,11 @@ pub type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[Option<u1 #[derive(Clone, Default, Debug)] struct Cache { - predecessors: OnceCell<Predecessors>, - switch_sources: OnceCell<SwitchSources>, - is_cyclic: OnceCell<bool>, - reverse_postorder: OnceCell<Vec<BasicBlock>>, - dominators: OnceCell<Dominators<BasicBlock>>, + predecessors: OnceLock<Predecessors>, + switch_sources: OnceLock<SwitchSources>, + is_cyclic: OnceLock<bool>, + reverse_postorder: OnceLock<Vec<BasicBlock>>, + dominators: OnceLock<Dominators<BasicBlock>>, } impl<'tcx> BasicBlocks<'tcx> { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 283c52a5538..1fdc4f7500f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -162,8 +162,6 @@ pub struct ResolverOutputs { #[derive(Debug)] pub struct ResolverGlobalCtxt { pub visibilities: FxHashMap<LocalDefId, Visibility>, - /// This field is used to decide whether we should make `PRIVATE_IN_PUBLIC` a hard error. - pub has_pub_restricted: bool, /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. pub expn_that_defined: FxHashMap<LocalDefId, ExpnId>, pub effective_visibilities: EffectiveVisibilities, diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index a5c86e31a29..1e0a47ead8c 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -159,52 +159,44 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } ExprKind::LogicalOp { op, lhs, rhs } => { - // And: - // - // [block: If(lhs)] -true-> [else_block: dest = (rhs)] - // | (false) - // [shortcircuit_block: dest = false] - // - // Or: - // - // [block: If(lhs)] -false-> [else_block: dest = (rhs)] - // | (true) - // [shortcircuit_block: dest = true] - - let (shortcircuit_block, mut else_block, join_block) = ( - this.cfg.start_new_block(), - this.cfg.start_new_block(), - this.cfg.start_new_block(), - ); - - let lhs = unpack!(block = this.as_local_operand(block, &this.thir[lhs])); - let blocks = match op { - LogicalOp::And => (else_block, shortcircuit_block), - LogicalOp::Or => (shortcircuit_block, else_block), + let condition_scope = this.local_scope(); + let source_info = this.source_info(expr.span); + // We first evaluate the left-hand side of the predicate ... + let (then_block, else_block) = + this.in_if_then_scope(condition_scope, expr.span, |this| { + this.then_else_break( + block, + &this.thir[lhs], + Some(condition_scope), + condition_scope, + source_info, + ) + }); + let (short_circuit, continuation, constant) = match op { + LogicalOp::And => (else_block, then_block, false), + LogicalOp::Or => (then_block, else_block, true), }; - let term = TerminatorKind::if_(lhs, blocks.0, blocks.1); - this.cfg.terminate(block, source_info, term); - + // At this point, the control flow splits into a short-circuiting path + // and a continuation path. + // - If the operator is `&&`, passing `lhs` leads to continuation of evaluation on `rhs`; + // failing it leads to the short-circuting path which assigns `false` to the place. + // - If the operator is `||`, failing `lhs` leads to continuation of evaluation on `rhs`; + // passing it leads to the short-circuting path which assigns `true` to the place. this.cfg.push_assign_constant( - shortcircuit_block, + short_circuit, source_info, destination, Constant { - span: expr_span, + span: expr.span, user_ty: None, - literal: match op { - LogicalOp::And => ConstantKind::from_bool(this.tcx, false), - LogicalOp::Or => ConstantKind::from_bool(this.tcx, true), - }, + literal: ConstantKind::from_bool(this.tcx, constant), }, ); - this.cfg.goto(shortcircuit_block, source_info, join_block); - - let rhs = unpack!(else_block = this.as_local_operand(else_block, &this.thir[rhs])); - this.cfg.push_assign(else_block, source_info, destination, Rvalue::Use(rhs)); - this.cfg.goto(else_block, source_info, join_block); - - join_block.unit() + let rhs = unpack!(this.expr_into_dest(destination, continuation, &this.thir[rhs])); + let target = this.cfg.start_new_block(); + this.cfg.goto(rhs, source_info, target); + this.cfg.goto(short_circuit, source_info, target); + target.unit() } ExprKind::Loop { body } => { // [block] diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 3c450740712..5ec216cea61 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -64,6 +64,43 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { rhs_then_block.unit() } + ExprKind::LogicalOp { op: LogicalOp::Or, lhs, rhs } => { + let local_scope = this.local_scope(); + let (lhs_success_block, failure_block) = + this.in_if_then_scope(local_scope, expr_span, |this| { + this.then_else_break( + block, + &this.thir[lhs], + temp_scope_override, + local_scope, + variable_source_info, + ) + }); + let rhs_success_block = unpack!(this.then_else_break( + failure_block, + &this.thir[rhs], + temp_scope_override, + break_scope, + variable_source_info, + )); + this.cfg.goto(lhs_success_block, variable_source_info, rhs_success_block); + rhs_success_block.unit() + } + ExprKind::Unary { op: UnOp::Not, arg } => { + let local_scope = this.local_scope(); + let (success_block, failure_block) = + this.in_if_then_scope(local_scope, expr_span, |this| { + this.then_else_break( + block, + &this.thir[arg], + temp_scope_override, + local_scope, + variable_source_info, + ) + }); + this.break_for_else(success_block, break_scope, variable_source_info); + failure_block.unit() + } ExprKind::Scope { region_scope, lint_level, value } => { let region_scope = (region_scope, this.source_info(expr_span)); this.in_scope(region_scope, lint_level, |this| { @@ -76,6 +113,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) }) } + ExprKind::Use { source } => this.then_else_break( + block, + &this.thir[source], + temp_scope_override, + break_scope, + variable_source_info, + ), ExprKind::Let { expr, ref pat } => this.lower_let_expr( block, &this.thir[expr], diff --git a/compiler/rustc_privacy/messages.ftl b/compiler/rustc_privacy/messages.ftl index b91e0d18a80..7785f1a7f81 100644 --- a/compiler/rustc_privacy/messages.ftl +++ b/compiler/rustc_privacy/messages.ftl @@ -11,11 +11,6 @@ privacy_in_public_interface = {$vis_descr} {$kind} `{$descr}` in public interfac privacy_item_is_private = {$kind} `{$descr}` is private .label = private {$kind} -privacy_private_in_public_lint = - {$vis_descr} {$kind} `{$descr}` in public interface (error {$kind -> - [trait] E0445 - *[other] E0446 - }) privacy_private_interface_or_bounds_lint = {$ty_kind} `{$ty_descr}` is more private than the item `{$item_descr}` .item_label = {$item_kind} `{$item_descr}` is reachable at visibility `{$item_vis_descr}` diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index da18f0c8268..b1242f82f4f 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -47,21 +47,6 @@ pub struct UnnamedItemIsPrivate { pub kind: &'static str, } -// Duplicate of `InPublicInterface` but with a different error code, shares the same slug. -#[derive(Diagnostic)] -#[diag(privacy_in_public_interface, code = "E0445")] -pub struct InPublicInterfaceTraits<'a> { - #[primary_span] - #[label] - pub span: Span, - pub vis_descr: &'static str, - pub kind: &'a str, - pub descr: DiagnosticArgFromDisplay<'a>, - #[label(privacy_visibility_label)] - pub vis_span: Span, -} - -// Duplicate of `InPublicInterfaceTraits` but with a different error code, shares the same slug. #[derive(Diagnostic)] #[diag(privacy_in_public_interface, code = "E0446")] pub struct InPublicInterface<'a> { @@ -92,14 +77,6 @@ pub struct FromPrivateDependencyInPublicInterface<'a> { } #[derive(LintDiagnostic)] -#[diag(privacy_private_in_public_lint)] -pub struct PrivateInPublicLint<'a> { - pub vis_descr: &'static str, - pub kind: &'a str, - pub descr: DiagnosticArgFromDisplay<'a>, -} - -#[derive(LintDiagnostic)] #[diag(privacy_unnameable_types_lint)] pub struct UnnameableTypesLint<'a> { #[label] diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 0eb344ba690..906a36cdb25 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -22,7 +22,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, CRATE_DEF_ID}; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{AssocItemKind, ForeignItemKind, HirIdSet, ItemId, Node, PatKind}; +use rustc_hir::{AssocItemKind, ForeignItemKind, ItemId, Node, PatKind}; use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level}; @@ -42,8 +42,8 @@ use std::{fmt, mem}; use errors::{ FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface, - InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, PrivateInterfacesOrBoundsLint, - ReportEffectiveVisibility, UnnameableTypesLint, UnnamedItemIsPrivate, + ItemIsPrivate, PrivateInterfacesOrBoundsLint, ReportEffectiveVisibility, UnnameableTypesLint, + UnnamedItemIsPrivate, }; fluent_messages! { "../messages.ftl" } @@ -364,6 +364,7 @@ trait VisibilityLike: Sized { find.min } } + impl VisibilityLike for ty::Visibility { const MAX: Self = ty::Visibility::Public; fn new_min<const SHALLOW: bool>( @@ -1383,345 +1384,6 @@ impl<'tcx> DefIdVisitor<'tcx> for TypePrivacyVisitor<'tcx> { } /////////////////////////////////////////////////////////////////////////////// -/// Obsolete visitors for checking for private items in public interfaces. -/// These visitors are supposed to be kept in frozen state and produce an -/// "old error node set". For backward compatibility the new visitor reports -/// warnings instead of hard errors when the erroneous node is not in this old set. -/////////////////////////////////////////////////////////////////////////////// - -struct ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { - tcx: TyCtxt<'tcx>, - effective_visibilities: &'a EffectiveVisibilities, - in_variant: bool, - // Set of errors produced by this obsolete visitor. - old_error_set: HirIdSet, -} - -struct ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> { - inner: &'a ObsoleteVisiblePrivateTypesVisitor<'b, 'tcx>, - /// Whether the type refers to private types. - contains_private: bool, - /// Whether we've recurred at all (i.e., if we're pointing at the - /// first type on which `visit_ty` was called). - at_outer_type: bool, - /// Whether that first type is a public path. - outer_type_is_public_path: bool, -} - -impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { - fn path_is_private_type(&self, path: &hir::Path<'_>) -> bool { - let did = match path.res { - Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Err => { - return false; - } - res => res.def_id(), - }; - - // A path can only be private if: - // it's in this crate... - if let Some(did) = did.as_local() { - // .. and it corresponds to a private type in the AST (this returns - // `None` for type parameters). - match self.tcx.hir().find(self.tcx.hir().local_def_id_to_hir_id(did)) { - Some(Node::Item(_)) => !self.tcx.visibility(did).is_public(), - Some(_) | None => false, - } - } else { - false - } - } - - fn trait_is_public(&self, trait_id: LocalDefId) -> bool { - // FIXME: this would preferably be using `exported_items`, but all - // traits are exported currently (see `EmbargoVisitor.exported_trait`). - self.effective_visibilities.is_directly_public(trait_id) - } - - fn check_generic_bound(&mut self, bound: &hir::GenericBound<'_>) { - if let hir::GenericBound::Trait(ref trait_ref, _) = *bound { - if self.path_is_private_type(trait_ref.trait_ref.path) { - self.old_error_set.insert(trait_ref.trait_ref.hir_ref_id); - } - } - } - - fn item_is_public(&self, def_id: LocalDefId) -> bool { - self.effective_visibilities.is_reachable(def_id) || self.tcx.visibility(def_id).is_public() - } -} - -impl<'a, 'b, 'tcx, 'v> Visitor<'v> for ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> { - fn visit_generic_arg(&mut self, generic_arg: &'v hir::GenericArg<'v>) { - match generic_arg { - hir::GenericArg::Type(t) => self.visit_ty(t), - hir::GenericArg::Infer(inf) => self.visit_ty(&inf.to_ty()), - hir::GenericArg::Lifetime(_) | hir::GenericArg::Const(_) => {} - } - } - - fn visit_ty(&mut self, ty: &hir::Ty<'_>) { - if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind { - if self.inner.path_is_private_type(path) { - self.contains_private = true; - // Found what we're looking for, so let's stop working. - return; - } - } - if let hir::TyKind::Path(_) = ty.kind { - if self.at_outer_type { - self.outer_type_is_public_path = true; - } - } - self.at_outer_type = false; - intravisit::walk_ty(self, ty) - } - - // Don't want to recurse into `[, .. expr]`. - fn visit_expr(&mut self, _: &hir::Expr<'_>) {} -} - -impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { - type NestedFilter = nested_filter::All; - - /// We want to visit items in the context of their containing - /// module and so forth, so supply a crate for doing a deep walk. - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() - } - - fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - match item.kind { - // Contents of a private mod can be re-exported, so we need - // to check internals. - hir::ItemKind::Mod(_) => {} - - // An `extern {}` doesn't introduce a new privacy - // namespace (the contents have their own privacies). - hir::ItemKind::ForeignMod { .. } => {} - - hir::ItemKind::Trait(.., bounds, _) => { - if !self.trait_is_public(item.owner_id.def_id) { - return; - } - - for bound in bounds.iter() { - self.check_generic_bound(bound) - } - } - - // Impls need some special handling to try to offer useful - // error messages without (too many) false positives - // (i.e., we could just return here to not check them at - // all, or some worse estimation of whether an impl is - // publicly visible). - hir::ItemKind::Impl(ref impl_) => { - // `impl [... for] Private` is never visible. - let self_contains_private; - // `impl [... for] Public<...>`, but not `impl [... for] - // Vec<Public>` or `(Public,)`, etc. - let self_is_public_path; - - // Check the properties of the `Self` type: - { - let mut visitor = ObsoleteCheckTypeForPrivatenessVisitor { - inner: self, - contains_private: false, - at_outer_type: true, - outer_type_is_public_path: false, - }; - visitor.visit_ty(impl_.self_ty); - self_contains_private = visitor.contains_private; - self_is_public_path = visitor.outer_type_is_public_path; - } - - // Miscellaneous info about the impl: - - // `true` iff this is `impl Private for ...`. - let not_private_trait = impl_.of_trait.as_ref().map_or( - true, // no trait counts as public trait - |tr| { - if let Some(def_id) = tr.path.res.def_id().as_local() { - self.trait_is_public(def_id) - } else { - true // external traits must be public - } - }, - ); - - // `true` iff this is a trait impl or at least one method is public. - // - // `impl Public { $( fn ...() {} )* }` is not visible. - // - // This is required over just using the methods' privacy - // directly because we might have `impl<T: Foo<Private>> ...`, - // and we shouldn't warn about the generics if all the methods - // are private (because `T` won't be visible externally). - let trait_or_some_public_method = impl_.of_trait.is_some() - || impl_.items.iter().any(|impl_item_ref| { - let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); - match impl_item.kind { - hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..) => self - .effective_visibilities - .is_reachable(impl_item_ref.id.owner_id.def_id), - hir::ImplItemKind::Type(_) => false, - } - }); - - if !self_contains_private && not_private_trait && trait_or_some_public_method { - intravisit::walk_generics(self, &impl_.generics); - - match impl_.of_trait { - None => { - for impl_item_ref in impl_.items { - // This is where we choose whether to walk down - // further into the impl to check its items. We - // should only walk into public items so that we - // don't erroneously report errors for private - // types in private items. - let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); - match impl_item.kind { - hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..) - if self.item_is_public(impl_item.owner_id.def_id) => - { - intravisit::walk_impl_item(self, impl_item) - } - hir::ImplItemKind::Type(..) => { - intravisit::walk_impl_item(self, impl_item) - } - _ => {} - } - } - } - Some(ref tr) => { - // Any private types in a trait impl fall into three - // categories. - // 1. mentioned in the trait definition - // 2. mentioned in the type params/generics - // 3. mentioned in the associated types of the impl - // - // Those in 1. can only occur if the trait is in - // this crate and will have been warned about on the - // trait definition (there's no need to warn twice - // so we don't check the methods). - // - // Those in 2. are warned via walk_generics and this - // call here. - intravisit::walk_path(self, tr.path); - - // Those in 3. are warned with this call. - for impl_item_ref in impl_.items { - let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); - if let hir::ImplItemKind::Type(ty) = impl_item.kind { - self.visit_ty(ty); - } - } - } - } - } else if impl_.of_trait.is_none() && self_is_public_path { - // `impl Public<Private> { ... }`. Any public static - // methods will be visible as `Public::foo`. - let mut found_pub_static = false; - for impl_item_ref in impl_.items { - if self - .effective_visibilities - .is_reachable(impl_item_ref.id.owner_id.def_id) - || self.tcx.visibility(impl_item_ref.id.owner_id).is_public() - { - let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); - match impl_item_ref.kind { - AssocItemKind::Const => { - found_pub_static = true; - intravisit::walk_impl_item(self, impl_item); - } - AssocItemKind::Fn { has_self: false } => { - found_pub_static = true; - intravisit::walk_impl_item(self, impl_item); - } - _ => {} - } - } - } - if found_pub_static { - intravisit::walk_generics(self, &impl_.generics) - } - } - return; - } - - // `type ... = ...;` can contain private types, because - // we're introducing a new name. - hir::ItemKind::TyAlias(..) => return, - - // Not at all public, so we don't care. - _ if !self.item_is_public(item.owner_id.def_id) => { - return; - } - - _ => {} - } - - // We've carefully constructed it so that if we're here, then - // any `visit_ty`'s will be called on things that are in - // public signatures, i.e., things that we're interested in for - // this visitor. - intravisit::walk_item(self, item); - } - - fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) { - for predicate in generics.predicates { - match predicate { - hir::WherePredicate::BoundPredicate(bound_pred) => { - for bound in bound_pred.bounds.iter() { - self.check_generic_bound(bound) - } - } - hir::WherePredicate::RegionPredicate(_) => {} - hir::WherePredicate::EqPredicate(eq_pred) => { - self.visit_ty(eq_pred.rhs_ty); - } - } - } - } - - fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) { - if self.effective_visibilities.is_reachable(item.owner_id.def_id) { - intravisit::walk_foreign_item(self, item) - } - } - - fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) { - if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = t.kind { - if self.path_is_private_type(path) { - self.old_error_set.insert(t.hir_id); - } - } - intravisit::walk_ty(self, t) - } - - fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) { - if self.effective_visibilities.is_reachable(v.def_id) { - self.in_variant = true; - intravisit::walk_variant(self, v); - self.in_variant = false; - } - } - - fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) { - let vis = self.tcx.visibility(s.def_id); - if vis.is_public() || self.in_variant { - intravisit::walk_field_def(self, s); - } - } - - // We don't need to introspect into these at all: an - // expression/block context can't possibly contain exported things. - // (Making them no-ops stops us from traversing the whole AST without - // having to be super careful about our `walk_...` calls above.) - fn visit_block(&mut self, _: &'tcx hir::Block<'tcx>) {} - fn visit_expr(&mut self, _: &'tcx hir::Expr<'tcx>) {} -} - -/////////////////////////////////////////////////////////////////////////////// /// SearchInterfaceForPrivateItemsVisitor traverses an item's interface and /// finds any private components in it. /// PrivateItemsInPublicInterfacesVisitor ensures there are no private types @@ -1734,7 +1396,6 @@ struct SearchInterfaceForPrivateItemsVisitor<'tcx> { /// The visitor checks that each component type is at least this visible. required_visibility: ty::Visibility, required_effective_vis: Option<EffectiveVisibility>, - has_old_errors: bool, in_assoc_ty: bool, in_primary_interface: bool, } @@ -1805,7 +1466,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id); let span = self.tcx.def_span(self.item_def_id.to_def_id()); let vis_span = self.tcx.def_span(def_id); - if !vis.is_at_least(self.required_visibility, self.tcx) { + if self.in_assoc_ty && !vis.is_at_least(self.required_visibility, self.tcx) { let vis_descr = match vis { ty::Visibility::Public => "public", ty::Visibility::Restricted(vis_def_id) => { @@ -1819,35 +1480,14 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { } }; - if self.has_old_errors - || self.in_assoc_ty - || self.tcx.resolutions(()).has_pub_restricted - { - if kind == "trait" { - self.tcx.sess.emit_err(InPublicInterfaceTraits { - span, - vis_descr, - kind, - descr: descr.into(), - vis_span, - }); - } else { - self.tcx.sess.emit_err(InPublicInterface { - span, - vis_descr, - kind, - descr: descr.into(), - vis_span, - }); - } - } else { - self.tcx.emit_spanned_lint( - lint::builtin::PRIVATE_IN_PUBLIC, - hir_id, - span, - PrivateInPublicLint { vis_descr, kind, descr: descr.into() }, - ); - } + self.tcx.sess.emit_err(InPublicInterface { + span, + vis_descr, + kind, + descr: descr.into(), + vis_span, + }); + return false; } let Some(effective_vis) = self.required_effective_vis else { @@ -1918,7 +1558,6 @@ impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> { struct PrivateItemsInPublicInterfacesChecker<'tcx, 'a> { tcx: TyCtxt<'tcx>, - old_error_set_ancestry: HirIdSet, effective_visibilities: &'a EffectiveVisibilities, } @@ -1934,9 +1573,6 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> { item_def_id: def_id, required_visibility, required_effective_vis, - has_old_errors: self - .old_error_set_ancestry - .contains(&self.tcx.hir().local_def_id_to_hir_id(def_id)), in_assoc_ty: false, in_primary_interface: true, } @@ -2298,35 +1934,8 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities { fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) { let effective_visibilities = tcx.effective_visibilities(()); - - let mut visitor = ObsoleteVisiblePrivateTypesVisitor { - tcx, - effective_visibilities, - in_variant: false, - old_error_set: Default::default(), - }; - tcx.hir().walk_toplevel_module(&mut visitor); - - let mut old_error_set_ancestry = HirIdSet::default(); - for mut id in visitor.old_error_set.iter().copied() { - loop { - if !old_error_set_ancestry.insert(id) { - break; - } - let parent = tcx.hir().parent_id(id); - if parent == id { - break; - } - id = parent; - } - } - - // Check for private types and traits in public interfaces. - let mut checker = PrivateItemsInPublicInterfacesChecker { - tcx, - old_error_set_ancestry, - effective_visibilities, - }; + // Check for private types in public interfaces. + let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, effective_visibilities }; for id in tcx.hir().items() { checker.check_item(id); diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index a96230fdc94..d8aa377af42 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -2,7 +2,7 @@ use crate::dep_graph::DepNodeIndex; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sharded::{self, Sharded}; -use rustc_data_structures::sync::Lock; +use rustc_data_structures::sync::OnceLock; use rustc_index::{Idx, IndexVec}; use std::fmt::Debug; use std::hash::Hash; @@ -87,12 +87,12 @@ impl<'tcx, V: 'tcx> CacheSelector<'tcx, V> for SingleCacheSelector { } pub struct SingleCache<V> { - cache: Lock<Option<(V, DepNodeIndex)>>, + cache: OnceLock<(V, DepNodeIndex)>, } impl<V> Default for SingleCache<V> { fn default() -> Self { - SingleCache { cache: Lock::new(None) } + SingleCache { cache: OnceLock::new() } } } @@ -105,16 +105,16 @@ where #[inline(always)] fn lookup(&self, _key: &()) -> Option<(V, DepNodeIndex)> { - *self.cache.lock() + self.cache.get().copied() } #[inline] fn complete(&self, _key: (), value: V, index: DepNodeIndex) { - *self.cache.lock() = Some((value, index)); + self.cache.set((value, index)).ok(); } fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { - if let Some(value) = self.cache.lock().as_ref() { + if let Some(value) = self.cache.get() { f(&(), &value.0, value.1) } } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 476b5f733a6..30db450870b 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -247,8 +247,6 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { }) } ast::VisibilityKind::Restricted { ref path, id, .. } => { - // Make `PRIVATE_IN_PUBLIC` lint a hard error. - self.r.has_pub_restricted = true; // For visibilities we are not ready to provide correct implementation of "uniform // paths" right now, so on 2018 edition we only allow module-relative paths for now. // On 2015 edition visibilities are resolved as crate-relative by default, diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index eb210532f51..46f5df5ca6f 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -128,11 +128,14 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { // If the binding is ambiguous, put the root ambiguity binding and all reexports // leading to it into the table. They are used by the `ambiguous_glob_reexports` // lint. For all bindings added to the table this way `is_ambiguity` returns true. + let is_ambiguity = + |binding: NameBinding<'a>, warn: bool| binding.ambiguity.is_some() && !warn; let mut parent_id = ParentId::Def(module_id); + let mut warn_ambiguity = binding.warn_ambiguity; while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind { self.update_import(binding, parent_id); - if binding.ambiguity.is_some() { + if is_ambiguity(binding, warn_ambiguity) { // Stop at the root ambiguity, further bindings in the chain should not // be reexported because the root ambiguity blocks any access to them. // (Those further bindings are most likely not ambiguities themselves.) @@ -141,9 +144,9 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { parent_id = ParentId::Import(binding); binding = nested_binding; + warn_ambiguity |= nested_binding.warn_ambiguity; } - - if binding.ambiguity.is_none() + if !is_ambiguity(binding, warn_ambiguity) && let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) { self.update_def(def_id, binding.vis.expect_local(), parent_id); } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 500004269c9..486d60eab21 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -313,7 +313,7 @@ enum LifetimeRibKind { /// Resolves elided lifetimes to `'static`, but gives a warning that this behavior /// is a bug and will be reverted soon. - AnonymousWarnToStatic(NodeId), + AnonymousWarn(NodeId), /// Signal we cannot find which should be the anonymous lifetime. ElisionFailure, @@ -1109,6 +1109,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, } }, AssocConstraintKind::Bound { ref bounds } => { + self.record_lifetime_params_for_impl_trait(constraint.id); walk_list!(self, visit_param_bound, bounds, BoundKind::Bound); } } @@ -1153,7 +1154,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, } LifetimeRibKind::AnonymousCreateParameter { .. } | LifetimeRibKind::AnonymousReportError - | LifetimeRibKind::AnonymousWarnToStatic(_) + | LifetimeRibKind::AnonymousWarn(_) | LifetimeRibKind::Elided(_) | LifetimeRibKind::ElisionFailure | LifetimeRibKind::ConcreteAnonConst(_) @@ -1521,7 +1522,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // lifetime would be illegal. LifetimeRibKind::Item | LifetimeRibKind::AnonymousReportError - | LifetimeRibKind::AnonymousWarnToStatic(_) + | LifetimeRibKind::AnonymousWarn(_) | LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many), // An anonymous lifetime is legal here, and bound to the right // place, go ahead. @@ -1584,7 +1585,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { | LifetimeRibKind::Generics { .. } | LifetimeRibKind::ElisionFailure | LifetimeRibKind::AnonymousReportError - | LifetimeRibKind::AnonymousWarnToStatic(_) => {} + | LifetimeRibKind::AnonymousWarn(_) => {} } } @@ -1624,8 +1625,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { self.record_lifetime_res(lifetime.id, res, elision_candidate); return; } - LifetimeRibKind::AnonymousWarnToStatic(node_id) => { - self.record_lifetime_res(lifetime.id, LifetimeRes::Static, elision_candidate); + LifetimeRibKind::AnonymousWarn(node_id) => { let msg = if elided { "`&` without an explicit lifetime name cannot be used here" } else { @@ -1641,7 +1641,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { span: lifetime.ident.span, }, ); - return; } LifetimeRibKind::AnonymousReportError => { let (msg, note) = if elided { @@ -1839,7 +1838,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // impl Foo for std::cell::Ref<u32> // note lack of '_ // async fn foo(_: std::cell::Ref<u32>) { ... } LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. } - | LifetimeRibKind::AnonymousWarnToStatic(_) => { + | LifetimeRibKind::AnonymousWarn(_) => { let sess = self.r.tcx.sess; let mut err = rustc_errors::struct_span_err!( sess, @@ -2935,33 +2934,30 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { kind: LifetimeBinderKind::ConstItem, }, |this| { - this.with_lifetime_rib( - LifetimeRibKind::AnonymousWarnToStatic(item.id), - |this| { - // If this is a trait impl, ensure the const - // exists in trait - this.check_trait_item( - item.id, - item.ident, - &item.kind, - ValueNS, - item.span, - seen_trait_items, - |i, s, c| ConstNotMemberOfTrait(i, s, c), - ); + this.with_lifetime_rib(LifetimeRibKind::AnonymousWarn(item.id), |this| { + // If this is a trait impl, ensure the const + // exists in trait + this.check_trait_item( + item.id, + item.ident, + &item.kind, + ValueNS, + item.span, + seen_trait_items, + |i, s, c| ConstNotMemberOfTrait(i, s, c), + ); - this.visit_generics(generics); - this.visit_ty(ty); - if let Some(expr) = expr { - // We allow arbitrary const expressions inside of associated consts, - // even if they are potentially not const evaluatable. - // - // Type parameters can already be used and as associated consts are - // not used as part of the type system, this is far less surprising. - this.resolve_const_body(expr, None); - } - }, - ); + this.visit_generics(generics); + this.visit_ty(ty); + if let Some(expr) = expr { + // We allow arbitrary const expressions inside of associated consts, + // even if they are potentially not const evaluatable. + // + // Type parameters can already be used and as associated consts are + // not used as part of the type system, this is far less surprising. + this.resolve_const_body(expr, None); + } + }); }, ); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 6d3a1d69ef0..b757f42eaa0 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -989,7 +989,6 @@ pub struct Resolver<'a, 'tcx> { glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>, /// Visibilities in "lowered" form, for all entities that have them. visibilities: FxHashMap<LocalDefId, ty::Visibility>, - has_pub_restricted: bool, used_imports: FxHashSet<NodeId>, maybe_unused_trait_imports: FxIndexSet<LocalDefId>, @@ -1342,7 +1341,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { glob_map: Default::default(), visibilities, - has_pub_restricted: false, used_imports: FxHashSet::default(), maybe_unused_trait_imports: Default::default(), @@ -1486,7 +1484,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect(); let expn_that_defined = self.expn_that_defined; let visibilities = self.visibilities; - let has_pub_restricted = self.has_pub_restricted; let extern_crate_map = self.extern_crate_map; let maybe_unused_trait_imports = self.maybe_unused_trait_imports; let glob_map = self.glob_map; @@ -1504,7 +1501,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let global_ctxt = ResolverGlobalCtxt { expn_that_defined, visibilities, - has_pub_restricted, effective_visibilities, extern_crate_map, module_children: self.module_children, diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 5334a75dc06..d8e1f0877bf 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -5,7 +5,6 @@ use std::fmt::Debug; use std::ops::Index; -use std::string::ToString; use crate::rustc_internal; use crate::{ @@ -156,10 +155,23 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) { } /// A type that provides internal information but that can still be used for debug purpose. -pub type Opaque = impl Debug + ToString + Clone; +#[derive(Clone)] +pub struct Opaque(String); + +impl std::fmt::Display for Opaque { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl std::fmt::Debug for Opaque { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self.0) + } +} pub(crate) fn opaque<T: Debug>(value: &T) -> Opaque { - format!("{value:?}") + Opaque(format!("{value:?}")) } pub struct StableMir { diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs new file mode 100644 index 00000000000..33c75250adc --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -0,0 +1,124 @@ +use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, Pointer}; + +use crate::{ + rustc_internal::opaque, + rustc_smir::{Stable, Tables}, + stable_mir::mir::Mutability, + stable_mir::ty::{Allocation, ProvenanceMap}, +}; + +/// Creates new empty `Allocation` from given `Align`. +fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation { + Allocation { + bytes: Vec::new(), + provenance: ProvenanceMap { ptrs: Vec::new() }, + align: align.bytes(), + mutability: Mutability::Not, + } +} + +// We need this method instead of a Stable implementation +// because we need to get `Ty` of the const we are trying to create, to do that +// we need to have access to `ConstantKind` but we can't access that inside Stable impl. +#[allow(rustc::usage_of_qualified_ty)] +pub fn new_allocation<'tcx>( + ty: rustc_middle::ty::Ty<'tcx>, + const_value: ConstValue<'tcx>, + tables: &mut Tables<'tcx>, +) -> Allocation { + match const_value { + ConstValue::Scalar(scalar) => { + let size = scalar.size(); + let align = tables + .tcx + .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty)) + .unwrap() + .align; + let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(size, align.abi); + allocation + .write_scalar(&tables.tcx, alloc_range(rustc_target::abi::Size::ZERO, size), scalar) + .unwrap(); + allocation.stable(tables) + } + ConstValue::ZeroSized => { + let align = + tables.tcx.layout_of(rustc_middle::ty::ParamEnv::empty().and(ty)).unwrap().align; + new_empty_allocation(align.abi) + } + ConstValue::Slice { data, start, end } => { + let alloc_id = tables.tcx.create_memory_alloc(data); + let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::from_bytes(start)); + let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx); + let scalar_len = rustc_middle::mir::interpret::Scalar::from_target_usize( + (end - start) as u64, + &tables.tcx, + ); + let layout = + tables.tcx.layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty)).unwrap(); + let mut allocation = + rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi); + allocation + .write_scalar( + &tables.tcx, + alloc_range(rustc_target::abi::Size::ZERO, tables.tcx.data_layout.pointer_size), + scalar_ptr, + ) + .unwrap(); + allocation + .write_scalar( + &tables.tcx, + alloc_range(tables.tcx.data_layout.pointer_size, scalar_len.size()), + scalar_len, + ) + .unwrap(); + allocation.stable(tables) + } + ConstValue::ByRef { alloc, offset } => { + let ty_size = tables + .tcx + .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty)) + .unwrap() + .size; + allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables) + } + } +} + +/// Creates an `Allocation` only from information within the `AllocRange`. +pub(super) fn allocation_filter<'tcx>( + alloc: &rustc_middle::mir::interpret::Allocation, + alloc_range: AllocRange, + tables: &mut Tables<'tcx>, +) -> Allocation { + let mut bytes: Vec<Option<u8>> = alloc + .inspect_with_uninit_and_ptr_outside_interpreter( + alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(), + ) + .iter() + .copied() + .map(Some) + .collect(); + for (i, b) in bytes.iter_mut().enumerate() { + if !alloc + .init_mask() + .get(rustc_target::abi::Size::from_bytes(i + alloc_range.start.bytes_usize())) + { + *b = None; + } + } + let mut ptrs = Vec::new(); + for (offset, prov) in alloc + .provenance() + .ptrs() + .iter() + .filter(|a| a.0 >= alloc_range.start && a.0 <= alloc_range.end()) + { + ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), opaque(prov))); + } + Allocation { + bytes: bytes, + provenance: ProvenanceMap { ptrs }, + align: alloc.align.bytes(), + mutability: alloc.mutability.stable(tables), + } +} diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 7877c91c2cf..d36835d37f5 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -9,10 +9,7 @@ use crate::rustc_internal::{self, opaque}; use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; -use crate::stable_mir::ty::{ - allocation_filter, new_allocation, Const, FloatTy, GenericParamDef, IntTy, Movability, RigidTy, - TyKind, UintTy, -}; +use crate::stable_mir::ty::{FloatTy, GenericParamDef, IntTy, Movability, RigidTy, TyKind, UintTy}; use crate::stable_mir::{self, Context}; use rustc_hir as hir; use rustc_middle::mir::interpret::alloc_range; @@ -22,6 +19,8 @@ use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_target::abi::FieldIdx; use tracing::debug; +mod alloc; + impl<'tcx> Context for Tables<'tcx> { fn local_crate(&self) -> stable_mir::Crate { smir_crate(self.tcx, LOCAL_CRATE) @@ -205,8 +204,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> { match self { Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables)), Repeat(op, len) => { - let cnst = ConstantKind::from_const(*len, tables.tcx); - let len = Const { literal: cnst.stable(tables) }; + let len = len.stable(tables); stable_mir::mir::Rvalue::Repeat(op.stable(tables), len) } Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref( @@ -394,8 +392,7 @@ impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> { match self { ty::TermKind::Ty(ty) => TermKind::Type(tables.intern_ty(*ty)), ty::TermKind::Const(cnst) => { - let cnst = ConstantKind::from_const(*cnst, tables.tcx); - let cnst = Const { literal: cnst.stable(tables) }; + let cnst = cnst.stable(tables); TermKind::Const(cnst) } } @@ -1083,8 +1080,32 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { type T = stable_mir::ty::Const; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - let cnst = ConstantKind::from_const(*self, tables.tcx); - stable_mir::ty::Const { literal: cnst.stable(tables) } + stable_mir::ty::Const { + literal: match self.kind() { + ty::Value(val) => { + let const_val = tables.tcx.valtree_to_const_val((self.ty(), val)); + stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation( + self.ty(), + const_val, + tables, + )) + } + ty::ParamCt(param) => stable_mir::ty::ConstantKind::ParamCt(opaque(¶m)), + ty::ErrorCt(_) => unreachable!(), + ty::InferCt(_) => unreachable!(), + ty::BoundCt(_, _) => unimplemented!(), + ty::PlaceholderCt(_) => unimplemented!(), + ty::Unevaluated(uv) => { + stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { + ty: tables.intern_ty(self.ty()), + def: tables.const_def(uv.def), + args: uv.args.stable(tables), + promoted: None, + }) + } + ty::ExprCt(_) => unimplemented!(), + }, + } } } @@ -1108,7 +1129,11 @@ impl<'tcx> Stable<'tcx> for mir::interpret::Allocation { type T = stable_mir::ty::Allocation; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - allocation_filter(self, alloc_range(rustc_target::abi::Size::ZERO, self.size()), tables) + alloc::allocation_filter( + self, + alloc_range(rustc_target::abi::Size::ZERO, self.size()), + tables, + ) } } @@ -1155,26 +1180,18 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::ConstantKind<'tcx> { type T = stable_mir::ty::ConstantKind; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - match self { - ConstantKind::Ty(c) => match c.kind() { - ty::Value(val) => { - let const_val = tables.tcx.valtree_to_const_val((c.ty(), val)); - stable_mir::ty::ConstantKind::Allocated(new_allocation(self, const_val, tables)) - } - ty::ParamCt(param) => stable_mir::ty::ConstantKind::ParamCt(opaque(¶m)), - ty::ErrorCt(_) => unreachable!(), - _ => unimplemented!(), - }, + match *self { + ConstantKind::Ty(c) => c.stable(tables).literal, ConstantKind::Unevaluated(unev_const, ty) => { stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { - ty: tables.intern_ty(*ty), + ty: tables.intern_ty(ty), def: tables.const_def(unev_const.def), args: unev_const.args.stable(tables), promoted: unev_const.promoted.map(|u| u.as_u32()), }) } - ConstantKind::Val(val, _) => { - stable_mir::ty::ConstantKind::Allocated(new_allocation(self, *val, tables)) + ConstantKind::Val(val, ty) => { + stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(ty, val, tables)) } } } diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index 1b834628175..2d43e62e97a 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -20,6 +20,7 @@ use crate::rustc_smir::Tables; pub mod mir; pub mod ty; +pub mod visitor; /// Use String for now but we should replace it. pub type Symbol = String; diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index fce5375f848..d49f3243777 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -1,10 +1,5 @@ -use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, Pointer}; - use super::{mir::Mutability, mir::Safety, with, DefId}; -use crate::{ - rustc_internal::{opaque, Opaque}, - rustc_smir::{Stable, Tables}, -}; +use crate::rustc_internal::Opaque; #[derive(Copy, Clone, Debug)] pub struct Ty(pub usize); @@ -286,128 +281,6 @@ pub struct Allocation { pub mutability: Mutability, } -impl Allocation { - /// Creates new empty `Allocation` from given `Align`. - fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation { - Allocation { - bytes: Vec::new(), - provenance: ProvenanceMap { ptrs: Vec::new() }, - align: align.bytes(), - mutability: Mutability::Not, - } - } -} - -// We need this method instead of a Stable implementation -// because we need to get `Ty` of the const we are trying to create, to do that -// we need to have access to `ConstantKind` but we can't access that inside Stable impl. -pub fn new_allocation<'tcx>( - const_kind: &rustc_middle::mir::ConstantKind<'tcx>, - const_value: ConstValue<'tcx>, - tables: &mut Tables<'tcx>, -) -> Allocation { - match const_value { - ConstValue::Scalar(scalar) => { - let size = scalar.size(); - let align = tables - .tcx - .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty())) - .unwrap() - .align; - let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(size, align.abi); - allocation - .write_scalar(&tables.tcx, alloc_range(rustc_target::abi::Size::ZERO, size), scalar) - .unwrap(); - allocation.stable(tables) - } - ConstValue::ZeroSized => { - let align = tables - .tcx - .layout_of(rustc_middle::ty::ParamEnv::empty().and(const_kind.ty())) - .unwrap() - .align; - Allocation::new_empty_allocation(align.abi) - } - ConstValue::Slice { data, start, end } => { - let alloc_id = tables.tcx.create_memory_alloc(data); - let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::from_bytes(start)); - let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx); - let scalar_len = rustc_middle::mir::interpret::Scalar::from_target_usize( - (end - start) as u64, - &tables.tcx, - ); - let layout = tables - .tcx - .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty())) - .unwrap(); - let mut allocation = - rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi); - allocation - .write_scalar( - &tables.tcx, - alloc_range(rustc_target::abi::Size::ZERO, tables.tcx.data_layout.pointer_size), - scalar_ptr, - ) - .unwrap(); - allocation - .write_scalar( - &tables.tcx, - alloc_range(tables.tcx.data_layout.pointer_size, scalar_len.size()), - scalar_len, - ) - .unwrap(); - allocation.stable(tables) - } - ConstValue::ByRef { alloc, offset } => { - let ty_size = tables - .tcx - .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty())) - .unwrap() - .size; - allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables) - } - } -} - -/// Creates an `Allocation` only from information within the `AllocRange`. -pub fn allocation_filter<'tcx>( - alloc: &rustc_middle::mir::interpret::Allocation, - alloc_range: AllocRange, - tables: &mut Tables<'tcx>, -) -> Allocation { - let mut bytes: Vec<Option<u8>> = alloc - .inspect_with_uninit_and_ptr_outside_interpreter( - alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(), - ) - .iter() - .copied() - .map(Some) - .collect(); - for (i, b) in bytes.iter_mut().enumerate() { - if !alloc - .init_mask() - .get(rustc_target::abi::Size::from_bytes(i + alloc_range.start.bytes_usize())) - { - *b = None; - } - } - let mut ptrs = Vec::new(); - for (offset, prov) in alloc - .provenance() - .ptrs() - .iter() - .filter(|a| a.0 >= alloc_range.start && a.0 <= alloc_range.end()) - { - ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), opaque(prov))); - } - Allocation { - bytes: bytes, - provenance: ProvenanceMap { ptrs }, - align: alloc.align.bytes(), - mutability: alloc.mutability.stable(tables), - } -} - #[derive(Clone, Debug)] pub enum ConstantKind { Allocated(Allocation), diff --git a/compiler/rustc_smir/src/stable_mir/visitor.rs b/compiler/rustc_smir/src/stable_mir/visitor.rs new file mode 100644 index 00000000000..c928eb1381f --- /dev/null +++ b/compiler/rustc_smir/src/stable_mir/visitor.rs @@ -0,0 +1,186 @@ +use std::ops::ControlFlow; + +use crate::rustc_internal::Opaque; + +use super::ty::{ + Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs, + Promoted, RigidTy, TermKind, Ty, UnevaluatedConst, +}; + +pub trait Visitor: Sized { + type Break; + fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break> { + ty.super_visit(self) + } + fn visit_const(&mut self, c: &Const) -> ControlFlow<Self::Break> { + c.super_visit(self) + } +} + +pub trait Visitable { + fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { + self.super_visit(visitor) + } + fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break>; +} + +impl Visitable for Ty { + fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { + visitor.visit_ty(self) + } + fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { + match self.kind() { + super::ty::TyKind::RigidTy(ty) => ty.visit(visitor), + super::ty::TyKind::Alias(_, alias) => alias.args.visit(visitor), + super::ty::TyKind::Param(_) => todo!(), + super::ty::TyKind::Bound(_, _) => todo!(), + } + } +} + +impl Visitable for Const { + fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { + visitor.visit_const(self) + } + fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { + match &self.literal { + super::ty::ConstantKind::Allocated(alloc) => alloc.visit(visitor), + super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor), + super::ty::ConstantKind::ParamCt(param) => param.visit(visitor), + } + } +} + +impl Visitable for Opaque { + fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> { + ControlFlow::Continue(()) + } +} + +impl Visitable for Allocation { + fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> { + ControlFlow::Continue(()) + } +} + +impl Visitable for UnevaluatedConst { + fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { + let UnevaluatedConst { ty, def, args, promoted } = self; + ty.visit(visitor)?; + def.visit(visitor)?; + args.visit(visitor)?; + promoted.visit(visitor) + } +} + +impl Visitable for ConstDef { + fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> { + ControlFlow::Continue(()) + } +} + +impl<T: Visitable> Visitable for Option<T> { + fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { + match self { + Some(val) => val.visit(visitor), + None => ControlFlow::Continue(()), + } + } +} + +impl Visitable for Promoted { + fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> { + ControlFlow::Continue(()) + } +} + +impl Visitable for GenericArgs { + fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { + self.0.visit(visitor) + } +} + +impl Visitable for GenericArgKind { + fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { + match self { + GenericArgKind::Lifetime(lt) => lt.visit(visitor), + GenericArgKind::Type(t) => t.visit(visitor), + GenericArgKind::Const(c) => c.visit(visitor), + } + } +} + +impl Visitable for RigidTy { + fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { + match self { + RigidTy::Bool + | RigidTy::Char + | RigidTy::Int(_) + | RigidTy::Uint(_) + | RigidTy::Float(_) + | RigidTy::Never + | RigidTy::Foreign(_) + | RigidTy::Str => ControlFlow::Continue(()), + RigidTy::Array(t, c) => { + t.visit(visitor)?; + c.visit(visitor) + } + RigidTy::Slice(inner) => inner.visit(visitor), + RigidTy::RawPtr(ty, _) => ty.visit(visitor), + RigidTy::Ref(_, ty, _) => ty.visit(visitor), + RigidTy::FnDef(_, args) => args.visit(visitor), + RigidTy::FnPtr(sig) => sig.visit(visitor), + RigidTy::Closure(_, args) => args.visit(visitor), + RigidTy::Generator(_, args, _) => args.visit(visitor), + RigidTy::Dynamic(pred, r, _) => { + pred.visit(visitor)?; + r.visit(visitor) + } + RigidTy::Tuple(fields) => fields.visit(visitor), + RigidTy::Adt(_, args) => args.visit(visitor), + } + } +} + +impl<T: Visitable> Visitable for Vec<T> { + fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { + for arg in self { + arg.visit(visitor)?; + } + ControlFlow::Continue(()) + } +} + +impl<T: Visitable> Visitable for Binder<T> { + fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { + self.value.visit(visitor) + } +} + +impl Visitable for ExistentialPredicate { + fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { + match self { + ExistentialPredicate::Trait(tr) => tr.generic_args.visit(visitor), + ExistentialPredicate::Projection(p) => { + p.term.visit(visitor)?; + p.generic_args.visit(visitor) + } + ExistentialPredicate::AutoTrait(_) => ControlFlow::Continue(()), + } + } +} + +impl Visitable for TermKind { + fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { + match self { + TermKind::Type(t) => t.visit(visitor), + TermKind::Const(c) => c.visit(visitor), + } + } +} + +impl Visitable for FnSig { + fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> { + self.inputs_and_output.visit(visitor) + } +} diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl index f4c9dfa3488..2a09a7dcd89 100644 --- a/compiler/rustc_trait_selection/messages.ftl +++ b/compiler/rustc_trait_selection/messages.ftl @@ -40,4 +40,5 @@ trait_selection_no_value_in_rustc_on_unimplemented = this attribute must have a .label = expected value here .note = eg `#[rustc_on_unimplemented(message="foo")]` +trait_selection_ty_alias_overflow = in case this is a recursive type alias, consider using a struct, enum, or union instead trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated} diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 5c2cbe39953..63ae83c8ef4 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -537,7 +537,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { /// Iterate over all added goals: returning `Ok(Some(_))` in case we can stop rerunning. /// - /// Goals for the next step get directly added the the nested goals of the `EvalCtxt`. + /// Goals for the next step get directly added to the nested goals of the `EvalCtxt`. fn evaluate_added_goals_step(&mut self) -> Result<Option<Certainty>, NoSolution> { let tcx = self.tcx(); let mut goals = core::mem::replace(&mut self.nested_goals, NestedGoals::new()); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 06a1027e5df..b31c0e655fb 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -659,6 +659,18 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx normalized_ty } ty::Weak => { + let recursion_limit = self.interner().recursion_limit(); + if !recursion_limit.value_within_limit(self.depth) { + self.selcx.infcx.err_ctxt().report_overflow_error( + &ty, + self.cause.span, + false, + |diag| { + diag.note(crate::fluent_generated::trait_selection_ty_alias_overflow); + }, + ); + } + let infcx = self.selcx.infcx; self.obligations.extend( infcx.tcx.predicates_of(data.def_id).instantiate_own(infcx.tcx, data.args).map( @@ -678,7 +690,14 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx }, ), ); - infcx.tcx.type_of(data.def_id).instantiate(infcx.tcx, data.args).fold_with(self) + self.depth += 1; + let res = infcx + .tcx + .type_of(data.def_id) + .instantiate(infcx.tcx, data.args) + .fold_with(self); + self.depth -= 1; + res } ty::Inherent if !data.has_escaping_bound_vars() => { diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index b84e4b35b1c..b6b36886604 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -87,20 +87,54 @@ impl From<char> for u128 { } } -/// Map `char` with code point in U+0000..=U+00FF to byte in 0x00..=0xFF with same value, failing -/// if the code point is greater than U+00FF. +/// Maps a `char` with code point in U+0000..=U+00FF to a byte in 0x00..=0xFF with same value, +/// failing if the code point is greater than U+00FF. /// /// See [`impl From<u8> for char`](char#impl-From<u8>-for-char) for details on the encoding. #[stable(feature = "u8_from_char", since = "1.59.0")] impl TryFrom<char> for u8 { type Error = TryFromCharError; + /// Tries to convert a [`char`] into a [`u8`]. + /// + /// # Examples + /// + /// ``` + /// let a = 'ÿ'; // U+00FF + /// let b = 'Ā'; // U+0100 + /// assert_eq!(u8::try_from(a), Ok(0xFF_u8)); + /// assert!(u8::try_from(b).is_err()); + /// ``` #[inline] fn try_from(c: char) -> Result<u8, Self::Error> { u8::try_from(u32::from(c)).map_err(|_| TryFromCharError(())) } } +/// Maps a `char` with code point in U+0000..=U+FFFF to a `u16` in 0x0000..=0xFFFF with same value, +/// failing if the code point is greater than U+FFFF. +/// +/// This corresponds to the UCS-2 encoding, as specified in ISO/IEC 10646:2003. +#[stable(feature = "u16_from_char", since = "CURRENT_RUSTC_VERSION")] +impl TryFrom<char> for u16 { + type Error = TryFromCharError; + + /// Tries to convert a [`char`] into a [`u16`]. + /// + /// # Examples + /// + /// ``` + /// let trans_rights = '⚧'; // U+26A7 + /// let ninjas = '🥷'; // U+1F977 + /// assert_eq!(u16::try_from(trans_rights), Ok(0x26A7_u16)); + /// assert!(u16::try_from(ninjas).is_err()); + /// ``` + #[inline] + fn try_from(c: char) -> Result<u16, Self::Error> { + u16::try_from(u32::from(c)).map_err(|_| TryFromCharError(())) + } +} + /// Maps a byte in 0x00..=0xFF to a `char` whose code point has the same value, in U+0000..=U+00FF. /// /// Unicode is designed such that this effectively decodes bytes diff --git a/library/core/src/iter/adapters/take.rs b/library/core/src/iter/adapters/take.rs index ce18bffe714..c1d8cc4ff57 100644 --- a/library/core/src/iter/adapters/take.rs +++ b/library/core/src/iter/adapters/take.rs @@ -1,5 +1,7 @@ use crate::cmp; -use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen}; +use crate::iter::{ + adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen, TrustedRandomAccess, +}; use crate::num::NonZeroUsize; use crate::ops::{ControlFlow, Try}; @@ -98,26 +100,18 @@ where } } - impl_fold_via_try_fold! { fold -> try_fold } - #[inline] - fn for_each<F: FnMut(Self::Item)>(mut self, f: F) { - // The default implementation would use a unit accumulator, so we can - // avoid a stateful closure by folding over the remaining number - // of items we wish to return instead. - fn check<'a, Item>( - mut action: impl FnMut(Item) + 'a, - ) -> impl FnMut(usize, Item) -> Option<usize> + 'a { - move |more, x| { - action(x); - more.checked_sub(1) - } - } + fn fold<B, F>(self, init: B, f: F) -> B + where + Self: Sized, + F: FnMut(B, Self::Item) -> B, + { + Self::spec_fold(self, init, f) + } - let remaining = self.n; - if remaining > 0 { - self.iter.try_fold(remaining - 1, check(f)); - } + #[inline] + fn for_each<F: FnMut(Self::Item)>(self, f: F) { + Self::spec_for_each(self, f) } #[inline] @@ -249,3 +243,72 @@ impl<I> FusedIterator for Take<I> where I: FusedIterator {} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl<I: TrustedLen> TrustedLen for Take<I> {} + +trait SpecTake: Iterator { + fn spec_fold<B, F>(self, init: B, f: F) -> B + where + Self: Sized, + F: FnMut(B, Self::Item) -> B; + + fn spec_for_each<F: FnMut(Self::Item)>(self, f: F); +} + +impl<I: Iterator> SpecTake for Take<I> { + #[inline] + default fn spec_fold<B, F>(mut self, init: B, f: F) -> B + where + Self: Sized, + F: FnMut(B, Self::Item) -> B, + { + use crate::ops::NeverShortCircuit; + self.try_fold(init, NeverShortCircuit::wrap_mut_2(f)).0 + } + + #[inline] + default fn spec_for_each<F: FnMut(Self::Item)>(mut self, f: F) { + // The default implementation would use a unit accumulator, so we can + // avoid a stateful closure by folding over the remaining number + // of items we wish to return instead. + fn check<'a, Item>( + mut action: impl FnMut(Item) + 'a, + ) -> impl FnMut(usize, Item) -> Option<usize> + 'a { + move |more, x| { + action(x); + more.checked_sub(1) + } + } + + let remaining = self.n; + if remaining > 0 { + self.iter.try_fold(remaining - 1, check(f)); + } + } +} + +impl<I: Iterator + TrustedRandomAccess> SpecTake for Take<I> { + #[inline] + fn spec_fold<B, F>(mut self, init: B, mut f: F) -> B + where + Self: Sized, + F: FnMut(B, Self::Item) -> B, + { + let mut acc = init; + let end = self.n.min(self.iter.size()); + for i in 0..end { + // SAFETY: i < end <= self.iter.size() and we discard the iterator at the end + let val = unsafe { self.iter.__iterator_get_unchecked(i) }; + acc = f(acc, val); + } + acc + } + + #[inline] + fn spec_for_each<F: FnMut(Self::Item)>(mut self, mut f: F) { + let end = self.n.min(self.iter.size()); + for i in 0..end { + // SAFETY: i < end <= self.iter.size() and we discard the iterator at the end + let val = unsafe { self.iter.__iterator_get_unchecked(i) }; + f(val); + } + } +} diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index 462f7170a55..44feb0a5638 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -1,3 +1,4 @@ +use crate::ascii::Char as AsciiChar; use crate::convert::TryFrom; use crate::mem; use crate::num::NonZeroUsize; @@ -14,7 +15,7 @@ macro_rules! unsafe_impl_trusted_step { unsafe impl TrustedStep for $type {} )*}; } -unsafe_impl_trusted_step![char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize]; +unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize]; /// Objects that have a notion of *successor* and *predecessor* operations. /// @@ -484,6 +485,48 @@ impl Step for char { } } +#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] +impl Step for AsciiChar { + #[inline] + fn steps_between(&start: &AsciiChar, &end: &AsciiChar) -> Option<usize> { + Step::steps_between(&start.to_u8(), &end.to_u8()) + } + + #[inline] + fn forward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> { + let end = Step::forward_checked(start.to_u8(), count)?; + AsciiChar::from_u8(end) + } + + #[inline] + fn backward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> { + let end = Step::backward_checked(start.to_u8(), count)?; + + // SAFETY: Values below that of a valid ASCII character are also valid ASCII + Some(unsafe { AsciiChar::from_u8_unchecked(end) }) + } + + #[inline] + unsafe fn forward_unchecked(start: AsciiChar, count: usize) -> AsciiChar { + // SAFETY: Caller asserts that result is a valid ASCII character, + // and therefore it is a valid u8. + let end = unsafe { Step::forward_unchecked(start.to_u8(), count) }; + + // SAFETY: Caller asserts that result is a valid ASCII character. + unsafe { AsciiChar::from_u8_unchecked(end) } + } + + #[inline] + unsafe fn backward_unchecked(start: AsciiChar, count: usize) -> AsciiChar { + // SAFETY: Caller asserts that result is a valid ASCII character, + // and therefore it is a valid u8. + let end = unsafe { Step::backward_unchecked(start.to_u8(), count) }; + + // SAFETY: Caller asserts that result is a valid ASCII character. + unsafe { AsciiChar::from_u8_unchecked(end) } + } +} + macro_rules! range_exact_iter_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index f39c4176440..b97cb652076 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -152,7 +152,6 @@ #![feature(const_slice_from_raw_parts_mut)] #![feature(const_slice_from_ref)] #![feature(const_slice_index)] -#![feature(const_slice_is_ascii)] #![feature(const_slice_ptr_len)] #![feature(const_slice_split_at_mut)] #![feature(const_str_from_utf8_unchecked_mut)] diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 5939dedbd1d..7f8d673c179 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -41,6 +41,20 @@ macro_rules! nonzero_integers { /// with the exception that `0` is not a valid instance. #[doc = concat!("`Option<", stringify!($Ty), ">` is guaranteed to be compatible with `", stringify!($Int), "`,")] /// including in FFI. + /// + /// Thanks to the [null pointer optimization], + #[doc = concat!("`", stringify!($Ty), "` and `Option<", stringify!($Ty), ">`")] + /// are guaranteed to have the same size and alignment: + /// + /// ``` + /// # use std::mem::{size_of, align_of}; + #[doc = concat!("use std::num::", stringify!($Ty), ";")] + /// + #[doc = concat!("assert_eq!(size_of::<", stringify!($Ty), ">(), size_of::<Option<", stringify!($Ty), ">>());")] + #[doc = concat!("assert_eq!(align_of::<", stringify!($Ty), ">(), align_of::<Option<", stringify!($Ty), ">>());")] + /// ``` + /// + /// [null pointer optimization]: crate::option#representation #[$stability] #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] diff --git a/library/core/src/num/saturating.rs b/library/core/src/num/saturating.rs index 8982473b2dc..e9f794e7d62 100644 --- a/library/core/src/num/saturating.rs +++ b/library/core/src/num/saturating.rs @@ -35,6 +35,7 @@ use crate::ops::{Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign}; #[unstable(feature = "saturating_int_impl", issue = "87920")] #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)] #[repr(transparent)] +#[rustc_diagnostic_item = "Saturating"] pub struct Saturating<T>(#[unstable(feature = "saturating_int_impl", issue = "87920")] pub T); #[unstable(feature = "saturating_int_impl", issue = "87920")] diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs index ed354a2e50b..16f0b6d913d 100644 --- a/library/core/src/num/wrapping.rs +++ b/library/core/src/num/wrapping.rs @@ -39,6 +39,7 @@ use crate::ops::{Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign}; #[stable(feature = "rust1", since = "1.0.0")] #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)] #[repr(transparent)] +#[rustc_diagnostic_item = "Wrapping"] pub struct Wrapping<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T); #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/option.rs b/library/core/src/option.rs index becb6330997..f2909a81d49 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -119,7 +119,7 @@ //! # Representation //! //! Rust guarantees to optimize the following types `T` such that -//! [`Option<T>`] has the same size as `T`: +//! [`Option<T>`] has the same size and alignment as `T`: //! //! * [`Box<U>`] //! * `&U` diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index e0fd347a049..6b3c4343ed3 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -43,9 +43,27 @@ use crate::slice::{self, SliceIndex}; /// it is your responsibility to ensure that `as_mut` is never called, and `as_ptr` /// is never used for mutation. /// +/// # Representation +/// +/// Thanks to the [null pointer optimization], +/// `NonNull<T>` and `Option<NonNull<T>>` +/// are guaranteed to have the same size and alignment: +/// +/// ``` +/// # use std::mem::{size_of, align_of}; +/// use std::ptr::NonNull; +/// +/// assert_eq!(size_of::<NonNull<i16>>(), size_of::<Option<NonNull<i16>>>()); +/// assert_eq!(align_of::<NonNull<i16>>(), align_of::<Option<NonNull<i16>>>()); +/// +/// assert_eq!(size_of::<NonNull<str>>(), size_of::<Option<NonNull<str>>>()); +/// assert_eq!(align_of::<NonNull<str>>(), align_of::<Option<NonNull<str>>>()); +/// ``` +/// /// [covariant]: https://doc.rust-lang.org/reference/subtyping.html /// [`PhantomData`]: crate::marker::PhantomData /// [`UnsafeCell<T>`]: crate::cell::UnsafeCell +/// [null pointer optimization]: crate::option#representation #[stable(feature = "nonnull", since = "1.25.0")] #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index f3311f76a7f..5dc53caba0d 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -10,7 +10,7 @@ use crate::ops; impl [u8] { /// Checks if all bytes in this slice are within the ASCII range. #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_slice_is_ascii", issue = "111090")] + #[rustc_const_stable(feature = "const_slice_is_ascii", since = "CURRENT_RUSTC_VERSION")] #[must_use] #[inline] pub const fn is_ascii(&self) -> bool { diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 23cebdb6c3b..d5b0ab92c09 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2322,7 +2322,7 @@ impl str { /// assert!(!non_ascii.is_ascii()); /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_slice_is_ascii", issue = "111090")] + #[rustc_const_stable(feature = "const_slice_is_ascii", since = "CURRENT_RUSTC_VERSION")] #[must_use] #[inline] pub const fn is_ascii(&self) -> bool { diff --git a/library/core/tests/iter/range.rs b/library/core/tests/iter/range.rs index 0a77ecddb84..5b87d6c1fa0 100644 --- a/library/core/tests/iter/range.rs +++ b/library/core/tests/iter/range.rs @@ -1,5 +1,6 @@ -use core::num::NonZeroUsize; use super::*; +use core::ascii::Char as AsciiChar; +use core::num::NonZeroUsize; #[test] fn test_range() { @@ -40,6 +41,21 @@ fn test_char_range() { } #[test] +fn test_ascii_char_range() { + let from = AsciiChar::Null; + let to = AsciiChar::Delete; + assert!((from..=to).eq((from as u8..=to as u8).filter_map(AsciiChar::from_u8))); + assert!((from..=to).rev().eq((from as u8..=to as u8).filter_map(AsciiChar::from_u8).rev())); + + assert_eq!((AsciiChar::CapitalA..=AsciiChar::CapitalZ).count(), 26); + assert_eq!((AsciiChar::CapitalA..=AsciiChar::CapitalZ).size_hint(), (26, Some(26))); + assert_eq!((AsciiChar::SmallA..=AsciiChar::SmallZ).count(), 26); + assert_eq!((AsciiChar::SmallA..=AsciiChar::SmallZ).size_hint(), (26, Some(26))); + assert_eq!((AsciiChar::Digit0..=AsciiChar::Digit9).count(), 10); + assert_eq!((AsciiChar::Digit0..=AsciiChar::Digit9).size_hint(), (10, Some(10))); +} + +#[test] fn test_range_exhaustion() { let mut r = 10..10; assert!(r.is_empty()); diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 7a6def37a55..17011b845cf 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -2,6 +2,8 @@ #![feature(array_chunks)] #![feature(array_methods)] #![feature(array_windows)] +#![feature(ascii_char)] +#![feature(ascii_char_variants)] #![feature(bigint_helper_methods)] #![feature(cell_update)] #![feature(const_align_offset)] diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs index ee9f6ed087c..97e78d17786 100644 --- a/library/std/src/ffi/mod.rs +++ b/library/std/src/ffi/mod.rs @@ -132,8 +132,8 @@ //! On all platforms, [`OsStr`] consists of a sequence of bytes that is encoded as a superset of //! UTF-8; see [`OsString`] for more details on its encoding on different platforms. //! -//! For limited, inexpensive conversions from and to bytes, see [`OsStr::as_os_str_bytes`] and -//! [`OsStr::from_os_str_bytes_unchecked`]. +//! For limited, inexpensive conversions from and to bytes, see [`OsStr::as_encoded_bytes`] and +//! [`OsStr::from_encoded_bytes_unchecked`]. //! //! [Unicode scalar value]: https://www.unicode.org/glossary/#unicode_scalar_value //! [Unicode code point]: https://www.unicode.org/glossary/#code_point diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 43cecb19b14..93b9bf0cc20 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -154,36 +154,34 @@ impl OsString { /// # Safety /// /// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of - /// validated UTF-8 and bytes from [`OsStr::as_os_str_bytes`] from within the same rust version + /// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same rust version /// built for the same target platform. For example, reconstructing an `OsString` from bytes sent /// over the network or stored in a file will likely violate these safety rules. /// - /// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_os_str_bytes`] can be + /// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_encoded_bytes`] can be /// split either immediately before or immediately after any valid non-empty UTF-8 substring. /// /// # Example /// /// ``` - /// #![feature(os_str_bytes)] - /// /// use std::ffi::OsStr; /// /// let os_str = OsStr::new("Mary had a little lamb"); - /// let bytes = os_str.as_os_str_bytes(); + /// let bytes = os_str.as_encoded_bytes(); /// let words = bytes.split(|b| *b == b' '); /// let words: Vec<&OsStr> = words.map(|word| { /// // SAFETY: - /// // - Each `word` only contains content that originated from `OsStr::as_os_str_bytes` + /// // - Each `word` only contains content that originated from `OsStr::as_encoded_bytes` /// // - Only split with ASCII whitespace which is a non-empty UTF-8 substring - /// unsafe { OsStr::from_os_str_bytes_unchecked(word) } + /// unsafe { OsStr::from_encoded_bytes_unchecked(word) } /// }).collect(); /// ``` /// /// [conversions]: super#conversions #[inline] - #[unstable(feature = "os_str_bytes", issue = "111544")] - pub unsafe fn from_os_str_bytes_unchecked(bytes: Vec<u8>) -> Self { - OsString { inner: Buf::from_os_str_bytes_unchecked(bytes) } + #[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")] + pub unsafe fn from_encoded_bytes_unchecked(bytes: Vec<u8>) -> Self { + OsString { inner: Buf::from_encoded_bytes_unchecked(bytes) } } /// Converts to an [`OsStr`] slice. @@ -205,7 +203,7 @@ impl OsString { } /// Converts the `OsString` into a byte slice. To convert the byte slice back into an - /// `OsString`, use the [`OsStr::from_os_str_bytes_unchecked`] function. + /// `OsString`, use the [`OsStr::from_encoded_bytes_unchecked`] function. /// /// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8. /// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit @@ -219,9 +217,9 @@ impl OsString { /// /// [`std::ffi`]: crate::ffi #[inline] - #[unstable(feature = "os_str_bytes", issue = "111544")] - pub fn into_os_str_bytes(self) -> Vec<u8> { - self.inner.into_os_str_bytes() + #[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")] + pub fn into_encoded_bytes(self) -> Vec<u8> { + self.inner.into_encoded_bytes() } /// Converts the `OsString` into a [`String`] if it contains valid Unicode data. @@ -745,36 +743,34 @@ impl OsStr { /// # Safety /// /// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of - /// validated UTF-8 and bytes from [`OsStr::as_os_str_bytes`] from within the same rust version + /// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same rust version /// built for the same target platform. For example, reconstructing an `OsStr` from bytes sent /// over the network or stored in a file will likely violate these safety rules. /// - /// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_os_str_bytes`] can be + /// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_encoded_bytes`] can be /// split either immediately before or immediately after any valid non-empty UTF-8 substring. /// /// # Example /// /// ``` - /// #![feature(os_str_bytes)] - /// /// use std::ffi::OsStr; /// /// let os_str = OsStr::new("Mary had a little lamb"); - /// let bytes = os_str.as_os_str_bytes(); + /// let bytes = os_str.as_encoded_bytes(); /// let words = bytes.split(|b| *b == b' '); /// let words: Vec<&OsStr> = words.map(|word| { /// // SAFETY: - /// // - Each `word` only contains content that originated from `OsStr::as_os_str_bytes` + /// // - Each `word` only contains content that originated from `OsStr::as_encoded_bytes` /// // - Only split with ASCII whitespace which is a non-empty UTF-8 substring - /// unsafe { OsStr::from_os_str_bytes_unchecked(word) } + /// unsafe { OsStr::from_encoded_bytes_unchecked(word) } /// }).collect(); /// ``` /// /// [conversions]: super#conversions #[inline] - #[unstable(feature = "os_str_bytes", issue = "111544")] - pub unsafe fn from_os_str_bytes_unchecked(bytes: &[u8]) -> &Self { - Self::from_inner(Slice::from_os_str_bytes_unchecked(bytes)) + #[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")] + pub unsafe fn from_encoded_bytes_unchecked(bytes: &[u8]) -> &Self { + Self::from_inner(Slice::from_encoded_bytes_unchecked(bytes)) } #[inline] @@ -948,7 +944,7 @@ impl OsStr { } /// Converts an OS string slice to a byte slice. To convert the byte slice back into an OS - /// string slice, use the [`OsStr::from_os_str_bytes_unchecked`] function. + /// string slice, use the [`OsStr::from_encoded_bytes_unchecked`] function. /// /// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8. /// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit @@ -962,9 +958,9 @@ impl OsStr { /// /// [`std::ffi`]: crate::ffi #[inline] - #[unstable(feature = "os_str_bytes", issue = "111544")] - pub fn as_os_str_bytes(&self) -> &[u8] { - self.inner.as_os_str_bytes() + #[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")] + pub fn as_encoded_bytes(&self) -> &[u8] { + self.inner.as_encoded_bytes() } /// Converts this string to its ASCII lower case equivalent in-place. @@ -1270,7 +1266,7 @@ impl Default for &OsStr { impl PartialEq for OsStr { #[inline] fn eq(&self, other: &OsStr) -> bool { - self.as_os_str_bytes().eq(other.as_os_str_bytes()) + self.as_encoded_bytes().eq(other.as_encoded_bytes()) } } @@ -1297,23 +1293,23 @@ impl Eq for OsStr {} impl PartialOrd for OsStr { #[inline] fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> { - self.as_os_str_bytes().partial_cmp(other.as_os_str_bytes()) + self.as_encoded_bytes().partial_cmp(other.as_encoded_bytes()) } #[inline] fn lt(&self, other: &OsStr) -> bool { - self.as_os_str_bytes().lt(other.as_os_str_bytes()) + self.as_encoded_bytes().lt(other.as_encoded_bytes()) } #[inline] fn le(&self, other: &OsStr) -> bool { - self.as_os_str_bytes().le(other.as_os_str_bytes()) + self.as_encoded_bytes().le(other.as_encoded_bytes()) } #[inline] fn gt(&self, other: &OsStr) -> bool { - self.as_os_str_bytes().gt(other.as_os_str_bytes()) + self.as_encoded_bytes().gt(other.as_encoded_bytes()) } #[inline] fn ge(&self, other: &OsStr) -> bool { - self.as_os_str_bytes().ge(other.as_os_str_bytes()) + self.as_encoded_bytes().ge(other.as_encoded_bytes()) } } @@ -1332,7 +1328,7 @@ impl PartialOrd<str> for OsStr { impl Ord for OsStr { #[inline] fn cmp(&self, other: &OsStr) -> cmp::Ordering { - self.as_os_str_bytes().cmp(other.as_os_str_bytes()) + self.as_encoded_bytes().cmp(other.as_encoded_bytes()) } } @@ -1382,7 +1378,7 @@ impl_cmp!(Cow<'a, OsStr>, OsString); impl Hash for OsStr { #[inline] fn hash<H: Hasher>(&self, state: &mut H) { - self.as_os_str_bytes().hash(state) + self.as_encoded_bytes().hash(state) } } diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 3c67bea7a22..adc1b85fd85 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -233,8 +233,8 @@ pub struct DirBuilder { /// This function will return an error if `path` does not already exist. /// Other errors may also be returned according to [`OpenOptions::open`]. /// -/// It will also return an error if it encounters while reading an error -/// of a kind other than [`io::ErrorKind::Interrupted`]. +/// While reading from the file, this function handles [`io::ErrorKind::Interrupted`] +/// with automatic retries. See [io::Read] documentation for details. /// /// # Examples /// @@ -271,9 +271,11 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> { /// This function will return an error if `path` does not already exist. /// Other errors may also be returned according to [`OpenOptions::open`]. /// -/// It will also return an error if it encounters while reading an error -/// of a kind other than [`io::ErrorKind::Interrupted`], -/// or if the contents of the file are not valid UTF-8. +/// If the contents of the file are not valid UTF-8, then an error will also be +/// returned. +/// +/// While reading from the file, this function handles [`io::ErrorKind::Interrupted`] +/// with automatic retries. See [io::Read] documentation for details. /// /// # Examples /// diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 5842c096f1a..60562f64c90 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -193,7 +193,7 @@ impl<'a> Prefix<'a> { fn len(&self) -> usize { use self::Prefix::*; fn os_str_len(s: &OsStr) -> usize { - s.as_os_str_bytes().len() + s.as_encoded_bytes().len() } match *self { Verbatim(x) => 4 + os_str_len(x), @@ -316,7 +316,7 @@ fn has_physical_root(s: &[u8], prefix: Option<Prefix<'_>>) -> bool { // basic workhorse for splitting stem and extension fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) { - if file.as_os_str_bytes() == b".." { + if file.as_encoded_bytes() == b".." { return (Some(file), None); } @@ -324,7 +324,7 @@ fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) { // and back. This is safe to do because (1) we only look at ASCII // contents of the encoding and (2) new &OsStr values are produced // only from ASCII-bounded slices of existing &OsStr values. - let mut iter = file.as_os_str_bytes().rsplitn(2, |b| *b == b'.'); + let mut iter = file.as_encoded_bytes().rsplitn(2, |b| *b == b'.'); let after = iter.next(); let before = iter.next(); if before == Some(b"") { @@ -332,15 +332,15 @@ fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) { } else { unsafe { ( - before.map(|s| OsStr::from_os_str_bytes_unchecked(s)), - after.map(|s| OsStr::from_os_str_bytes_unchecked(s)), + before.map(|s| OsStr::from_encoded_bytes_unchecked(s)), + after.map(|s| OsStr::from_encoded_bytes_unchecked(s)), ) } } } fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) { - let slice = file.as_os_str_bytes(); + let slice = file.as_encoded_bytes(); if slice == b".." { return (file, None); } @@ -357,8 +357,8 @@ fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) { let after = &slice[i + 1..]; unsafe { ( - OsStr::from_os_str_bytes_unchecked(before), - Some(OsStr::from_os_str_bytes_unchecked(after)), + OsStr::from_encoded_bytes_unchecked(before), + Some(OsStr::from_encoded_bytes_unchecked(after)), ) } } @@ -739,7 +739,7 @@ impl<'a> Components<'a> { // separately via `include_cur_dir` b".." => Some(Component::ParentDir), b"" => None, - _ => Some(Component::Normal(unsafe { OsStr::from_os_str_bytes_unchecked(comp) })), + _ => Some(Component::Normal(unsafe { OsStr::from_encoded_bytes_unchecked(comp) })), } } @@ -896,7 +896,7 @@ impl<'a> Iterator for Components<'a> { let raw = &self.path[..self.prefix_len()]; self.path = &self.path[self.prefix_len()..]; return Some(Component::Prefix(PrefixComponent { - raw: unsafe { OsStr::from_os_str_bytes_unchecked(raw) }, + raw: unsafe { OsStr::from_encoded_bytes_unchecked(raw) }, parsed: self.prefix.unwrap(), })); } @@ -968,7 +968,7 @@ impl<'a> DoubleEndedIterator for Components<'a> { State::Prefix if self.prefix_len() > 0 => { self.back = State::Done; return Some(Component::Prefix(PrefixComponent { - raw: unsafe { OsStr::from_os_str_bytes_unchecked(self.path) }, + raw: unsafe { OsStr::from_encoded_bytes_unchecked(self.path) }, parsed: self.prefix.unwrap(), })); } @@ -1477,17 +1477,17 @@ impl PathBuf { fn _set_extension(&mut self, extension: &OsStr) -> bool { let file_stem = match self.file_stem() { None => return false, - Some(f) => f.as_os_str_bytes(), + Some(f) => f.as_encoded_bytes(), }; // truncate until right after the file stem let end_file_stem = file_stem[file_stem.len()..].as_ptr().addr(); - let start = self.inner.as_os_str_bytes().as_ptr().addr(); + let start = self.inner.as_encoded_bytes().as_ptr().addr(); let v = self.as_mut_vec(); v.truncate(end_file_stem.wrapping_sub(start)); // add the new extension, if any - let new = extension.as_os_str_bytes(); + let new = extension.as_encoded_bytes(); if !new.is_empty() { v.reserve_exact(new.len() + 1); v.push(b'.'); @@ -2007,11 +2007,11 @@ impl Path { // The following (private!) function allows construction of a path from a u8 // slice, which is only safe when it is known to follow the OsStr encoding. unsafe fn from_u8_slice(s: &[u8]) -> &Path { - unsafe { Path::new(OsStr::from_os_str_bytes_unchecked(s)) } + unsafe { Path::new(OsStr::from_encoded_bytes_unchecked(s)) } } // The following (private!) function reveals the byte encoding used for OsStr. fn as_u8_slice(&self) -> &[u8] { - self.inner.as_os_str_bytes() + self.inner.as_encoded_bytes() } /// Directly wraps a string slice as a `Path` slice. @@ -2609,7 +2609,7 @@ impl Path { fn _with_extension(&self, extension: &OsStr) -> PathBuf { let self_len = self.as_os_str().len(); - let self_bytes = self.as_os_str().as_os_str_bytes(); + let self_bytes = self.as_os_str().as_encoded_bytes(); let (new_capacity, slice_to_copy) = match self.extension() { None => { diff --git a/library/std/src/sys/common/small_c_string.rs b/library/std/src/sys/common/small_c_string.rs index 963d17a47e4..af9b18e372d 100644 --- a/library/std/src/sys/common/small_c_string.rs +++ b/library/std/src/sys/common/small_c_string.rs @@ -19,7 +19,7 @@ pub fn run_path_with_cstr<T, F>(path: &Path, f: F) -> io::Result<T> where F: FnOnce(&CStr) -> io::Result<T>, { - run_with_cstr(path.as_os_str().as_os_str_bytes(), f) + run_with_cstr(path.as_os_str().as_encoded_bytes(), f) } #[inline] diff --git a/library/std/src/sys/common/tests.rs b/library/std/src/sys/common/tests.rs index 0a1cbcbe8ef..32dc18ee1cf 100644 --- a/library/std/src/sys/common/tests.rs +++ b/library/std/src/sys/common/tests.rs @@ -8,7 +8,7 @@ use core::iter::repeat; fn stack_allocation_works() { let path = Path::new("abc"); let result = run_path_with_cstr(path, |p| { - assert_eq!(p, &*CString::new(path.as_os_str().as_os_str_bytes()).unwrap()); + assert_eq!(p, &*CString::new(path.as_os_str().as_encoded_bytes()).unwrap()); Ok(42) }); assert_eq!(result.unwrap(), 42); @@ -25,7 +25,7 @@ fn heap_allocation_works() { let path = repeat("a").take(384).collect::<String>(); let path = Path::new(&path); let result = run_path_with_cstr(path, |p| { - assert_eq!(p, &*CString::new(path.as_os_str().as_os_str_bytes()).unwrap()); + assert_eq!(p, &*CString::new(path.as_os_str().as_encoded_bytes()).unwrap()); Ok(42) }); assert_eq!(result.unwrap(), 42); diff --git a/library/std/src/sys/solid/error.rs b/library/std/src/sys/solid/error.rs index d1877a8bcd2..547b4f3a984 100644 --- a/library/std/src/sys/solid/error.rs +++ b/library/std/src/sys/solid/error.rs @@ -31,11 +31,6 @@ pub fn error_name(er: abi::ER) -> Option<&'static str> { } } -#[inline] -fn is_interrupted(er: abi::ER) -> bool { - false -} - pub fn decode_error_kind(er: abi::ER) -> ErrorKind { match er { // Success diff --git a/library/std/src/sys/solid/mod.rs b/library/std/src/sys/solid/mod.rs index e7029174511..5af83653cf8 100644 --- a/library/std/src/sys/solid/mod.rs +++ b/library/std/src/sys/solid/mod.rs @@ -74,7 +74,7 @@ pub fn unsupported_err() -> crate::io::Error { #[inline] pub fn is_interrupted(code: i32) -> bool { - error::is_interrupted(code) + net::is_interrupted(code) } pub fn decode_error_kind(code: i32) -> crate::io::ErrorKind { diff --git a/library/std/src/sys/solid/net.rs b/library/std/src/sys/solid/net.rs index bdd64ab02b7..6adced787f3 100644 --- a/library/std/src/sys/solid/net.rs +++ b/library/std/src/sys/solid/net.rs @@ -183,8 +183,7 @@ pub(super) fn error_name(er: abi::ER) -> Option<&'static str> { #[inline] pub fn is_interrupted(er: abi::ER) -> bool { - let errno = netc::SOLID_NET_ERR_BASE - er; - errno as libc::c_int == libc::EINTR + er == netc::SOLID_NET_ERR_BASE - libc::EINTR } pub(super) fn decode_error_kind(er: abi::ER) -> ErrorKind { diff --git a/library/std/src/sys/unix/os_str.rs b/library/std/src/sys/unix/os_str.rs index 463b0a27515..7bd2f656a24 100644 --- a/library/std/src/sys/unix/os_str.rs +++ b/library/std/src/sys/unix/os_str.rs @@ -97,12 +97,12 @@ impl AsInner<[u8]> for Buf { impl Buf { #[inline] - pub fn into_os_str_bytes(self) -> Vec<u8> { + pub fn into_encoded_bytes(self) -> Vec<u8> { self.inner } #[inline] - pub unsafe fn from_os_str_bytes_unchecked(s: Vec<u8>) -> Self { + pub unsafe fn from_encoded_bytes_unchecked(s: Vec<u8>) -> Self { Self { inner: s } } @@ -203,18 +203,18 @@ impl Buf { impl Slice { #[inline] - pub fn as_os_str_bytes(&self) -> &[u8] { + pub fn as_encoded_bytes(&self) -> &[u8] { &self.inner } #[inline] - pub unsafe fn from_os_str_bytes_unchecked(s: &[u8]) -> &Slice { + pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice { unsafe { mem::transmute(s) } } #[inline] pub fn from_str(s: &str) -> &Slice { - unsafe { Slice::from_os_str_bytes_unchecked(s.as_bytes()) } + unsafe { Slice::from_encoded_bytes_unchecked(s.as_bytes()) } } pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> { diff --git a/library/std/src/sys/unix/os_str/tests.rs b/library/std/src/sys/unix/os_str/tests.rs index 91bc0e61a4a..e2a99045e41 100644 --- a/library/std/src/sys/unix/os_str/tests.rs +++ b/library/std/src/sys/unix/os_str/tests.rs @@ -2,7 +2,7 @@ use super::*; #[test] fn slice_debug_output() { - let input = unsafe { Slice::from_os_str_bytes_unchecked(b"\xF0hello,\tworld") }; + let input = unsafe { Slice::from_encoded_bytes_unchecked(b"\xF0hello,\tworld") }; let expected = r#""\xF0hello,\tworld""#; let output = format!("{input:?}"); @@ -12,6 +12,6 @@ fn slice_debug_output() { #[test] fn display() { assert_eq!("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye", unsafe { - Slice::from_os_str_bytes_unchecked(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string() + Slice::from_encoded_bytes_unchecked(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string() },); } diff --git a/library/std/src/sys/unix/path.rs b/library/std/src/sys/unix/path.rs index 935245f637b..837f68d3eaf 100644 --- a/library/std/src/sys/unix/path.rs +++ b/library/std/src/sys/unix/path.rs @@ -30,7 +30,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> { // Get the components, skipping the redundant leading "." component if it exists. let mut components = path.strip_prefix(".").unwrap_or(path).components(); - let path_os = path.as_os_str().as_os_str_bytes(); + let path_os = path.as_os_str().as_encoded_bytes(); let mut normalized = if path.is_absolute() { // "If a pathname begins with two successive <slash> characters, the diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs index 640648e8707..e7d1533f122 100644 --- a/library/std/src/sys/unix/process/process_common.rs +++ b/library/std/src/sys/unix/process/process_common.rs @@ -164,9 +164,9 @@ pub enum ProgramKind { impl ProgramKind { fn new(program: &OsStr) -> Self { - if program.as_os_str_bytes().starts_with(b"/") { + if program.as_encoded_bytes().starts_with(b"/") { Self::Absolute - } else if program.as_os_str_bytes().contains(&b'/') { + } else if program.as_encoded_bytes().contains(&b'/') { // If the program has more than one component in it, it is a relative path. Self::Relative } else { diff --git a/library/std/src/sys/windows/args.rs b/library/std/src/sys/windows/args.rs index 6b597f499bc..ee7dba6e5b3 100644 --- a/library/std/src/sys/windows/args.rs +++ b/library/std/src/sys/windows/args.rs @@ -226,7 +226,7 @@ pub(crate) fn append_arg(cmd: &mut Vec<u16>, arg: &Arg, force_quotes: bool) -> i // that it actually gets passed through on the command line or otherwise // it will be dropped entirely when parsed on the other end. ensure_no_nuls(arg)?; - let arg_bytes = arg.as_os_str_bytes(); + let arg_bytes = arg.as_encoded_bytes(); let (quote, escape) = match quote { Quote::Always => (true, true), Quote::Auto => { @@ -298,7 +298,7 @@ pub(crate) fn make_bat_command_line( const SPECIAL: &[u8] = b"\t &()[]{}^=;!'+,`~%|<>"; let force_quotes = match arg { Arg::Regular(arg) if !force_quotes => { - arg.as_os_str_bytes().iter().any(|c| SPECIAL.contains(c)) + arg.as_encoded_bytes().iter().any(|c| SPECIAL.contains(c)) } _ => force_quotes, }; diff --git a/library/std/src/sys/windows/os_str.rs b/library/std/src/sys/windows/os_str.rs index 4708657a907..237854fac4e 100644 --- a/library/std/src/sys/windows/os_str.rs +++ b/library/std/src/sys/windows/os_str.rs @@ -64,12 +64,12 @@ impl fmt::Display for Slice { impl Buf { #[inline] - pub fn into_os_str_bytes(self) -> Vec<u8> { + pub fn into_encoded_bytes(self) -> Vec<u8> { self.inner.into_bytes() } #[inline] - pub unsafe fn from_os_str_bytes_unchecked(s: Vec<u8>) -> Self { + pub unsafe fn from_encoded_bytes_unchecked(s: Vec<u8>) -> Self { Self { inner: Wtf8Buf::from_bytes_unchecked(s) } } @@ -162,12 +162,12 @@ impl Buf { impl Slice { #[inline] - pub fn as_os_str_bytes(&self) -> &[u8] { + pub fn as_encoded_bytes(&self) -> &[u8] { self.inner.as_bytes() } #[inline] - pub unsafe fn from_os_str_bytes_unchecked(s: &[u8]) -> &Slice { + pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice { mem::transmute(Wtf8::from_bytes_unchecked(s)) } diff --git a/library/std/src/sys/windows/path.rs b/library/std/src/sys/windows/path.rs index c9c2d10e6c4..8c0e07b3566 100644 --- a/library/std/src/sys/windows/path.rs +++ b/library/std/src/sys/windows/path.rs @@ -22,12 +22,12 @@ pub fn is_verbatim_sep(b: u8) -> bool { /// Returns true if `path` looks like a lone filename. pub(crate) fn is_file_name(path: &OsStr) -> bool { - !path.as_os_str_bytes().iter().copied().any(is_sep_byte) + !path.as_encoded_bytes().iter().copied().any(is_sep_byte) } pub(crate) fn has_trailing_slash(path: &OsStr) -> bool { - let is_verbatim = path.as_os_str_bytes().starts_with(br"\\?\"); + let is_verbatim = path.as_encoded_bytes().starts_with(br"\\?\"); let is_separator = if is_verbatim { is_verbatim_sep } else { is_sep_byte }; - if let Some(&c) = path.as_os_str_bytes().last() { is_separator(c) } else { false } + if let Some(&c) = path.as_encoded_bytes().last() { is_separator(c) } else { false } } /// Appends a suffix to a path. @@ -49,7 +49,7 @@ impl<'a, const LEN: usize> PrefixParser<'a, LEN> { fn get_prefix(path: &OsStr) -> [u8; LEN] { let mut prefix = [0; LEN]; // SAFETY: Only ASCII characters are modified. - for (i, &ch) in path.as_os_str_bytes().iter().take(LEN).enumerate() { + for (i, &ch) in path.as_encoded_bytes().iter().take(LEN).enumerate() { prefix[i] = if ch == b'/' { b'\\' } else { ch }; } prefix @@ -82,7 +82,7 @@ impl<'a> PrefixParserSlice<'a, '_> { } fn prefix_bytes(&self) -> &'a [u8] { - &self.path.as_os_str_bytes()[..self.index] + &self.path.as_encoded_bytes()[..self.index] } fn finish(self) -> &'a OsStr { @@ -90,7 +90,7 @@ impl<'a> PrefixParserSlice<'a, '_> { // &[u8] and back. This is safe to do because (1) we only look at ASCII // contents of the encoding and (2) new &OsStr values are produced only // from ASCII-bounded slices of existing &OsStr values. - unsafe { OsStr::from_os_str_bytes_unchecked(&self.path.as_os_str_bytes()[self.index..]) } + unsafe { OsStr::from_encoded_bytes_unchecked(&self.path.as_encoded_bytes()[self.index..]) } } } @@ -162,7 +162,7 @@ fn parse_drive(path: &OsStr) -> Option<u8> { drive.is_ascii_alphabetic() } - match path.as_os_str_bytes() { + match path.as_encoded_bytes() { [drive, b':', ..] if is_valid_drive_letter(drive) => Some(drive.to_ascii_uppercase()), _ => None, } @@ -171,7 +171,7 @@ fn parse_drive(path: &OsStr) -> Option<u8> { // Parses a drive prefix exactly, e.g. "C:" fn parse_drive_exact(path: &OsStr) -> Option<u8> { // only parse two bytes: the drive letter and the drive separator - if path.as_os_str_bytes().get(2).map(|&x| is_sep_byte(x)).unwrap_or(true) { + if path.as_encoded_bytes().get(2).map(|&x| is_sep_byte(x)).unwrap_or(true) { parse_drive(path) } else { None @@ -185,15 +185,15 @@ fn parse_drive_exact(path: &OsStr) -> Option<u8> { fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) { let separator = if verbatim { is_verbatim_sep } else { is_sep_byte }; - match path.as_os_str_bytes().iter().position(|&x| separator(x)) { + match path.as_encoded_bytes().iter().position(|&x| separator(x)) { Some(separator_start) => { let separator_end = separator_start + 1; - let component = &path.as_os_str_bytes()[..separator_start]; + let component = &path.as_encoded_bytes()[..separator_start]; // Panic safe // The max `separator_end` is `bytes.len()` and `bytes[bytes.len()..]` is a valid index. - let path = &path.as_os_str_bytes()[separator_end..]; + let path = &path.as_encoded_bytes()[separator_end..]; // SAFETY: `path` is a valid wtf8 encoded slice and each of the separators ('/', '\') // is encoded in a single byte, therefore `bytes[separator_start]` and @@ -201,8 +201,8 @@ fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) { // `bytes[..separator_start]` and `bytes[separator_end..]` are valid wtf8 slices. unsafe { ( - OsStr::from_os_str_bytes_unchecked(component), - OsStr::from_os_str_bytes_unchecked(path), + OsStr::from_encoded_bytes_unchecked(component), + OsStr::from_encoded_bytes_unchecked(path), ) } } @@ -323,7 +323,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> { // Verbatim paths should not be modified. if prefix.map(|x| x.is_verbatim()).unwrap_or(false) { // NULs in verbatim paths are rejected for consistency. - if path.as_os_str_bytes().contains(&0) { + if path.as_encoded_bytes().contains(&0) { return Err(io::const_io_error!( io::ErrorKind::InvalidInput, "strings passed to WinAPI cannot contain NULs", diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index 92edd2f6112..6f46da1748a 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -429,7 +429,7 @@ fn resolve_exe<'a>( // Test if the file name has the `exe` extension. // This does a case-insensitive `ends_with`. let has_exe_suffix = if exe_path.len() >= EXE_SUFFIX.len() { - exe_path.as_os_str_bytes()[exe_path.len() - EXE_SUFFIX.len()..] + exe_path.as_encoded_bytes()[exe_path.len() - EXE_SUFFIX.len()..] .eq_ignore_ascii_case(EXE_SUFFIX.as_bytes()) } else { false @@ -459,7 +459,7 @@ fn resolve_exe<'a>( // From the `CreateProcessW` docs: // > If the file name does not contain an extension, .exe is appended. // Note that this rule only applies when searching paths. - let has_extension = exe_path.as_os_str_bytes().contains(&b'.'); + let has_extension = exe_path.as_encoded_bytes().contains(&b'.'); // Search the directories given by `search_paths`. let result = search_paths(parent_paths, child_paths, |mut path| { diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs index c841cb34036..07502e0e9dd 100644 --- a/src/bootstrap/llvm.rs +++ b/src/bootstrap/llvm.rs @@ -24,6 +24,7 @@ use crate::util::{self, exe, output, t, up_to_date}; use crate::{CLang, GitRepo, Kind}; use build_helper::ci::CiEnv; +use build_helper::git::get_git_merge_base; #[derive(Clone)] pub struct LlvmResult { @@ -128,13 +129,19 @@ pub fn prebuilt_llvm_config( /// This retrieves the LLVM sha we *want* to use, according to git history. pub(crate) fn detect_llvm_sha(config: &Config, is_git: bool) -> String { let llvm_sha = if is_git { + // We proceed in 2 steps. First we get the closest commit that is actually upstream. Then we + // walk back further to the last bors merge commit that actually changed LLVM. The first + // step will fail on CI because only the `auto` branch exists; we just fall back to `HEAD` + // in that case. + let closest_upstream = + get_git_merge_base(Some(&config.src)).unwrap_or_else(|_| "HEAD".into()); let mut rev_list = config.git(); rev_list.args(&[ PathBuf::from("rev-list"), format!("--author={}", config.stage0_metadata.config.git_merge_commit_email).into(), "-n1".into(), "--first-parent".into(), - "HEAD".into(), + closest_upstream.into(), "--".into(), config.src.join("src/llvm-project"), config.src.join("src/bootstrap/download-ci-llvm-stamp"), diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 7e83b508e94..144e2acd09e 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -62,6 +62,9 @@ impl Finder { } pub fn check(build: &mut Build) { + let skip_target_sanity = + env::var_os("BOOTSTRAP_SKIP_TARGET_SANITY").is_some_and(|s| s == "1" || s == "true"); + let path = env::var_os("PATH").unwrap_or_default(); // On Windows, quotes are invalid characters for filename paths, and if // one is present as part of the PATH then that can lead to the system @@ -166,7 +169,7 @@ than building it. // FIXME: it would be better to refactor this code to split necessary setup from pure sanity // checks, and have a regular flag for skipping the latter. Also see // <https://github.com/rust-lang/rust/pull/103569#discussion_r1008741742>. - if env::var_os("BOOTSTRAP_SKIP_TARGET_SANITY").is_some() { + if skip_target_sanity { continue; } @@ -205,7 +208,15 @@ than building it. } } - // Make sure musl-root is valid + // Some environments don't want or need these tools, such as when testing Miri. + // FIXME: it would be better to refactor this code to split necessary setup from pure sanity + // checks, and have a regular flag for skipping the latter. Also see + // <https://github.com/rust-lang/rust/pull/103569#discussion_r1008741742>. + if skip_target_sanity { + continue; + } + + // Make sure musl-root is valid. if target.contains("musl") && !target.contains("unikraft") { // If this is a native target (host is also musl) and no musl-root is given, // fall back to the system toolchain in /usr before giving up @@ -227,14 +238,6 @@ than building it. } } - // Some environments don't want or need these tools, such as when testing Miri. - // FIXME: it would be better to refactor this code to split necessary setup from pure sanity - // checks, and have a regular flag for skipping the latter. Also see - // <https://github.com/rust-lang/rust/pull/103569#discussion_r1008741742>. - if env::var_os("BOOTSTRAP_SKIP_TARGET_SANITY").is_some() { - continue; - } - if need_cmake && target.contains("msvc") { // There are three builds of cmake on windows: MSVC, MinGW, and // Cygwin. The Cygwin build does not have generators for Visual diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index c1614d02f34..2cb0a8f3c17 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -63,8 +63,9 @@ Tools](#tier-1-with-host-tools). ## Tier 2 with Host Tools Tier 2 targets can be thought of as "guaranteed to build". The Rust project -builds official binary releases for each tier 2 target, and automated builds -ensure that each tier 2 target builds after each change. Automated tests are +builds official binary releases of the standard library (or, in some cases, +only the `core` library) for each tier 2 target, and automated builds +ensure that each tier 2 target can be used as build target after each change. Automated tests are not always run so it's not guaranteed to produce a working build, but tier 2 targets often work to quite a good degree and patches are always welcome! @@ -103,11 +104,12 @@ target | notes `x86_64-unknown-linux-musl` | 64-bit Linux with MUSL [`x86_64-unknown-netbsd`](platform-support/netbsd.md) | NetBSD/amd64 -## Tier 2 +## Tier 2 without Host Tools Tier 2 targets can be thought of as "guaranteed to build". The Rust project -builds official binary releases for each tier 2 target, and automated builds -ensure that each tier 2 target builds after each change. Automated tests are +builds official binary releases of the standard library (or, in some cases, +only the `core` library) for each tier 2 target, and automated builds +ensure that each tier 2 target can be used as build target after each change. Automated tests are not always run so it's not guaranteed to produce a working build, but tier 2 targets often work to quite a good degree and patches are always welcome! For the full requirements, see [Tier 2 target diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1e85284371d..b584c32a4c7 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1959,31 +1959,44 @@ fn can_elide_trait_object_lifetime_bound<'tcx>( #[derive(Debug)] pub(crate) enum ContainerTy<'tcx> { Ref(ty::Region<'tcx>), - Regular { ty: DefId, args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>, arg: usize }, + Regular { + ty: DefId, + args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>, + has_self: bool, + arg: usize, + }, } impl<'tcx> ContainerTy<'tcx> { fn object_lifetime_default(self, tcx: TyCtxt<'tcx>) -> ObjectLifetimeDefault<'tcx> { match self { Self::Ref(region) => ObjectLifetimeDefault::Arg(region), - Self::Regular { ty: container, args, arg: index } => { + Self::Regular { ty: container, args, has_self, arg: index } => { let (DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::TyAlias { .. } - | DefKind::Trait - | DefKind::AssocTy - | DefKind::Variant) = tcx.def_kind(container) + | DefKind::Trait) = tcx.def_kind(container) else { return ObjectLifetimeDefault::Empty; }; let generics = tcx.generics_of(container); - let param = generics.params[index].def_id; - let default = tcx.object_lifetime_default(param); + debug_assert_eq!(generics.parent_count, 0); + + // If the container is a trait object type, the arguments won't contain the self type but the + // generics of the corresponding trait will. In such a case, offset the index by one. + // For comparison, if the container is a trait inside a bound, the arguments do contain the + // self type. + let offset = + if !has_self && generics.parent.is_none() && generics.has_self { 1 } else { 0 }; + let param = generics.params[index + offset].def_id; + let default = tcx.object_lifetime_default(param); match default { rbv::ObjectLifetimeDefault::Param(lifetime) => { + // The index is relative to the parent generics but since we don't have any, + // we don't need to translate it. let index = generics.param_def_id_to_index[&lifetime]; let arg = args.skip_binder()[index as usize].expect_region(); ObjectLifetimeDefault::Arg(arg) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 9cf3c068b60..9134d5268da 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -22,6 +22,7 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::{BodyId, Mutability}; use rustc_hir_analysis::check::intrinsic::intrinsic_operation_unsafety; use rustc_index::IndexVec; +use rustc_metadata::rendered_const; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::{self, TyCtxt, Visibility}; use rustc_resolve::rustdoc::{add_doc_fragment, attrs_to_doc_fragments, inner_docs, DocFragment}; @@ -35,7 +36,7 @@ use rustc_target::spec::abi::Abi; use crate::clean::cfg::Cfg; use crate::clean::external_path; use crate::clean::inline::{self, print_inlined_const}; -use crate::clean::utils::{is_literal_expr, print_const_expr, print_evaluated_const}; +use crate::clean::utils::{is_literal_expr, print_evaluated_const}; use crate::core::DocContext; use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; @@ -2086,7 +2087,7 @@ impl Discriminant { /// Will be `None` in the case of cross-crate reexports, and may be /// simplified pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> Option<String> { - self.expr.map(|body| print_const_expr(tcx, body)) + self.expr.map(|body| rendered_const(tcx, body)) } /// Will always be a machine readable number, without underscores or suffixes. pub(crate) fn value(&self, tcx: TyCtxt<'_>) -> String { @@ -2326,7 +2327,7 @@ impl ConstantKind { ConstantKind::TyConst { ref expr } => expr.to_string(), ConstantKind::Extern { def_id } => print_inlined_const(tcx, def_id), ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => { - print_const_expr(tcx, body) + rendered_const(tcx, body) } } } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 80a7a33d2bd..7696ea0f449 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -14,6 +14,7 @@ use rustc_ast::tokenstream::TokenTree; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; +use rustc_metadata::rendered_const; use rustc_middle::mir; use rustc_middle::mir::interpret::ConstValue; use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, TyCtxt}; @@ -77,9 +78,10 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate { pub(crate) fn ty_args_to_args<'tcx>( cx: &mut DocContext<'tcx>, args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>, - mut skip_first: bool, + has_self: bool, container: Option<DefId>, ) -> Vec<GenericArg> { + let mut skip_first = has_self; let mut ret_val = Vec::with_capacity(args.skip_binder().len().saturating_sub(if skip_first { 1 } else { 0 })); @@ -99,6 +101,7 @@ pub(crate) fn ty_args_to_args<'tcx>( container.map(|container| crate::clean::ContainerTy::Regular { ty: container, args, + has_self, arg: index, }), ))), @@ -253,7 +256,7 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { match n.kind() { ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args: _ }) => { let s = if let Some(def) = def.as_local() { - print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def)) + rendered_const(cx.tcx, cx.tcx.hir().body_owned_by(def)) } else { inline::print_inlined_const(cx.tcx, def) }; @@ -365,100 +368,6 @@ pub(crate) fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { false } -/// Build a textual representation of an unevaluated constant expression. -/// -/// If the const expression is too complex, an underscore `_` is returned. -/// For const arguments, it's `{ _ }` to be precise. -/// This means that the output is not necessarily valid Rust code. -/// -/// Currently, only -/// -/// * literals (optionally with a leading `-`) -/// * unit `()` -/// * blocks (`{ … }`) around simple expressions and -/// * paths without arguments -/// -/// are considered simple enough. Simple blocks are included since they are -/// necessary to disambiguate unit from the unit type. -/// This list might get extended in the future. -/// -/// Without this censoring, in a lot of cases the output would get too large -/// and verbose. Consider `match` expressions, blocks and deeply nested ADTs. -/// Further, private and `doc(hidden)` fields of structs would get leaked -/// since HIR datatypes like the `body` parameter do not contain enough -/// semantic information for this function to be able to hide them – -/// at least not without significant performance overhead. -/// -/// Whenever possible, prefer to evaluate the constant first and try to -/// use a different method for pretty-printing. Ideally this function -/// should only ever be used as a fallback. -pub(crate) fn print_const_expr(tcx: TyCtxt<'_>, body: hir::BodyId) -> String { - let hir = tcx.hir(); - let value = &hir.body(body).value; - - #[derive(PartialEq, Eq)] - enum Classification { - Literal, - Simple, - Complex, - } - - use Classification::*; - - fn classify(expr: &hir::Expr<'_>) -> Classification { - match &expr.kind { - hir::ExprKind::Unary(hir::UnOp::Neg, expr) => { - if matches!(expr.kind, hir::ExprKind::Lit(_)) { Literal } else { Complex } - } - hir::ExprKind::Lit(_) => Literal, - hir::ExprKind::Tup([]) => Simple, - hir::ExprKind::Block(hir::Block { stmts: [], expr: Some(expr), .. }, _) => { - if classify(expr) == Complex { Complex } else { Simple } - } - // Paths with a self-type or arguments are too “complex” following our measure since - // they may leak private fields of structs (with feature `adt_const_params`). - // Consider: `<Self as Trait<{ Struct { private: () } }>>::CONSTANT`. - // Paths without arguments are definitely harmless though. - hir::ExprKind::Path(hir::QPath::Resolved(_, hir::Path { segments, .. })) => { - if segments.iter().all(|segment| segment.args.is_none()) { Simple } else { Complex } - } - // FIXME: Claiming that those kinds of QPaths are simple is probably not true if the Ty - // contains const arguments. Is there a *concise* way to check for this? - hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => Simple, - // FIXME: Can they contain const arguments and thus leak private struct fields? - hir::ExprKind::Path(hir::QPath::LangItem(..)) => Simple, - _ => Complex, - } - } - - let classification = classify(value); - - if classification == Literal - && !value.span.from_expansion() - && let Ok(snippet) = tcx.sess.source_map().span_to_snippet(value.span) { - // For literals, we avoid invoking the pretty-printer and use the source snippet instead to - // preserve certain stylistic choices the user likely made for the sake legibility like - // - // * hexadecimal notation - // * underscores - // * character escapes - // - // FIXME: This passes through `-/*spacer*/0` verbatim. - snippet - } else if classification == Simple { - // Otherwise we prefer pretty-printing to get rid of extraneous whitespace, comments and - // other formatting artifacts. - rustc_hir_pretty::id_to_string(&hir, body.hir_id) - } else if tcx.def_kind(hir.body_owner_def_id(body).to_def_id()) == DefKind::AnonConst { - // FIXME: Omit the curly braces if the enclosing expression is an array literal - // with a repeated element (an `ExprKind::Repeat`) as in such case it - // would not actually need any disambiguation. - "{ _ }".to_owned() - } else { - "_".to_owned() - } -} - /// Given a type Path, resolve it to a Type using the TyCtxt pub(crate) fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type { debug!("resolve_type({path:?})"); diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index f34be120d29..145c7d18dd0 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -1,10 +1,10 @@ use std::collections::hash_map::Entry; use std::collections::BTreeMap; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::Symbol; -use serde::ser::{Serialize, SerializeStruct, Serializer}; +use serde::ser::{Serialize, SerializeSeq, SerializeStruct, Serializer}; use crate::clean; use crate::clean::types::{Function, Generics, ItemId, Type, WherePredicate}; @@ -78,9 +78,9 @@ pub(crate) fn build_index<'tcx>( map: &mut FxHashMap<F, usize>, itemid: F, lastpathid: &mut usize, - crate_paths: &mut Vec<(ItemType, Symbol)>, + crate_paths: &mut Vec<(ItemType, Vec<Symbol>)>, item_type: ItemType, - path: Symbol, + path: &[Symbol], ) { match map.entry(itemid) { Entry::Occupied(entry) => ty.id = Some(RenderTypeId::Index(*entry.get())), @@ -88,7 +88,7 @@ pub(crate) fn build_index<'tcx>( let pathid = *lastpathid; entry.insert(pathid); *lastpathid += 1; - crate_paths.push((item_type, path)); + crate_paths.push((item_type, path.to_vec())); ty.id = Some(RenderTypeId::Index(pathid)); } } @@ -100,7 +100,7 @@ pub(crate) fn build_index<'tcx>( itemid_to_pathid: &mut FxHashMap<ItemId, usize>, primitives: &mut FxHashMap<Symbol, usize>, lastpathid: &mut usize, - crate_paths: &mut Vec<(ItemType, Symbol)>, + crate_paths: &mut Vec<(ItemType, Vec<Symbol>)>, ) { if let Some(generics) = &mut ty.generics { for item in generics { @@ -131,7 +131,7 @@ pub(crate) fn build_index<'tcx>( lastpathid, crate_paths, item_type, - *fqp.last().unwrap(), + fqp, ); } else { ty.id = None; @@ -146,7 +146,7 @@ pub(crate) fn build_index<'tcx>( lastpathid, crate_paths, ItemType::Primitive, - sym, + &[sym], ); } RenderTypeId::Index(_) => {} @@ -191,7 +191,7 @@ pub(crate) fn build_index<'tcx>( lastpathid += 1; if let Some(&(ref fqp, short)) = paths.get(&defid) { - crate_paths.push((short, *fqp.last().unwrap())); + crate_paths.push((short, fqp.clone())); Some(pathid) } else { None @@ -213,118 +213,163 @@ pub(crate) fn build_index<'tcx>( struct CrateData<'a> { doc: String, items: Vec<&'a IndexItem>, - paths: Vec<(ItemType, Symbol)>, + paths: Vec<(ItemType, Vec<Symbol>)>, // The String is alias name and the vec is the list of the elements with this alias. // // To be noted: the `usize` elements are indexes to `items`. aliases: &'a BTreeMap<String, Vec<usize>>, } + struct Paths { + ty: ItemType, + name: Symbol, + path: Option<usize>, + } + + impl Serialize for Paths { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let mut seq = serializer.serialize_seq(None)?; + seq.serialize_element(&self.ty)?; + seq.serialize_element(self.name.as_str())?; + if let Some(ref path) = self.path { + seq.serialize_element(path)?; + } + seq.end() + } + } + impl<'a> Serialize for CrateData<'a> { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { + let mut extra_paths = FxHashMap::default(); + // We need to keep the order of insertion, hence why we use an `IndexMap`. Then we will + // insert these "extra paths" (which are paths of items from external crates) into the + // `full_paths` list at the end. + let mut revert_extra_paths = FxIndexMap::default(); + let mut mod_paths = FxHashMap::default(); + for (index, item) in self.items.iter().enumerate() { + if item.path.is_empty() { + continue; + } + mod_paths.insert(&item.path, index); + } + let mut paths = Vec::with_capacity(self.paths.len()); + for (ty, path) in &self.paths { + if path.len() < 2 { + paths.push(Paths { ty: *ty, name: path[0], path: None }); + continue; + } + let full_path = join_with_double_colon(&path[..path.len() - 1]); + if let Some(index) = mod_paths.get(&full_path) { + paths.push(Paths { ty: *ty, name: *path.last().unwrap(), path: Some(*index) }); + continue; + } + // It means it comes from an external crate so the item and its path will be + // stored into another array. + // + // `index` is put after the last `mod_paths` + let index = extra_paths.len() + self.items.len(); + if !revert_extra_paths.contains_key(&index) { + revert_extra_paths.insert(index, full_path.clone()); + } + match extra_paths.entry(full_path) { + Entry::Occupied(entry) => { + paths.push(Paths { + ty: *ty, + name: *path.last().unwrap(), + path: Some(*entry.get()), + }); + } + Entry::Vacant(entry) => { + entry.insert(index); + paths.push(Paths { + ty: *ty, + name: *path.last().unwrap(), + path: Some(index), + }); + } + } + } + + let mut names = Vec::with_capacity(self.items.len()); + let mut types = String::with_capacity(self.items.len()); + let mut full_paths = Vec::with_capacity(self.items.len()); + let mut descriptions = Vec::with_capacity(self.items.len()); + let mut parents = Vec::with_capacity(self.items.len()); + let mut functions = Vec::with_capacity(self.items.len()); + let mut deprecated = Vec::with_capacity(self.items.len()); + + for (index, item) in self.items.iter().enumerate() { + let n = item.ty as u8; + let c = char::try_from(n + b'A').expect("item types must fit in ASCII"); + assert!(c <= 'z', "item types must fit within ASCII printables"); + types.push(c); + + assert_eq!( + item.parent.is_some(), + item.parent_idx.is_some(), + "`{}` is missing idx", + item.name + ); + // 0 is a sentinel, everything else is one-indexed + parents.push(item.parent_idx.map(|x| x + 1).unwrap_or(0)); + + names.push(item.name.as_str()); + descriptions.push(&item.desc); + + if !item.path.is_empty() { + full_paths.push((index, &item.path)); + } + + // Fake option to get `0` out as a sentinel instead of `null`. + // We want to use `0` because it's three less bytes. + enum FunctionOption<'a> { + Function(&'a IndexItemFunctionType), + None, + } + impl<'a> Serialize for FunctionOption<'a> { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + match self { + FunctionOption::None => 0.serialize(serializer), + FunctionOption::Function(ty) => ty.serialize(serializer), + } + } + } + functions.push(match &item.search_type { + Some(ty) => FunctionOption::Function(ty), + None => FunctionOption::None, + }); + + if item.deprecation.is_some() { + deprecated.push(index); + } + } + + for (index, path) in &revert_extra_paths { + full_paths.push((*index, path)); + } + let has_aliases = !self.aliases.is_empty(); let mut crate_data = serializer.serialize_struct("CrateData", if has_aliases { 9 } else { 8 })?; crate_data.serialize_field("doc", &self.doc)?; - crate_data.serialize_field( - "t", - &self - .items - .iter() - .map(|item| { - let n = item.ty as u8; - let c = char::try_from(n + b'A').expect("item types must fit in ASCII"); - assert!(c <= 'z', "item types must fit within ASCII printables"); - c - }) - .collect::<String>(), - )?; - crate_data.serialize_field( - "n", - &self.items.iter().map(|item| item.name.as_str()).collect::<Vec<_>>(), - )?; - crate_data.serialize_field( - "q", - &self - .items - .iter() - .enumerate() - // Serialize as an array of item indices and full paths - .filter_map( - |(index, item)| { - if item.path.is_empty() { None } else { Some((index, &item.path)) } - }, - ) - .collect::<Vec<_>>(), - )?; - crate_data.serialize_field( - "d", - &self.items.iter().map(|item| &item.desc).collect::<Vec<_>>(), - )?; - crate_data.serialize_field( - "i", - &self - .items - .iter() - .map(|item| { - assert_eq!( - item.parent.is_some(), - item.parent_idx.is_some(), - "`{}` is missing idx", - item.name - ); - // 0 is a sentinel, everything else is one-indexed - item.parent_idx.map(|x| x + 1).unwrap_or(0) - }) - .collect::<Vec<_>>(), - )?; - crate_data.serialize_field( - "f", - &self - .items - .iter() - .map(|item| { - // Fake option to get `0` out as a sentinel instead of `null`. - // We want to use `0` because it's three less bytes. - enum FunctionOption<'a> { - Function(&'a IndexItemFunctionType), - None, - } - impl<'a> Serialize for FunctionOption<'a> { - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> - where - S: Serializer, - { - match self { - FunctionOption::None => 0.serialize(serializer), - FunctionOption::Function(ty) => ty.serialize(serializer), - } - } - } - match &item.search_type { - Some(ty) => FunctionOption::Function(ty), - None => FunctionOption::None, - } - }) - .collect::<Vec<_>>(), - )?; - crate_data.serialize_field( - "c", - &self - .items - .iter() - .enumerate() - // Serialize as an array of deprecated item indices - .filter_map(|(index, item)| item.deprecation.map(|_| index)) - .collect::<Vec<_>>(), - )?; - crate_data.serialize_field( - "p", - &self.paths.iter().map(|(it, s)| (it, s.as_str())).collect::<Vec<_>>(), - )?; + crate_data.serialize_field("t", &types)?; + crate_data.serialize_field("n", &names)?; + // Serialize as an array of item indices and full paths + crate_data.serialize_field("q", &full_paths)?; + crate_data.serialize_field("d", &descriptions)?; + crate_data.serialize_field("i", &parents)?; + crate_data.serialize_field("f", &functions)?; + crate_data.serialize_field("c", &deprecated)?; + crate_data.serialize_field("p", &paths)?; if has_aliases { crate_data.serialize_field("a", &self.aliases)?; } diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 42088e73554..449168c460b 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -263,7 +263,6 @@ function initSearch(rawSearchIndex) { * @returns {integer} */ function buildTypeMapIndex(name) { - if (name === "" || name === null) { return -1; } @@ -1380,7 +1379,7 @@ function initSearch(rawSearchIndex) { * @type Map<integer, QueryElement[]> */ const queryElemSet = new Map(); - const addQueryElemToQueryElemSet = function addQueryElemToQueryElemSet(queryElem) { + const addQueryElemToQueryElemSet = queryElem => { let currentQueryElemList; if (queryElemSet.has(queryElem.id)) { currentQueryElemList = queryElemSet.get(queryElem.id); @@ -1397,7 +1396,7 @@ function initSearch(rawSearchIndex) { * @type Map<integer, FunctionType[]> */ const fnTypeSet = new Map(); - const addFnTypeToFnTypeSet = function addFnTypeToFnTypeSet(fnType) { + const addFnTypeToFnTypeSet = fnType => { // Pure generic, or an item that's not matched by any query elems. // Try [unboxing] it. // @@ -1463,6 +1462,32 @@ function initSearch(rawSearchIndex) { if (!typePassesFilter(queryElem.typeFilter, fnType.ty)) { continue; } + const queryElemPathLength = queryElem.pathWithoutLast.length; + // If the query element is a path (it contains `::`), we need to check if this + // path is compatible with the target type. + if (queryElemPathLength > 0) { + const fnTypePath = fnType.path !== undefined && fnType.path !== null ? + fnType.path.split("::") : []; + // If the path provided in the query element is longer than this type, + // no need to check it since it won't match in any case. + if (queryElemPathLength > fnTypePath.length) { + continue; + } + let i = 0; + for (const path of fnTypePath) { + if (path === queryElem.pathWithoutLast[i]) { + i += 1; + if (i >= queryElemPathLength) { + break; + } + } + } + if (i < queryElemPathLength) { + // If we didn't find all parts of the path of the query element inside + // the fn type, then it's not the right one. + continue; + } + } if (queryElem.generics.length === 0 || checkGenerics(fnType, queryElem)) { currentFnTypeList.splice(i, 1); const result = doHandleQueryElemList(currentFnTypeList, queryElemList); @@ -1863,14 +1888,14 @@ function initSearch(rawSearchIndex) { * @param {QueryElement} elem */ function convertNameToId(elem) { - if (typeNameIdMap.has(elem.name)) { - elem.id = typeNameIdMap.get(elem.name); + if (typeNameIdMap.has(elem.pathLast)) { + elem.id = typeNameIdMap.get(elem.pathLast); } else if (!parsedQuery.literalSearch) { let match = -1; let matchDist = maxEditDistance + 1; let matchName = ""; for (const [name, id] of typeNameIdMap) { - const dist = editDistance(name, elem.name, maxEditDistance); + const dist = editDistance(name, elem.pathLast, maxEditDistance); if (dist <= matchDist && dist <= maxEditDistance) { if (dist === matchDist && matchName > name) { continue; @@ -2385,12 +2410,20 @@ ${item.displayPath}<span class="${type}">${name}</span>\ lowercasePaths ); } + // `0` is used as a sentinel because it's fewer bytes than `null` + if (pathIndex === 0) { + return { + id: -1, + ty: null, + path: null, + generics: generics, + }; + } + const item = lowercasePaths[pathIndex - 1]; return { - // `0` is used as a sentinel because it's fewer bytes than `null` - id: pathIndex === 0 - ? -1 - : buildTypeMapIndex(lowercasePaths[pathIndex - 1].name), - ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty, + id: buildTypeMapIndex(item.name), + ty: item.ty, + path: item.path, generics: generics, }; }); @@ -2422,13 +2455,22 @@ ${item.displayPath}<span class="${type}">${name}</span>\ let inputs, output; if (typeof functionSearchType[INPUTS_DATA] === "number") { const pathIndex = functionSearchType[INPUTS_DATA]; - inputs = [{ - id: pathIndex === 0 - ? -1 - : buildTypeMapIndex(lowercasePaths[pathIndex - 1].name), - ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty, - generics: [], - }]; + if (pathIndex === 0) { + inputs = [{ + id: -1, + ty: null, + path: null, + generics: [], + }]; + } else { + const item = lowercasePaths[pathIndex - 1]; + inputs = [{ + id: buildTypeMapIndex(item.name), + ty: item.ty, + path: item.path, + generics: [], + }]; + } } else { inputs = buildItemSearchTypeAll( functionSearchType[INPUTS_DATA], @@ -2438,13 +2480,22 @@ ${item.displayPath}<span class="${type}">${name}</span>\ if (functionSearchType.length > 1) { if (typeof functionSearchType[OUTPUT_DATA] === "number") { const pathIndex = functionSearchType[OUTPUT_DATA]; - output = [{ - id: pathIndex === 0 - ? -1 - : buildTypeMapIndex(lowercasePaths[pathIndex - 1].name), - ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty, - generics: [], - }]; + if (pathIndex === 0) { + output = [{ + id: -1, + ty: null, + path: null, + generics: [], + }]; + } else { + const item = lowercasePaths[pathIndex - 1]; + output = [{ + id: buildTypeMapIndex(item.name), + ty: item.ty, + path: item.path, + generics: [], + }]; + } } else { output = buildItemSearchTypeAll( functionSearchType[OUTPUT_DATA], @@ -2577,9 +2628,19 @@ ${item.displayPath}<span class="${type}">${name}</span>\ // convert `rawPaths` entries into object form // generate normalizedPaths for function search mode let len = paths.length; + let lastPath = itemPaths.get(0); for (let i = 0; i < len; ++i) { - lowercasePaths.push({ty: paths[i][0], name: paths[i][1].toLowerCase()}); - paths[i] = {ty: paths[i][0], name: paths[i][1]}; + const elem = paths[i]; + const ty = elem[0]; + const name = elem[1]; + let path = null; + if (elem.length > 2) { + path = itemPaths.has(elem[2]) ? itemPaths.get(elem[2]) : lastPath; + lastPath = path; + } + + lowercasePaths.push({ty: ty, name: name.toLowerCase(), path: path}); + paths[i] = {ty: ty, name: name, path: path}; } // convert `item*` into an object form, and construct word indices. @@ -2589,8 +2650,8 @@ ${item.displayPath}<span class="${type}">${name}</span>\ // operation that is cached for the life of the page state so that // all other search operations have access to this cached data for // faster analysis operations + lastPath = ""; len = itemTypes.length; - let lastPath = ""; for (let i = 0; i < len; ++i) { let word = ""; // This object should have exactly the same set of fields as the "crateRow" @@ -2599,11 +2660,12 @@ ${item.displayPath}<span class="${type}">${name}</span>\ word = itemNames[i].toLowerCase(); } searchWords.push(word); + const path = itemPaths.has(i) ? itemPaths.get(i) : lastPath; const row = { crate: crate, ty: itemTypes.charCodeAt(i) - charA, name: itemNames[i], - path: itemPaths.has(i) ? itemPaths.get(i) : lastPath, + path: path, desc: itemDescs[i], parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined, type: buildFunctionSearchType( diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 66b5798797f..0c18f5687f5 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -8,6 +8,7 @@ use std::fmt; use rustc_ast::ast; use rustc_hir::{def::CtorKind, def::DefKind, def_id::DefId}; +use rustc_metadata::rendered_const; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::{Pos, Symbol}; @@ -15,7 +16,6 @@ use rustc_target::spec::abi::Abi as RustcAbi; use rustdoc_json_types::*; -use crate::clean::utils::print_const_expr; use crate::clean::{self, ItemId}; use crate::formats::item_type::ItemType; use crate::json::JsonRenderer; @@ -805,7 +805,7 @@ impl FromWithTcx<clean::Static> for Static { Static { type_: stat.type_.into_tcx(tcx), mutable: stat.mutability == ast::Mutability::Mut, - expr: stat.expr.map(|e| print_const_expr(tcx, e)).unwrap_or_default(), + expr: stat.expr.map(|e| rendered_const(tcx, e)).unwrap_or_default(), } } } diff --git a/src/tools/build_helper/src/git.rs b/src/tools/build_helper/src/git.rs index 66876e02c19..f20b7a2b4d7 100644 --- a/src/tools/build_helper/src/git.rs +++ b/src/tools/build_helper/src/git.rs @@ -78,13 +78,22 @@ pub fn rev_exists(rev: &str, git_dir: Option<&Path>) -> Result<bool, String> { /// We will then fall back to origin/master in the hope that at least this exists. pub fn updated_master_branch(git_dir: Option<&Path>) -> Result<String, String> { let upstream_remote = get_rust_lang_rust_remote(git_dir)?; - let upstream_master = format!("{upstream_remote}/master"); - if rev_exists(&upstream_master, git_dir)? { - return Ok(upstream_master); + for upstream_master in [format!("{upstream_remote}/master"), format!("origin/master")] { + if rev_exists(&upstream_master, git_dir)? { + return Ok(upstream_master); + } } - // We could implement smarter logic here in the future. - Ok("origin/master".into()) + Err(format!("Cannot find any suitable upstream master branch")) +} + +pub fn get_git_merge_base(git_dir: Option<&Path>) -> Result<String, String> { + let updated_master = updated_master_branch(git_dir)?; + let mut git = Command::new("git"); + if let Some(git_dir) = git_dir { + git.current_dir(git_dir); + } + Ok(output_result(git.arg("merge-base").arg(&updated_master).arg("HEAD"))?.trim().to_owned()) } /// Returns the files that have been modified in the current branch compared to the master branch. @@ -94,20 +103,13 @@ pub fn get_git_modified_files( git_dir: Option<&Path>, extensions: &Vec<&str>, ) -> Result<Option<Vec<String>>, String> { - let Ok(updated_master) = updated_master_branch(git_dir) else { - return Ok(None); - }; - - let git = || { - let mut git = Command::new("git"); - if let Some(git_dir) = git_dir { - git.current_dir(git_dir); - } - git - }; + let merge_base = get_git_merge_base(git_dir)?; - let merge_base = output_result(git().arg("merge-base").arg(&updated_master).arg("HEAD"))?; - let files = output_result(git().arg("diff-index").arg("--name-only").arg(merge_base.trim()))? + let mut git = Command::new("git"); + if let Some(git_dir) = git_dir { + git.current_dir(git_dir); + } + let files = output_result(git.args(["diff-index", "--name-only", merge_base.trim()]))? .lines() .map(|s| s.trim().to_owned()) .filter(|f| { diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs index f9108145cdb..a687c7d29b5 100644 --- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs +++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs @@ -1,24 +1,20 @@ use super::ARITHMETIC_SIDE_EFFECTS; use clippy_utils::consts::{constant, constant_simple, Constant}; use clippy_utils::diagnostics::span_lint; +use clippy_utils::ty::type_diagnostic_name; use clippy_utils::{expr_or_init, is_from_proc_macro, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty; use rustc_session::impl_lint_pass; use rustc_span::source_map::{Span, Spanned}; +use rustc_span::symbol::sym; use rustc_span::Symbol; use {rustc_ast as ast, rustc_hir as hir}; -const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[ - ["f32", "f32"], - ["f64", "f64"], - ["std::num::Saturating", "*"], - ["std::num::Wrapping", "*"], - ["std::string::String", "str"], -]; +const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[["f32", "f32"], ["f64", "f64"], ["std::string::String", "str"]]; const HARD_CODED_ALLOWED_UNARY: &[&str] = &["f32", "f64", "std::num::Saturating", "std::num::Wrapping"]; -const INTEGER_METHODS: &[&str] = &["saturating_div", "wrapping_div", "wrapping_rem", "wrapping_rem_euclid"]; +const INTEGER_METHODS: &[Symbol] = &[sym::saturating_div, sym::wrapping_div, sym::wrapping_rem, sym::wrapping_rem_euclid]; #[derive(Debug)] pub struct ArithmeticSideEffects { @@ -53,7 +49,7 @@ impl ArithmeticSideEffects { allowed_unary, const_span: None, expr_span: None, - integer_methods: INTEGER_METHODS.iter().map(|el| Symbol::intern(el)).collect(), + integer_methods: INTEGER_METHODS.iter().copied().collect(), } } @@ -86,6 +82,38 @@ impl ArithmeticSideEffects { self.allowed_unary.contains(ty_string_elem) } + /// Verifies built-in types that have specific allowed operations + fn has_specific_allowed_type_and_operation( + cx: &LateContext<'_>, + lhs_ty: Ty<'_>, + op: &Spanned<hir::BinOpKind>, + rhs_ty: Ty<'_>, + ) -> bool { + let is_div_or_rem = matches!(op.node, hir::BinOpKind::Div | hir::BinOpKind::Rem); + let is_non_zero_u = |symbol: Option<Symbol>| { + matches!( + symbol, + Some(sym::NonZeroU128 | sym::NonZeroU16 | sym::NonZeroU32 | sym::NonZeroU64 | sym::NonZeroU8 | sym::NonZeroUsize) + ) + }; + let is_sat_or_wrap = |ty: Ty<'_>| { + let is_sat = type_diagnostic_name(cx, ty) == Some(sym::Saturating); + let is_wrap = type_diagnostic_name(cx, ty) == Some(sym::Wrapping); + is_sat || is_wrap + }; + + // If the RHS is NonZeroU*, then division or module by zero will never occur + if is_non_zero_u(type_diagnostic_name(cx, rhs_ty)) && is_div_or_rem { + return true; + } + // `Saturation` and `Wrapping` can overflow if the RHS is zero in a division or module + if is_sat_or_wrap(lhs_ty) { + return !is_div_or_rem; + } + + false + } + // For example, 8i32 or &i64::MAX. fn is_integral(ty: Ty<'_>) -> bool { ty.peel_refs().is_integral() @@ -147,6 +175,9 @@ impl ArithmeticSideEffects { if self.has_allowed_binary(lhs_ty, rhs_ty) { return; } + if Self::has_specific_allowed_type_and_operation(cx, lhs_ty, op, rhs_ty) { + return; + } let has_valid_op = if Self::is_integral(lhs_ty) && Self::is_integral(rhs_ty) { if let hir::BinOpKind::Shl | hir::BinOpKind::Shr = op.node { // At least for integers, shifts are already handled by the CTFE diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs index 8485b3eab71..def30f5903d 100644 --- a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs +++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs @@ -15,7 +15,7 @@ extern crate proc_macro_derive; -use core::num::{Saturating, Wrapping}; +use core::num::{NonZeroUsize, Saturating, Wrapping}; const ONE: i32 = 1; const ZERO: i32 = 0; @@ -493,4 +493,32 @@ pub fn issue_11262() { let _ = 2 / zero; } +pub fn issue_11392() { + fn example_div(unsigned: usize, nonzero_unsigned: NonZeroUsize) -> usize { + unsigned / nonzero_unsigned + } + + fn example_rem(unsigned: usize, nonzero_unsigned: NonZeroUsize) -> usize { + unsigned % nonzero_unsigned + } + + let (unsigned, nonzero_unsigned) = (0, NonZeroUsize::new(1).unwrap()); + example_div(unsigned, nonzero_unsigned); + example_rem(unsigned, nonzero_unsigned); +} + +pub fn issue_11393() { + fn example_div(x: Wrapping<i32>, maybe_zero: Wrapping<i32>) -> Wrapping<i32> { + x / maybe_zero + } + + fn example_rem(x: Wrapping<i32>, maybe_zero: Wrapping<i32>) -> Wrapping<i32> { + x % maybe_zero + } + + let [x, maybe_zero] = [1, 0].map(Wrapping); + example_div(x, maybe_zero); + example_rem(x, maybe_zero); +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr index e9a626643ff..7f490748160 100644 --- a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr +++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr @@ -702,5 +702,17 @@ error: arithmetic operation that can potentially result in unexpected side-effec LL | 10 / a | ^^^^^^ -error: aborting due to 117 previous errors +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:512:9 + | +LL | x / maybe_zero + | ^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:516:9 + | +LL | x % maybe_zero + | ^^^^^^^^^^^^^^ + +error: aborting due to 119 previous errors diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 919bc135fdf..b40e7f83f4f 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -35e416303e6591a71ef6a91e006c602d2def3968 +a989e25f1b87949a886eab3da10324d14189fe95 diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 03dd9037808..816055cc4fe 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -8,7 +8,6 @@ #![feature(yeet_expr)] #![feature(nonzero_ops)] #![feature(round_ties_even)] -#![feature(os_str_bytes)] #![feature(lint_reasons)] #![feature(trait_upcasting)] // Configure clippy and other lints diff --git a/src/tools/miri/src/shims/os_str.rs b/src/tools/miri/src/shims/os_str.rs index f08f0aad5e7..a94b1ddcd95 100644 --- a/src/tools/miri/src/shims/os_str.rs +++ b/src/tools/miri/src/shims/os_str.rs @@ -24,7 +24,7 @@ pub fn bytes_to_os_str<'tcx>(bytes: &[u8]) -> InterpResult<'tcx, &OsStr> { } #[cfg(not(unix))] pub fn bytes_to_os_str<'tcx>(bytes: &[u8]) -> InterpResult<'tcx, &OsStr> { - // We cannot use `from_os_str_bytes_unchecked` here since we can't trust `bytes`. + // We cannot use `from_encoded_bytes_unchecked` here since we can't trust `bytes`. let s = std::str::from_utf8(bytes) .map_err(|_| err_unsup_format!("{:?} is not a valid utf-8 string", bytes))?; Ok(OsStr::new(s)) @@ -83,7 +83,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ptr: Pointer<Option<Provenance>>, size: u64, ) -> InterpResult<'tcx, (bool, u64)> { - let bytes = os_str.as_os_str_bytes(); + let bytes = os_str.as_encoded_bytes(); self.eval_context_mut().write_c_str(bytes, ptr, size) } diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index beaef22075b..dd2da3d22f2 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -1344,7 +1344,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let mut name = dir_entry.file_name(); // not a Path as there are no separators! name.push("\0"); // Add a NUL terminator - let name_bytes = name.as_os_str_bytes(); + let name_bytes = name.as_encoded_bytes(); let name_len = u64::try_from(name_bytes.len()).unwrap(); let dirent64_layout = this.libc_ty_layout("dirent64"); @@ -1698,7 +1698,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { Cow::Borrowed(resolved.as_ref()), crate::shims::os_str::PathConversion::HostToTarget, ); - let mut path_bytes = resolved.as_os_str_bytes(); + let mut path_bytes = resolved.as_encoded_bytes(); let bufsize: usize = bufsize.try_into().unwrap(); if path_bytes.len() > bufsize { path_bytes = &path_bytes[..bufsize] diff --git a/src/tools/miri/tests/utils/fs.rs b/src/tools/miri/tests/utils/fs.rs index 47904926b48..0242a228068 100644 --- a/src/tools/miri/tests/utils/fs.rs +++ b/src/tools/miri/tests/utils/fs.rs @@ -6,7 +6,7 @@ use super::miri_extern; pub fn host_to_target_path(path: OsString) -> PathBuf { use std::ffi::{CStr, CString}; - // Once into_os_str_bytes is stable we can use it here. + // Once into_encoded_bytes is stable we can use it here. // (Unstable features would need feature flags in each test...) let path = CString::new(path.into_string().unwrap()).unwrap(); let mut out = Vec::with_capacity(1024); diff --git a/tests/codegen/lib-optimizations/iter-sum.rs b/tests/codegen/lib-optimizations/iter-sum.rs new file mode 100644 index 00000000000..ff7ca6ef6c1 --- /dev/null +++ b/tests/codegen/lib-optimizations/iter-sum.rs @@ -0,0 +1,15 @@ +// ignore-debug: the debug assertions get in the way +// compile-flags: -O +// only-x86_64 (vectorization varies between architectures) +#![crate_type = "lib"] + + +// Ensure that slice + take + sum gets vectorized. +// Currently this relies on the slice::Iter::try_fold implementation +// CHECK-LABEL: @slice_take_sum +#[no_mangle] +pub fn slice_take_sum(s: &[u64], l: usize) -> u64 { + // CHECK: vector.body: + // CHECK: ret + s.iter().take(l).sum() +} diff --git a/tests/codegen/slice-as_chunks.rs b/tests/codegen/slice-as_chunks.rs index 48e3f73fc86..efac9f3d68d 100644 --- a/tests/codegen/slice-as_chunks.rs +++ b/tests/codegen/slice-as_chunks.rs @@ -22,9 +22,9 @@ pub fn chunks4(x: &[u8]) -> &[[u8; 4]] { // CHECK-LABEL: @chunks4_with_remainder #[no_mangle] pub fn chunks4_with_remainder(x: &[u8]) -> (&[[u8; 4]], &[u8]) { - // CHECK: and i64 %x.1, -4 - // CHECK: and i64 %x.1, 3 - // CHECK: lshr exact + // CHECK-DAG: and i64 %x.1, -4 + // CHECK-DAG: and i64 %x.1, 3 + // CHECK-DAG: lshr // CHECK-NOT: mul // CHECK-NOT: udiv // CHECK-NOT: urem diff --git a/tests/codegen/slice-iter-nonnull.rs b/tests/codegen/slice-iter-nonnull.rs index f7d164bc856..8749226d401 100644 --- a/tests/codegen/slice-iter-nonnull.rs +++ b/tests/codegen/slice-iter-nonnull.rs @@ -100,13 +100,13 @@ pub fn slice_iter_is_empty(it: &std::slice::Iter<'_, u32>) -> bool { // CHECK-LABEL: @slice_iter_len #[no_mangle] pub fn slice_iter_len(it: &std::slice::Iter<'_, u32>) -> usize { - // CHECK: %[[START:.+]] = load ptr, ptr %it, - // CHECK-SAME: !nonnull - // CHECK-SAME: !noundef // CHECK: %[[ENDP:.+]] = getelementptr{{.+}}ptr %it,{{.+}} 1 // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] // CHECK-SAME: !nonnull // CHECK-SAME: !noundef + // CHECK: %[[START:.+]] = load ptr, ptr %it, + // CHECK-SAME: !nonnull + // CHECK-SAME: !noundef // CHECK: ptrtoint // CHECK: ptrtoint diff --git a/tests/mir-opt/bool_compare.opt1.InstSimplify.diff b/tests/mir-opt/bool_compare.opt1.InstSimplify.diff index 8d0011d5067..657c11516a1 100644 --- a/tests/mir-opt/bool_compare.opt1.InstSimplify.diff +++ b/tests/mir-opt/bool_compare.opt1.InstSimplify.diff @@ -13,16 +13,17 @@ _3 = _1; - _2 = Ne(move _3, const true); + _2 = Not(move _3); - StorageDead(_3); switchInt(move _2) -> [0: bb2, otherwise: bb1]; } bb1: { + StorageDead(_3); _0 = const 0_u32; goto -> bb3; } bb2: { + StorageDead(_3); _0 = const 1_u32; goto -> bb3; } diff --git a/tests/mir-opt/bool_compare.opt2.InstSimplify.diff b/tests/mir-opt/bool_compare.opt2.InstSimplify.diff index 35f1068709b..bc8be62bd49 100644 --- a/tests/mir-opt/bool_compare.opt2.InstSimplify.diff +++ b/tests/mir-opt/bool_compare.opt2.InstSimplify.diff @@ -13,16 +13,17 @@ _3 = _1; - _2 = Ne(const true, move _3); + _2 = Not(move _3); - StorageDead(_3); switchInt(move _2) -> [0: bb2, otherwise: bb1]; } bb1: { + StorageDead(_3); _0 = const 0_u32; goto -> bb3; } bb2: { + StorageDead(_3); _0 = const 1_u32; goto -> bb3; } diff --git a/tests/mir-opt/bool_compare.opt3.InstSimplify.diff b/tests/mir-opt/bool_compare.opt3.InstSimplify.diff index ab15c30ca11..034d5e44013 100644 --- a/tests/mir-opt/bool_compare.opt3.InstSimplify.diff +++ b/tests/mir-opt/bool_compare.opt3.InstSimplify.diff @@ -13,16 +13,17 @@ _3 = _1; - _2 = Eq(move _3, const false); + _2 = Not(move _3); - StorageDead(_3); switchInt(move _2) -> [0: bb2, otherwise: bb1]; } bb1: { + StorageDead(_3); _0 = const 0_u32; goto -> bb3; } bb2: { + StorageDead(_3); _0 = const 1_u32; goto -> bb3; } diff --git a/tests/mir-opt/bool_compare.opt4.InstSimplify.diff b/tests/mir-opt/bool_compare.opt4.InstSimplify.diff index 40fd1cfe112..d3096da6c5a 100644 --- a/tests/mir-opt/bool_compare.opt4.InstSimplify.diff +++ b/tests/mir-opt/bool_compare.opt4.InstSimplify.diff @@ -13,16 +13,17 @@ _3 = _1; - _2 = Eq(const false, move _3); + _2 = Not(move _3); - StorageDead(_3); switchInt(move _2) -> [0: bb2, otherwise: bb1]; } bb1: { + StorageDead(_3); _0 = const 0_u32; goto -> bb3; } bb2: { + StorageDead(_3); _0 = const 1_u32; goto -> bb3; } diff --git a/tests/mir-opt/building/logical_or_in_conditional.rs b/tests/mir-opt/building/logical_or_in_conditional.rs new file mode 100644 index 00000000000..ae159f7e122 --- /dev/null +++ b/tests/mir-opt/building/logical_or_in_conditional.rs @@ -0,0 +1,39 @@ +// compile-flags: -Z validate-mir +#![feature(let_chains)] +struct Droppy(u8); +impl Drop for Droppy { + fn drop(&mut self) { + println!("drop {}", self.0); + } +} + +enum E { + A(u8), + B, +} + +impl E { + fn f() -> Self { + Self::A(1) + } +} + +fn always_true() -> bool { + true +} + +// EMIT_MIR logical_or_in_conditional.test_or.built.after.mir +fn test_or() { + if Droppy(0).0 > 0 || Droppy(1).0 > 1 {} +} + +// EMIT_MIR logical_or_in_conditional.test_complex.built.after.mir +fn test_complex() { + if let E::A(_) = E::f() && ((always_true() && Droppy(0).0 > 0) || Droppy(1).0 > 1) {} + + if !always_true() && let E::B = E::f() {} +} + +fn main() { + test_or(); +} diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir new file mode 100644 index 00000000000..096aaec4a38 --- /dev/null +++ b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir @@ -0,0 +1,186 @@ +// MIR for `test_complex` after built + +fn test_complex() -> () { + let mut _0: (); + let _1: (); + let mut _2: E; + let mut _3: isize; + let mut _4: bool; + let mut _5: bool; + let mut _6: u8; + let mut _7: Droppy; + let mut _8: bool; + let mut _9: u8; + let mut _10: Droppy; + let mut _11: bool; + let mut _12: E; + let mut _13: isize; + + bb0: { + StorageLive(_1); + StorageLive(_2); + _2 = E::f() -> [return: bb1, unwind: bb31]; + } + + bb1: { + FakeRead(ForMatchedPlace(None), _2); + _3 = discriminant(_2); + switchInt(move _3) -> [0: bb2, otherwise: bb3]; + } + + bb2: { + falseEdge -> [real: bb4, imaginary: bb3]; + } + + bb3: { + goto -> bb19; + } + + bb4: { + StorageLive(_4); + _4 = always_true() -> [return: bb5, unwind: bb31]; + } + + bb5: { + switchInt(move _4) -> [0: bb7, otherwise: bb6]; + } + + bb6: { + StorageLive(_5); + StorageLive(_6); + StorageLive(_7); + _7 = Droppy(const 0_u8); + _6 = (_7.0: u8); + _5 = Gt(move _6, const 0_u8); + switchInt(move _5) -> [0: bb9, otherwise: bb8]; + } + + bb7: { + goto -> bb13; + } + + bb8: { + drop(_7) -> [return: bb10, unwind: bb31]; + } + + bb9: { + goto -> bb11; + } + + bb10: { + StorageDead(_7); + StorageDead(_6); + goto -> bb16; + } + + bb11: { + drop(_7) -> [return: bb12, unwind: bb31]; + } + + bb12: { + StorageDead(_7); + StorageDead(_6); + goto -> bb13; + } + + bb13: { + StorageLive(_8); + StorageLive(_9); + StorageLive(_10); + _10 = Droppy(const 1_u8); + _9 = (_10.0: u8); + _8 = Gt(move _9, const 1_u8); + switchInt(move _8) -> [0: bb15, otherwise: bb14]; + } + + bb14: { + drop(_10) -> [return: bb16, unwind: bb31]; + } + + bb15: { + goto -> bb17; + } + + bb16: { + StorageDead(_10); + StorageDead(_9); + _1 = const (); + goto -> bb20; + } + + bb17: { + drop(_10) -> [return: bb18, unwind: bb31]; + } + + bb18: { + StorageDead(_10); + StorageDead(_9); + goto -> bb19; + } + + bb19: { + _1 = const (); + goto -> bb20; + } + + bb20: { + StorageDead(_8); + StorageDead(_5); + StorageDead(_4); + StorageDead(_2); + StorageDead(_1); + StorageLive(_11); + _11 = always_true() -> [return: bb21, unwind: bb31]; + } + + bb21: { + switchInt(move _11) -> [0: bb23, otherwise: bb22]; + } + + bb22: { + goto -> bb29; + } + + bb23: { + goto -> bb24; + } + + bb24: { + StorageLive(_12); + _12 = E::f() -> [return: bb25, unwind: bb31]; + } + + bb25: { + FakeRead(ForMatchedPlace(None), _12); + _13 = discriminant(_12); + switchInt(move _13) -> [1: bb27, otherwise: bb26]; + } + + bb26: { + goto -> bb29; + } + + bb27: { + falseEdge -> [real: bb28, imaginary: bb26]; + } + + bb28: { + _0 = const (); + goto -> bb30; + } + + bb29: { + _0 = const (); + goto -> bb30; + } + + bb30: { + StorageDead(_11); + StorageDead(_12); + return; + } + + bb31 (cleanup): { + resume; + } +} diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir new file mode 100644 index 00000000000..b84c17c2188 --- /dev/null +++ b/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir @@ -0,0 +1,87 @@ +// MIR for `test_or` after built + +fn test_or() -> () { + let mut _0: (); + let mut _1: bool; + let mut _2: u8; + let mut _3: Droppy; + let mut _4: bool; + let mut _5: u8; + let mut _6: Droppy; + + bb0: { + StorageLive(_1); + StorageLive(_2); + StorageLive(_3); + _3 = Droppy(const 0_u8); + _2 = (_3.0: u8); + _1 = Gt(move _2, const 0_u8); + switchInt(move _1) -> [0: bb2, otherwise: bb1]; + } + + bb1: { + drop(_3) -> [return: bb3, unwind: bb12]; + } + + bb2: { + goto -> bb4; + } + + bb3: { + StorageDead(_3); + StorageDead(_2); + goto -> bb8; + } + + bb4: { + drop(_3) -> [return: bb5, unwind: bb12]; + } + + bb5: { + StorageDead(_3); + StorageDead(_2); + StorageLive(_4); + StorageLive(_5); + StorageLive(_6); + _6 = Droppy(const 1_u8); + _5 = (_6.0: u8); + _4 = Gt(move _5, const 1_u8); + switchInt(move _4) -> [0: bb7, otherwise: bb6]; + } + + bb6: { + drop(_6) -> [return: bb8, unwind: bb12]; + } + + bb7: { + goto -> bb9; + } + + bb8: { + StorageDead(_6); + StorageDead(_5); + _0 = const (); + goto -> bb11; + } + + bb9: { + drop(_6) -> [return: bb10, unwind: bb12]; + } + + bb10: { + StorageDead(_6); + StorageDead(_5); + _0 = const (); + goto -> bb11; + } + + bb11: { + StorageDead(_4); + StorageDead(_1); + return; + } + + bb12 (cleanup): { + resume; + } +} diff --git a/tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff b/tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff index d1dbc7089a1..1768298d521 100644 --- a/tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff +++ b/tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff @@ -43,31 +43,33 @@ } bb3: { -- StorageDead(_6); - switchInt(move _5) -> [0: bb5, otherwise: bb4]; - } - - bb4: { +- StorageDead(_6); - _4 = const true; - goto -> bb6; - } - - bb5: { +- StorageDead(_6); - _4 = const false; - goto -> bb6; - } - - bb6: { -- StorageDead(_5); - switchInt(move _4) -> [0: bb8, otherwise: bb7]; - } - - bb7: { +- StorageDead(_5); - _3 = const true; - goto -> bb9; - } - - bb8: { +- StorageDead(_5); - _3 = const false; - goto -> bb9; - } diff --git a/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff index 08b599f9f5d..355f28b03db 100644 --- a/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff +++ b/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff @@ -39,19 +39,20 @@ StorageLive(_4); - _4 = _1; - _3 = Eq(move _4, const 1_i32); +- switchInt(move _3) -> [0: bb2, otherwise: bb1]; + _4 = const 1_i32; + _3 = const true; - StorageDead(_4); -- switchInt(move _3) -> [0: bb2, otherwise: bb1]; + switchInt(const true) -> [0: bb2, otherwise: bb1]; } bb1: { + StorageDead(_4); _2 = const 2_i32; goto -> bb3; } bb2: { + StorageDead(_4); _2 = const 3_i32; goto -> bb3; } @@ -70,20 +71,21 @@ StorageLive(_9); - _9 = _1; - _8 = Eq(move _9, const 1_i32); +- switchInt(move _8) -> [0: bb5, otherwise: bb4]; + _9 = const 1_i32; + _8 = const true; - StorageDead(_9); -- switchInt(move _8) -> [0: bb5, otherwise: bb4]; + switchInt(const true) -> [0: bb5, otherwise: bb4]; } bb4: { + StorageDead(_9); - _7 = _1; + _7 = const 1_i32; goto -> bb6; } bb5: { + StorageDead(_9); StorageLive(_10); _10 = _1; _7 = Add(move _10, const 1_i32); diff --git a/tests/mir-opt/equal_true.opt.InstSimplify.diff b/tests/mir-opt/equal_true.opt.InstSimplify.diff index 7b38862e4d5..88a51000c93 100644 --- a/tests/mir-opt/equal_true.opt.InstSimplify.diff +++ b/tests/mir-opt/equal_true.opt.InstSimplify.diff @@ -13,16 +13,17 @@ _3 = _1; - _2 = Eq(move _3, const true); + _2 = move _3; - StorageDead(_3); switchInt(move _2) -> [0: bb2, otherwise: bb1]; } bb1: { + StorageDead(_3); _0 = const 0_i32; goto -> bb3; } bb2: { + StorageDead(_3); _0 = const 1_i32; goto -> bb3; } diff --git a/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff index 8483b89f814..15319586062 100644 --- a/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff @@ -12,16 +12,17 @@ StorageLive(_3); _3 = _1; _2 = Eq(move _3, const -42f32); - StorageDead(_3); switchInt(move _2) -> [0: bb2, otherwise: bb1]; } bb1: { + StorageDead(_3); _0 = const 0_i32; goto -> bb3; } bb2: { + StorageDead(_3); _0 = const 1_i32; goto -> bb3; } diff --git a/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff index 837841b009b..fedbd6cdd24 100644 --- a/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff @@ -12,21 +12,19 @@ StorageLive(_3); _3 = _1; - _2 = Eq(move _3, const 'x'); -- StorageDead(_3); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ nop; + switchInt(move _3) -> [120: bb1, otherwise: bb2]; } bb1: { -+ StorageDead(_3); + StorageDead(_3); _0 = const 0_u32; goto -> bb3; } bb2: { -+ StorageDead(_3); + StorageDead(_3); _0 = const 1_u32; goto -> bb3; } diff --git a/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff index 3cbf912996c..9c38d8fe065 100644 --- a/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff @@ -12,21 +12,19 @@ StorageLive(_3); _3 = _1; - _2 = Eq(move _3, const 42_i8); -- StorageDead(_3); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ nop; + switchInt(move _3) -> [42: bb1, otherwise: bb2]; } bb1: { -+ StorageDead(_3); + StorageDead(_3); _0 = const 0_u32; goto -> bb3; } bb2: { -+ StorageDead(_3); + StorageDead(_3); _0 = const 1_u32; goto -> bb3; } diff --git a/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff index 8d6f3b2249e..8c85ce78565 100644 --- a/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff @@ -14,40 +14,36 @@ StorageLive(_3); _3 = _1; - _2 = Eq(move _3, const 42_u32); -- StorageDead(_3); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ nop; + switchInt(move _3) -> [42: bb1, otherwise: bb2]; } bb1: { -+ StorageDead(_3); + StorageDead(_3); _0 = const 0_u32; goto -> bb6; } bb2: { -+ StorageDead(_3); + StorageDead(_3); StorageLive(_4); StorageLive(_5); _5 = _1; - _4 = Ne(move _5, const 21_u32); -- StorageDead(_5); - switchInt(move _4) -> [0: bb4, otherwise: bb3]; + nop; -+ nop; + switchInt(move _5) -> [21: bb4, otherwise: bb3]; } bb3: { -+ StorageDead(_5); + StorageDead(_5); _0 = const 1_u32; goto -> bb5; } bb4: { -+ StorageDead(_5); + StorageDead(_5); _0 = const 2_u32; goto -> bb5; } diff --git a/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff index e2566b13c59..876ed61e9fa 100644 --- a/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff @@ -12,21 +12,19 @@ StorageLive(_3); _3 = _1; - _2 = Eq(move _3, const -42_i32); -- StorageDead(_3); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ nop; + switchInt(move _3) -> [4294967254: bb1, otherwise: bb2]; } bb1: { -+ StorageDead(_3); + StorageDead(_3); _0 = const 0_u32; goto -> bb3; } bb2: { -+ StorageDead(_3); + StorageDead(_3); _0 = const 1_u32; goto -> bb3; } diff --git a/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff index dc8da5b44b2..ed3eb47dd3d 100644 --- a/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff @@ -12,21 +12,19 @@ StorageLive(_3); _3 = _1; - _2 = Eq(move _3, const 42_u32); -- StorageDead(_3); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ nop; + switchInt(move _3) -> [42: bb1, otherwise: bb2]; } bb1: { -+ StorageDead(_3); + StorageDead(_3); _0 = const 0_u32; goto -> bb3; } bb2: { -+ StorageDead(_3); + StorageDead(_3); _0 = const 1_u32; goto -> bb3; } diff --git a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff index 9db0d385da7..d675695eb10 100644 --- a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff @@ -18,11 +18,11 @@ StorageLive(_3); _3 = _1; _2 = Gt(move _3, const 0_i32); - StorageDead(_3); switchInt(move _2) -> [0: bb2, otherwise: bb1]; } bb1: { + StorageDead(_3); StorageLive(_4); _4 = _1; _0 = move _4 as u32 (IntToInt); @@ -32,6 +32,7 @@ } bb2: { + StorageDead(_3); StorageLive(_6); - _6 = panic() -> unwind unreachable; + StorageLive(_7); diff --git a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff index 5663b462400..1142616115f 100644 --- a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff @@ -18,11 +18,11 @@ StorageLive(_3); _3 = _1; _2 = Gt(move _3, const 0_i32); - StorageDead(_3); switchInt(move _2) -> [0: bb2, otherwise: bb1]; } bb1: { + StorageDead(_3); StorageLive(_4); _4 = _1; _0 = move _4 as u32 (IntToInt); @@ -32,6 +32,7 @@ } bb2: { + StorageDead(_3); StorageLive(_6); - _6 = panic() -> unwind continue; + StorageLive(_7); diff --git a/tests/mir-opt/issue_99325.main.built.after.mir b/tests/mir-opt/issue_99325.main.built.after.mir index aef89c7f9f7..f12179a8905 100644 --- a/tests/mir-opt/issue_99325.main.built.after.mir +++ b/tests/mir-opt/issue_99325.main.built.after.mir @@ -16,51 +16,49 @@ fn main() -> () { let _8: &&[u8]; let _9: &&[u8; 4]; let mut _10: bool; - let mut _11: bool; - let mut _12: &&[u8]; - let mut _13: &&[u8; 4]; - let mut _14: !; - let _16: !; - let mut _17: core::panicking::AssertKind; - let mut _18: &&[u8]; - let _19: &&[u8]; - let mut _20: &&[u8; 4]; - let _21: &&[u8; 4]; - let mut _22: std::option::Option<std::fmt::Arguments<'_>>; - let _23: (); - let mut _24: (&&[u8], &&[u8; 4]); - let mut _25: &&[u8]; - let _26: &[u8]; - let mut _27: &&[u8; 4]; - let _28: &[u8; 4]; - let _29: &&[u8]; - let _30: &&[u8; 4]; - let mut _31: bool; - let mut _32: bool; - let mut _33: &&[u8]; - let mut _34: &&[u8; 4]; - let mut _35: !; - let _37: !; - let mut _38: core::panicking::AssertKind; - let mut _39: &&[u8]; - let _40: &&[u8]; - let mut _41: &&[u8; 4]; - let _42: &&[u8; 4]; - let mut _43: std::option::Option<std::fmt::Arguments<'_>>; + let mut _11: &&[u8]; + let mut _12: &&[u8; 4]; + let mut _13: !; + let _15: !; + let mut _16: core::panicking::AssertKind; + let mut _17: &&[u8]; + let _18: &&[u8]; + let mut _19: &&[u8; 4]; + let _20: &&[u8; 4]; + let mut _21: std::option::Option<std::fmt::Arguments<'_>>; + let _22: (); + let mut _23: (&&[u8], &&[u8; 4]); + let mut _24: &&[u8]; + let _25: &[u8]; + let mut _26: &&[u8; 4]; + let _27: &[u8; 4]; + let _28: &&[u8]; + let _29: &&[u8; 4]; + let mut _30: bool; + let mut _31: &&[u8]; + let mut _32: &&[u8; 4]; + let mut _33: !; + let _35: !; + let mut _36: core::panicking::AssertKind; + let mut _37: &&[u8]; + let _38: &&[u8]; + let mut _39: &&[u8; 4]; + let _40: &&[u8; 4]; + let mut _41: std::option::Option<std::fmt::Arguments<'_>>; scope 1 { debug left_val => _8; debug right_val => _9; - let _15: core::panicking::AssertKind; + let _14: core::panicking::AssertKind; scope 2 { - debug kind => _15; + debug kind => _14; } } scope 3 { - debug left_val => _29; - debug right_val => _30; - let _36: core::panicking::AssertKind; + debug left_val => _28; + debug right_val => _29; + let _34: core::panicking::AssertKind; scope 4 { - debug kind => _36; + debug kind => _34; } } @@ -69,7 +67,7 @@ fn main() -> () { StorageLive(_2); StorageLive(_3); StorageLive(_4); - _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb19]; + _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb21]; } bb1: { @@ -90,179 +88,185 @@ fn main() -> () { _9 = (_2.1: &&[u8; 4]); StorageLive(_10); StorageLive(_11); + _11 = &(*_8); StorageLive(_12); - _12 = &(*_8); - StorageLive(_13); - _13 = &(*_9); - _11 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _12, move _13) -> [return: bb2, unwind: bb19]; + _12 = &(*_9); + _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb2, unwind: bb21]; } bb2: { - StorageDead(_13); - StorageDead(_12); - _10 = Not(move _11); - StorageDead(_11); switchInt(move _10) -> [0: bb4, otherwise: bb3]; } bb3: { + StorageDead(_12); + StorageDead(_11); + goto -> bb8; + } + + bb4: { + goto -> bb5; + } + + bb5: { + StorageDead(_12); + StorageDead(_11); + StorageLive(_14); + _14 = core::panicking::AssertKind::Eq; + FakeRead(ForLet(None), _14); StorageLive(_15); - _15 = core::panicking::AssertKind::Eq; - FakeRead(ForLet(None), _15); StorageLive(_16); + _16 = move _14; StorageLive(_17); - _17 = move _15; StorageLive(_18); + _18 = &(*_8); + _17 = &(*_18); StorageLive(_19); - _19 = &(*_8); - _18 = &(*_19); StorageLive(_20); + _20 = &(*_9); + _19 = &(*_20); StorageLive(_21); - _21 = &(*_9); - _20 = &(*_21); - StorageLive(_22); - _22 = Option::<Arguments<'_>>::None; - _16 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _17, move _18, move _20, move _22) -> bb19; - } - - bb4: { - goto -> bb7; + _21 = Option::<Arguments<'_>>::None; + _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> bb21; } - bb5: { - StorageDead(_22); - StorageDead(_20); - StorageDead(_18); - StorageDead(_17); + bb6: { StorageDead(_21); StorageDead(_19); + StorageDead(_17); StorageDead(_16); + StorageDead(_20); + StorageDead(_18); StorageDead(_15); + StorageDead(_14); unreachable; } - bb6: { - goto -> bb8; + bb7: { + goto -> bb9; } - bb7: { + bb8: { _1 = const (); - goto -> bb8; + goto -> bb9; } - bb8: { + bb9: { StorageDead(_10); StorageDead(_9); StorageDead(_8); - goto -> bb9; + goto -> bb10; } - bb9: { + bb10: { StorageDead(_7); StorageDead(_6); StorageDead(_4); StorageDead(_2); StorageDead(_1); + StorageLive(_22); StorageLive(_23); StorageLive(_24); StorageLive(_25); - StorageLive(_26); - _26 = function_with_bytes::<&*b"AAAA">() -> [return: bb10, unwind: bb19]; + _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb11, unwind: bb21]; } - bb10: { - _25 = &_26; + bb11: { + _24 = &_25; + StorageLive(_26); StorageLive(_27); + _27 = const b"AAAA"; + _26 = &_27; + _23 = (move _24, move _26); + StorageDead(_26); + StorageDead(_24); + FakeRead(ForMatchedPlace(None), _23); StorageLive(_28); - _28 = const b"AAAA"; - _27 = &_28; - _24 = (move _25, move _27); - StorageDead(_27); - StorageDead(_25); - FakeRead(ForMatchedPlace(None), _24); + _28 = (_23.0: &&[u8]); StorageLive(_29); - _29 = (_24.0: &&[u8]); + _29 = (_23.1: &&[u8; 4]); StorageLive(_30); - _30 = (_24.1: &&[u8; 4]); StorageLive(_31); + _31 = &(*_28); StorageLive(_32); - StorageLive(_33); - _33 = &(*_29); - StorageLive(_34); - _34 = &(*_30); - _32 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _33, move _34) -> [return: bb11, unwind: bb19]; + _32 = &(*_29); + _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb12, unwind: bb21]; } - bb11: { - StorageDead(_34); - StorageDead(_33); - _31 = Not(move _32); + bb12: { + switchInt(move _30) -> [0: bb14, otherwise: bb13]; + } + + bb13: { StorageDead(_32); - switchInt(move _31) -> [0: bb13, otherwise: bb12]; + StorageDead(_31); + goto -> bb18; } - bb12: { + bb14: { + goto -> bb15; + } + + bb15: { + StorageDead(_32); + StorageDead(_31); + StorageLive(_34); + _34 = core::panicking::AssertKind::Eq; + FakeRead(ForLet(None), _34); + StorageLive(_35); StorageLive(_36); - _36 = core::panicking::AssertKind::Eq; - FakeRead(ForLet(None), _36); + _36 = move _34; StorageLive(_37); StorageLive(_38); - _38 = move _36; + _38 = &(*_28); + _37 = &(*_38); StorageLive(_39); StorageLive(_40); _40 = &(*_29); _39 = &(*_40); StorageLive(_41); - StorageLive(_42); - _42 = &(*_30); - _41 = &(*_42); - StorageLive(_43); - _43 = Option::<Arguments<'_>>::None; - _37 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _38, move _39, move _41, move _43) -> bb19; - } - - bb13: { - goto -> bb16; + _41 = Option::<Arguments<'_>>::None; + _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> bb21; } - bb14: { - StorageDead(_43); + bb16: { StorageDead(_41); StorageDead(_39); - StorageDead(_38); - StorageDead(_42); - StorageDead(_40); StorageDead(_37); StorageDead(_36); + StorageDead(_40); + StorageDead(_38); + StorageDead(_35); + StorageDead(_34); unreachable; } - bb15: { - goto -> bb17; + bb17: { + goto -> bb19; } - bb16: { - _23 = const (); - goto -> bb17; + bb18: { + _22 = const (); + goto -> bb19; } - bb17: { - StorageDead(_31); + bb19: { StorageDead(_30); StorageDead(_29); - goto -> bb18; + StorageDead(_28); + goto -> bb20; } - bb18: { - StorageDead(_28); - StorageDead(_26); - StorageDead(_24); + bb20: { + StorageDead(_27); + StorageDead(_25); StorageDead(_23); + StorageDead(_22); _0 = const (); return; } - bb19 (cleanup): { + bb21 (cleanup): { resume; } } diff --git a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff index 6174d5259d0..5242c5f6afd 100644 --- a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff @@ -32,12 +32,12 @@ bb1: { StorageDead(_6); _3 = Lt(move _4, move _5); - StorageDead(_5); - StorageDead(_4); switchInt(move _3) -> [0: bb4, otherwise: bb2]; } bb2: { + StorageDead(_5); + StorageDead(_4); StorageLive(_8); _8 = _1; _9 = Len((*_2)); @@ -52,6 +52,8 @@ } bb4: { + StorageDead(_5); + StorageDead(_4); _0 = const 42_u8; goto -> bb5; } diff --git a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff index 60c0772d8ec..a9e99933b12 100644 --- a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff @@ -32,12 +32,12 @@ bb1: { StorageDead(_6); _3 = Lt(move _4, move _5); - StorageDead(_5); - StorageDead(_4); switchInt(move _3) -> [0: bb4, otherwise: bb2]; } bb2: { + StorageDead(_5); + StorageDead(_4); StorageLive(_8); _8 = _1; _9 = Len((*_2)); @@ -52,6 +52,8 @@ } bb4: { + StorageDead(_5); + StorageDead(_4); _0 = const 42_u8; goto -> bb5; } diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff index e2de1845296..7749ba6beca 100644 --- a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff @@ -35,12 +35,12 @@ bb1: { StorageDead(_6); _3 = Lt(move _4, move _5); - StorageDead(_5); - StorageDead(_4); switchInt(move _3) -> [0: bb4, otherwise: bb2]; } bb2: { + StorageDead(_5); + StorageDead(_4); StorageLive(_8); _8 = _1; _9 = Len((*_2)); @@ -55,6 +55,8 @@ } bb4: { + StorageDead(_5); + StorageDead(_4); StorageLive(_11); _11 = const 0_usize; _12 = Len((*_2)); diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff index eb81e0eea2c..fcc2c1653dc 100644 --- a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff @@ -35,12 +35,12 @@ bb1: { StorageDead(_6); _3 = Lt(move _4, move _5); - StorageDead(_5); - StorageDead(_4); switchInt(move _3) -> [0: bb4, otherwise: bb2]; } bb2: { + StorageDead(_5); + StorageDead(_4); StorageLive(_8); _8 = _1; _9 = Len((*_2)); @@ -55,6 +55,8 @@ } bb4: { + StorageDead(_5); + StorageDead(_4); StorageLive(_11); _11 = const 0_usize; _12 = Len((*_2)); diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff index 70b33fb703b..7f752ca0f5a 100644 --- a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff +++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff @@ -28,12 +28,12 @@ bb1: { StorageDead(_6); _3 = Lt(move _4, move _5); - StorageDead(_5); - StorageDead(_4); switchInt(move _3) -> [0: bb4, otherwise: bb2]; } bb2: { + StorageDead(_5); + StorageDead(_4); StorageLive(_7); _7 = _1; _8 = Len((*_2)); @@ -48,6 +48,8 @@ } bb4: { + StorageDead(_5); + StorageDead(_4); _0 = const 42_u8; goto -> bb5; } diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff index 310b3b26ac5..d73b563a0e5 100644 --- a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff +++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff @@ -28,12 +28,12 @@ bb1: { StorageDead(_6); _3 = Lt(move _4, move _5); - StorageDead(_5); - StorageDead(_4); switchInt(move _3) -> [0: bb4, otherwise: bb2]; } bb2: { + StorageDead(_5); + StorageDead(_4); StorageLive(_7); _7 = _1; _8 = Len((*_2)); @@ -48,6 +48,8 @@ } bb4: { + StorageDead(_5); + StorageDead(_4); _0 = const 42_u8; goto -> bb5; } diff --git a/tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff index b5edbfee0fc..5a71bef9341 100644 --- a/tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff +++ b/tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff @@ -40,39 +40,43 @@ - } - - bb3: { +- switchInt(move _5) -> [0: bb5, otherwise: bb4]; +- } +- +- bb4: { + StorageLive(_7); + _7 = move _6; + _5 = Ne(_7, const false); + StorageDead(_7); ++ StorageLive(_8); ++ _8 = move _5; StorageDead(_6); -- switchInt(move _5) -> [0: bb5, otherwise: bb4]; -- } -- -- bb4: { - _4 = const true; - goto -> bb6; - } - - bb5: { +- StorageDead(_6); - _4 = const false; - goto -> bb6; - } - - bb6: { -+ StorageLive(_8); -+ _8 = move _5; -+ _4 = Ne(_8, const false); -+ StorageDead(_8); - StorageDead(_5); - switchInt(move _4) -> [0: bb8, otherwise: bb7]; - } - - bb7: { ++ _4 = Ne(_8, const false); ++ StorageDead(_8); ++ StorageLive(_9); ++ _9 = move _4; + StorageDead(_5); - _3 = const true; - goto -> bb9; - } - - bb8: { +- StorageDead(_5); - _3 = const false; - goto -> bb9; - } @@ -82,8 +86,6 @@ - } - - bb10: { -+ StorageLive(_9); -+ _9 = move _4; + _3 = Ne(_9, const false); + StorageDead(_9); + StorageLive(_10); diff --git a/tests/mir-opt/not_equal_false.opt.InstSimplify.diff b/tests/mir-opt/not_equal_false.opt.InstSimplify.diff index 71353be24a6..1342966aa15 100644 --- a/tests/mir-opt/not_equal_false.opt.InstSimplify.diff +++ b/tests/mir-opt/not_equal_false.opt.InstSimplify.diff @@ -13,16 +13,17 @@ _3 = _1; - _2 = Ne(move _3, const false); + _2 = move _3; - StorageDead(_3); switchInt(move _2) -> [0: bb2, otherwise: bb1]; } bb1: { + StorageDead(_3); _0 = const 0_u32; goto -> bb3; } bb2: { + StorageDead(_3); _0 = const 1_u32; goto -> bb3; } diff --git a/tests/mir-opt/pre-codegen/chained_comparison.naive.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/chained_comparison.naive.PreCodegen.after.mir index c7fd397fcd4..838e30fa35e 100644 --- a/tests/mir-opt/pre-codegen/chained_comparison.naive.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/chained_comparison.naive.PreCodegen.after.mir @@ -7,130 +7,111 @@ fn naive(_1: &Blueprint, _2: &Blueprint) -> bool { let mut _3: u32; let mut _4: u32; let mut _5: bool; - let mut _6: bool; + let mut _6: u32; let mut _7: u32; - let mut _8: u32; - let mut _9: bool; - let mut _10: bool; - let mut _11: u32; + let mut _8: bool; + let mut _9: u32; + let mut _10: u32; + let mut _11: bool; let mut _12: u32; - let mut _13: bool; + let mut _13: u32; let mut _14: bool; let mut _15: u32; let mut _16: u32; - let mut _17: bool; - let mut _18: u32; - let mut _19: u32; - let mut _20: bool; bb0: { - StorageLive(_14); - StorageLive(_10); - StorageLive(_6); StorageLive(_5); StorageLive(_3); _3 = ((*_1).0: u32); StorageLive(_4); _4 = ((*_2).0: u32); _5 = Eq(move _3, move _4); - StorageDead(_4); - StorageDead(_3); switchInt(move _5) -> [0: bb1, otherwise: bb2]; } bb1: { - _6 = const false; - goto -> bb3; + StorageDead(_4); + StorageDead(_3); + goto -> bb8; } bb2: { - StorageLive(_9); - StorageLive(_7); - _7 = ((*_1).1: u32); + StorageDead(_4); + StorageDead(_3); StorageLive(_8); - _8 = ((*_2).1: u32); - _9 = Eq(move _7, move _8); - StorageDead(_8); - StorageDead(_7); - _6 = move _9; - goto -> bb3; + StorageLive(_6); + _6 = ((*_1).1: u32); + StorageLive(_7); + _7 = ((*_2).1: u32); + _8 = Eq(move _6, move _7); + switchInt(move _8) -> [0: bb3, otherwise: bb4]; } bb3: { - StorageDead(_9); - StorageDead(_5); - switchInt(move _6) -> [0: bb4, otherwise: bb5]; + StorageDead(_7); + StorageDead(_6); + goto -> bb8; } bb4: { - _10 = const false; - goto -> bb6; + StorageDead(_7); + StorageDead(_6); + StorageLive(_11); + StorageLive(_9); + _9 = ((*_1).2: u32); + StorageLive(_10); + _10 = ((*_2).2: u32); + _11 = Eq(move _9, move _10); + switchInt(move _11) -> [0: bb5, otherwise: bb6]; } bb5: { - StorageLive(_13); - StorageLive(_11); - _11 = ((*_1).2: u32); - StorageLive(_12); - _12 = ((*_2).2: u32); - _13 = Eq(move _11, move _12); - StorageDead(_12); - StorageDead(_11); - _10 = move _13; - goto -> bb6; + StorageDead(_10); + StorageDead(_9); + goto -> bb8; } bb6: { - StorageDead(_13); - StorageDead(_6); - switchInt(move _10) -> [0: bb7, otherwise: bb8]; + StorageDead(_10); + StorageDead(_9); + StorageLive(_14); + StorageLive(_12); + _12 = ((*_1).3: u32); + StorageLive(_13); + _13 = ((*_2).3: u32); + _14 = Eq(move _12, move _13); + switchInt(move _14) -> [0: bb7, otherwise: bb9]; } bb7: { - _14 = const false; - goto -> bb9; + StorageDead(_13); + StorageDead(_12); + goto -> bb8; } bb8: { - StorageLive(_17); + _0 = const false; + goto -> bb10; + } + + bb9: { + StorageDead(_13); + StorageDead(_12); StorageLive(_15); - _15 = ((*_1).3: u32); + _15 = ((*_1).4: u32); StorageLive(_16); - _16 = ((*_2).3: u32); - _17 = Eq(move _15, move _16); + _16 = ((*_2).4: u32); + _0 = Eq(move _15, move _16); StorageDead(_16); StorageDead(_15); - _14 = move _17; - goto -> bb9; - } - - bb9: { - StorageDead(_17); - StorageDead(_10); - switchInt(move _14) -> [0: bb10, otherwise: bb11]; + goto -> bb10; } bb10: { - _0 = const false; - goto -> bb12; - } - - bb11: { - StorageLive(_20); - StorageLive(_18); - _18 = ((*_1).4: u32); - StorageLive(_19); - _19 = ((*_2).4: u32); - _20 = Eq(move _18, move _19); - StorageDead(_19); - StorageDead(_18); - _0 = move _20; - goto -> bb12; - } - - bb12: { - StorageDead(_20); StorageDead(_14); + StorageDead(_11); + StorageDead(_8); + StorageDead(_5); return; } } diff --git a/tests/mir-opt/pre-codegen/chained_comparison.returning.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/chained_comparison.returning.PreCodegen.after.mir index 1e619bc9704..8452fa12f31 100644 --- a/tests/mir-opt/pre-codegen/chained_comparison.returning.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/chained_comparison.returning.PreCodegen.after.mir @@ -27,12 +27,12 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool { StorageLive(_4); _4 = ((*_2).0: u32); _5 = Ne(move _3, move _4); - StorageDead(_4); - StorageDead(_3); switchInt(move _5) -> [0: bb1, otherwise: bb10]; } bb1: { + StorageDead(_4); + StorageDead(_3); StorageDead(_5); StorageLive(_8); StorageLive(_6); @@ -40,12 +40,12 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool { StorageLive(_7); _7 = ((*_2).1: u32); _8 = Ne(move _6, move _7); - StorageDead(_7); - StorageDead(_6); switchInt(move _8) -> [0: bb2, otherwise: bb9]; } bb2: { + StorageDead(_7); + StorageDead(_6); StorageDead(_8); StorageLive(_11); StorageLive(_9); @@ -53,12 +53,12 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool { StorageLive(_10); _10 = ((*_2).2: u32); _11 = Ne(move _9, move _10); - StorageDead(_10); - StorageDead(_9); switchInt(move _11) -> [0: bb3, otherwise: bb8]; } bb3: { + StorageDead(_10); + StorageDead(_9); StorageDead(_11); StorageLive(_14); StorageLive(_12); @@ -66,12 +66,12 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool { StorageLive(_13); _13 = ((*_2).3: u32); _14 = Ne(move _12, move _13); - StorageDead(_13); - StorageDead(_12); switchInt(move _14) -> [0: bb4, otherwise: bb7]; } bb4: { + StorageDead(_13); + StorageDead(_12); StorageDead(_14); StorageLive(_17); StorageLive(_15); @@ -79,42 +79,52 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool { StorageLive(_16); _16 = ((*_2).4: u32); _17 = Ne(move _15, move _16); - StorageDead(_16); - StorageDead(_15); switchInt(move _17) -> [0: bb5, otherwise: bb6]; } bb5: { + StorageDead(_16); + StorageDead(_15); StorageDead(_17); _0 = const true; goto -> bb11; } bb6: { + StorageDead(_16); + StorageDead(_15); _0 = const false; StorageDead(_17); goto -> bb11; } bb7: { + StorageDead(_13); + StorageDead(_12); _0 = const false; StorageDead(_14); goto -> bb11; } bb8: { + StorageDead(_10); + StorageDead(_9); _0 = const false; StorageDead(_11); goto -> bb11; } bb9: { + StorageDead(_7); + StorageDead(_6); _0 = const false; StorageDead(_8); goto -> bb11; } bb10: { + StorageDead(_4); + StorageDead(_3); _0 = const false; StorageDead(_5); goto -> bb11; diff --git a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir index b2ea96f033e..75f81c5aaca 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir @@ -40,16 +40,22 @@ fn step_forward(_1: u32, _2: usize) -> u32 { _5 = Eq(_4, const 1_isize); _6 = Not(move _5); StorageDead(_5); - StorageDead(_3); - StorageDead(_8); - switchInt(move _6) -> [0: bb3, otherwise: bb2]; + switchInt(move _6) -> [0: bb2, otherwise: bb3]; } bb2: { - assert(!const true, "attempt to compute `{} + {}`, which would overflow", const _, const 1_u32) -> [success: bb3, unwind continue]; + StorageDead(_3); + StorageDead(_8); + goto -> bb4; } bb3: { + StorageDead(_3); + StorageDead(_8); + assert(!const true, "attempt to compute `{} + {}`, which would overflow", const _, const 1_u32) -> [success: bb4, unwind continue]; + } + + bb4: { StorageDead(_6); StorageLive(_7); _7 = _2 as u32 (IntToInt); diff --git a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir index 2e51faeba5a..0d79f2de10d 100644 --- a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir @@ -63,17 +63,19 @@ fn int_range(_1: usize, _2: usize) -> () { _7 = Lt(move _5, move _6); StorageDead(_6); StorageDead(_5); - StorageDead(_16); - StorageDead(_15); switchInt(move _7) -> [0: bb2, otherwise: bb3]; } bb2: { + StorageDead(_16); + StorageDead(_15); _8 = Option::<usize>::None; goto -> bb5; } bb3: { + StorageDead(_16); + StorageDead(_15); _9 = (_4.0: usize); StorageLive(_10); _10 = <usize as Step>::forward_unchecked(_9, const 1_usize) -> [return: bb4, unwind continue]; diff --git a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir index 26919dd98dd..630babaa821 100644 --- a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir @@ -10,23 +10,53 @@ fn mem_replace(_1: &mut u32, _2: u32) -> u32 { scope 2 { scope 3 { debug result => _0; - scope 6 (inlined std::ptr::write::<u32>) { + scope 16 (inlined std::ptr::write::<u32>) { debug dst => _1; debug src => _2; - scope 7 { + scope 17 { } } } scope 4 (inlined std::ptr::read::<u32>) { debug src => _1; scope 5 { + scope 6 (inlined std::ptr::read::runtime::<u32>) { + debug src => _1; + scope 7 (inlined intrinsics::is_aligned_and_not_null::<u32>) { + debug ptr => _1; + scope 8 (inlined ptr::const_ptr::<impl *const u32>::is_null) { + debug self => _1; + let mut _3: *const u8; + scope 9 { + scope 10 (inlined ptr::const_ptr::<impl *const T>::is_null::runtime_impl) { + debug ptr => _3; + scope 11 (inlined ptr::const_ptr::<impl *const u8>::addr) { + debug self => _3; + scope 12 { + scope 13 (inlined ptr::const_ptr::<impl *const u8>::cast::<()>) { + debug self => _3; + } + } + } + } + } + } + scope 14 (inlined ptr::const_ptr::<impl *const u32>::is_aligned) { + debug self => _1; + scope 15 (inlined align_of::<u32>) { + } + } + } + } } } } } bb0: { + StorageLive(_3); _0 = (*_1); + StorageDead(_3); (*_1) = _2; return; } diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir index d76b46bdd94..9664ccfb094 100644 --- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -66,17 +66,19 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { _8 = Lt(move _6, move _7); StorageDead(_7); StorageDead(_6); - StorageDead(_19); - StorageDead(_18); switchInt(move _8) -> [0: bb2, otherwise: bb3]; } bb2: { + StorageDead(_19); + StorageDead(_18); _9 = Option::<u32>::None; goto -> bb5; } bb3: { + StorageDead(_19); + StorageDead(_18); _10 = (_5.0: u32); StorageLive(_11); _11 = <u32 as Step>::forward_unchecked(_10, const 1_usize) -> [return: bb4, unwind unreachable]; diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir index 35f7356d47a..dc8b46b6c08 100644 --- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -66,17 +66,19 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { _8 = Lt(move _6, move _7); StorageDead(_7); StorageDead(_6); - StorageDead(_19); - StorageDead(_18); switchInt(move _8) -> [0: bb2, otherwise: bb3]; } bb2: { + StorageDead(_19); + StorageDead(_18); _9 = Option::<u32>::None; goto -> bb5; } bb3: { + StorageDead(_19); + StorageDead(_18); _10 = (_5.0: u32); StorageLive(_11); _11 = <u32 as Step>::forward_unchecked(_10, const 1_usize) -> [return: bb4, unwind: bb11]; diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir index 7360aa3e698..fff713b5a79 100644 --- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir @@ -38,17 +38,19 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> { _4 = Lt(move _2, move _3); StorageDead(_3); StorageDead(_2); - StorageDead(_8); - StorageDead(_7); switchInt(move _4) -> [0: bb1, otherwise: bb2]; } bb1: { + StorageDead(_8); + StorageDead(_7); _0 = Option::<u32>::None; goto -> bb4; } bb2: { + StorageDead(_8); + StorageDead(_7); _5 = ((*_1).0: u32); StorageLive(_6); _6 = <u32 as Step>::forward_unchecked(_5, const 1_usize) -> [return: bb3, unwind unreachable]; diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir index 61957082d8b..cc12c0122b7 100644 --- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir @@ -38,17 +38,19 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> { _4 = Lt(move _2, move _3); StorageDead(_3); StorageDead(_2); - StorageDead(_8); - StorageDead(_7); switchInt(move _4) -> [0: bb1, otherwise: bb2]; } bb1: { + StorageDead(_8); + StorageDead(_7); _0 = Option::<u32>::None; goto -> bb4; } bb2: { + StorageDead(_8); + StorageDead(_7); _5 = ((*_1).0: u32); StorageLive(_6); _6 = <u32 as Step>::forward_unchecked(_5, const 1_usize) -> [return: bb3, unwind continue]; diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir index 1488779f93b..ddfd5b0fefc 100644 --- a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir @@ -12,30 +12,27 @@ fn variant_a::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:7:25: 7:39], _2 let _10: &usize; let _11: &usize; let mut _16: bool; - let mut _17: bool; - let _18: &usize; - let mut _23: bool; - let _24: &usize; - let mut _29: bool; - let mut _30: bool; - let _31: &usize; - let mut _36: bool; + let _17: &usize; + let mut _22: bool; + let _23: &usize; + let mut _28: bool; + let _29: &usize; + let mut _34: &&usize; + let mut _35: &&usize; + let mut _36: &&usize; let mut _37: &&usize; let mut _38: &&usize; let mut _39: &&usize; let mut _40: &&usize; let mut _41: &&usize; - let mut _42: &&usize; - let mut _43: &&usize; - let mut _44: &&usize; scope 1 { debug a => _4; debug b => _6; debug c => _8; debug d => _10; scope 2 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { - debug self => _37; - debug other => _38; + debug self => _34; + debug other => _35; let mut _12: &usize; let mut _13: &usize; scope 3 (inlined cmp::impls::<impl PartialOrd for usize>::le) { @@ -46,39 +43,39 @@ fn variant_a::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:7:25: 7:39], _2 } } scope 4 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { - debug self => _41; - debug other => _42; - let mut _25: &usize; - let mut _26: &usize; + debug self => _36; + debug other => _37; + let mut _18: &usize; + let mut _19: &usize; scope 5 (inlined cmp::impls::<impl PartialOrd for usize>::le) { - debug self => _25; - debug other => _26; - let mut _27: usize; - let mut _28: usize; + debug self => _18; + debug other => _19; + let mut _20: usize; + let mut _21: usize; } } scope 6 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { - debug self => _39; - debug other => _40; - let mut _19: &usize; - let mut _20: &usize; + debug self => _38; + debug other => _39; + let mut _24: &usize; + let mut _25: &usize; scope 7 (inlined cmp::impls::<impl PartialOrd for usize>::le) { - debug self => _19; - debug other => _20; - let mut _21: usize; - let mut _22: usize; + debug self => _24; + debug other => _25; + let mut _26: usize; + let mut _27: usize; } } scope 8 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { - debug self => _43; - debug other => _44; - let mut _32: &usize; - let mut _33: &usize; + debug self => _40; + debug other => _41; + let mut _30: &usize; + let mut _31: &usize; scope 9 (inlined cmp::impls::<impl PartialOrd for usize>::le) { - debug self => _32; - debug other => _33; - let mut _34: usize; - let mut _35: usize; + debug self => _30; + debug other => _31; + let mut _32: usize; + let mut _33: usize; } } } @@ -96,10 +93,9 @@ fn variant_a::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:7:25: 7:39], _2 StorageLive(_10); _9 = deref_copy (*_2); _10 = &((*_9).3: usize); - StorageLive(_17); StorageLive(_16); - StorageLive(_37); - StorageLive(_38); + StorageLive(_34); + StorageLive(_35); StorageLive(_11); _11 = _8; _12 = deref_copy _4; @@ -111,109 +107,109 @@ fn variant_a::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:7:25: 7:39], _2 _16 = Le(move _14, move _15); StorageDead(_15); StorageDead(_14); - StorageDead(_11); - StorageDead(_38); - StorageDead(_37); switchInt(move _16) -> [0: bb1, otherwise: bb2]; } bb1: { - _17 = const false; - goto -> bb3; + StorageDead(_11); + StorageDead(_35); + StorageDead(_34); + goto -> bb4; } bb2: { - StorageLive(_23); - StorageLive(_39); - StorageLive(_40); - StorageLive(_18); - _18 = _6; - _19 = deref_copy _10; - _20 = deref_copy _18; + StorageDead(_11); + StorageDead(_35); + StorageDead(_34); + StorageLive(_22); + StorageLive(_36); + StorageLive(_37); + StorageLive(_17); + _17 = _6; + _18 = deref_copy _10; + _19 = deref_copy _17; + StorageLive(_20); + _20 = (*_18); StorageLive(_21); _21 = (*_19); - StorageLive(_22); - _22 = (*_20); - _23 = Le(move _21, move _22); - StorageDead(_22); + _22 = Le(move _20, move _21); StorageDead(_21); - StorageDead(_18); - StorageDead(_40); - StorageDead(_39); - _17 = move _23; - goto -> bb3; + StorageDead(_20); + switchInt(move _22) -> [0: bb3, otherwise: bb8]; } bb3: { - StorageDead(_23); - StorageDead(_16); - switchInt(move _17) -> [0: bb4, otherwise: bb8]; + StorageDead(_17); + StorageDead(_37); + StorageDead(_36); + goto -> bb4; } bb4: { - StorageLive(_30); - StorageLive(_29); - StorageLive(_41); - StorageLive(_42); - StorageLive(_24); - _24 = _4; - _25 = deref_copy _8; - _26 = deref_copy _24; + StorageLive(_28); + StorageLive(_38); + StorageLive(_39); + StorageLive(_23); + _23 = _4; + _24 = deref_copy _8; + _25 = deref_copy _23; + StorageLive(_26); + _26 = (*_24); StorageLive(_27); _27 = (*_25); - StorageLive(_28); - _28 = (*_26); - _29 = Le(move _27, move _28); - StorageDead(_28); + _28 = Le(move _26, move _27); StorageDead(_27); - StorageDead(_24); - StorageDead(_42); - StorageDead(_41); - switchInt(move _29) -> [0: bb5, otherwise: bb6]; + StorageDead(_26); + switchInt(move _28) -> [0: bb5, otherwise: bb6]; } bb5: { - _30 = const false; + StorageDead(_23); + StorageDead(_39); + StorageDead(_38); + _0 = const false; goto -> bb7; } bb6: { - StorageLive(_36); - StorageLive(_43); - StorageLive(_44); - StorageLive(_31); - _31 = _10; - _32 = deref_copy _6; - _33 = deref_copy _31; - StorageLive(_34); - _34 = (*_32); - StorageLive(_35); - _35 = (*_33); - _36 = Le(move _34, move _35); - StorageDead(_35); - StorageDead(_34); - StorageDead(_31); - StorageDead(_44); - StorageDead(_43); - _30 = move _36; + StorageDead(_23); + StorageDead(_39); + StorageDead(_38); + StorageLive(_40); + StorageLive(_41); + StorageLive(_29); + _29 = _10; + _30 = deref_copy _6; + _31 = deref_copy _29; + StorageLive(_32); + _32 = (*_30); + StorageLive(_33); + _33 = (*_31); + _0 = Le(move _32, move _33); + StorageDead(_33); + StorageDead(_32); + StorageDead(_29); + StorageDead(_41); + StorageDead(_40); goto -> bb7; } bb7: { - StorageDead(_36); - StorageDead(_29); - _0 = move _30; + StorageDead(_28); goto -> bb9; } bb8: { + StorageDead(_17); + StorageDead(_37); + StorageDead(_36); _0 = const true; goto -> bb9; } bb9: { - StorageDead(_30); - StorageDead(_17); + StorageDead(_22); + StorageDead(_16); StorageDead(_10); StorageDead(_8); StorageDead(_6); diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir index bab9f0b58aa..7e70c6290a8 100644 --- a/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir @@ -13,9 +13,6 @@ fn variant_b::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:11:25: 11:41], let mut _11: bool; let mut _12: bool; let mut _13: bool; - let mut _14: bool; - let mut _15: bool; - let mut _16: bool; scope 1 { debug a => _4; debug b => _6; @@ -32,64 +29,46 @@ fn variant_b::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:11:25: 11:41], _8 = ((*_7).2: usize); _9 = deref_copy (*_2); _10 = ((*_9).3: usize); - StorageLive(_12); StorageLive(_11); _11 = Le(_4, _8); - switchInt(move _11) -> [0: bb1, otherwise: bb2]; + switchInt(move _11) -> [0: bb2, otherwise: bb1]; } bb1: { - _12 = const false; - goto -> bb3; + StorageLive(_12); + _12 = Le(_10, _6); + switchInt(move _12) -> [0: bb2, otherwise: bb6]; } bb2: { StorageLive(_13); - _13 = Le(_10, _6); - _12 = move _13; - goto -> bb3; + _13 = Le(_8, _4); + switchInt(move _13) -> [0: bb3, otherwise: bb4]; } bb3: { - StorageDead(_13); - StorageDead(_11); - switchInt(move _12) -> [0: bb4, otherwise: bb8]; + _0 = const false; + goto -> bb5; } bb4: { - StorageLive(_15); - StorageLive(_14); - _14 = Le(_8, _4); - switchInt(move _14) -> [0: bb5, otherwise: bb6]; + _0 = Le(_6, _10); + goto -> bb5; } bb5: { - _15 = const false; + StorageDead(_13); goto -> bb7; } bb6: { - StorageLive(_16); - _16 = Le(_6, _10); - _15 = move _16; + _0 = const true; goto -> bb7; } bb7: { - StorageDead(_16); - StorageDead(_14); - _0 = move _15; - goto -> bb9; - } - - bb8: { - _0 = const true; - goto -> bb9; - } - - bb9: { - StorageDead(_15); StorageDead(_12); + StorageDead(_11); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir index 07a58309ee4..8590c9d3b83 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir @@ -58,16 +58,17 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { StorageLive(_3); _3 = Len((*_1)); _4 = Lt(_2, move _3); - StorageDead(_3); switchInt(move _4) -> [0: bb1, otherwise: bb2]; } bb1: { + StorageDead(_3); _0 = const Option::<&mut u32>::None; goto -> bb3; } bb2: { + StorageDead(_3); StorageLive(_8); StorageLive(_5); _5 = &raw mut (*_1); diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir index 07a58309ee4..8590c9d3b83 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir @@ -58,16 +58,17 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { StorageLive(_3); _3 = Len((*_1)); _4 = Lt(_2, move _3); - StorageDead(_3); switchInt(move _4) -> [0: bb1, otherwise: bb2]; } bb1: { + StorageDead(_3); _0 = const Option::<&mut u32>::None; goto -> bb3; } bb2: { + StorageDead(_3); StorageLive(_8); StorageLive(_5); _5 = &raw mut (*_1); diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir index 2f5d356a26d..8dd2cd7900f 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir @@ -17,37 +17,50 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) -> debug slice => _5; let mut _7: *mut u32; let mut _8: *mut u32; - let _14: usize; let _15: usize; + let _16: usize; scope 4 { - debug this => std::ops::Range<usize>{ .0 => _14, .1 => _15, }; + debug this => std::ops::Range<usize>{ .0 => _15, .1 => _16, }; scope 5 { let _6: usize; scope 6 { debug new_len => _6; - scope 7 (inlined ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) { + scope 11 (inlined ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) { debug self => _5; } - scope 8 (inlined ptr::mut_ptr::<impl *mut u32>::add) { + scope 12 (inlined ptr::mut_ptr::<impl *mut u32>::add) { debug self => _7; debug count => _3; - scope 9 { + scope 13 { } } - scope 10 (inlined slice_from_raw_parts_mut::<u32>) { + scope 14 (inlined slice_from_raw_parts_mut::<u32>) { debug data => _8; debug len => _6; let mut _9: *mut (); - scope 11 (inlined ptr::mut_ptr::<impl *mut u32>::cast::<()>) { + scope 15 (inlined ptr::mut_ptr::<impl *mut u32>::cast::<()>) { debug self => _8; } - scope 12 (inlined std::ptr::from_raw_parts_mut::<[u32]>) { + scope 16 (inlined std::ptr::from_raw_parts_mut::<[u32]>) { debug data_address => _9; debug metadata => _6; let mut _10: *const (); let mut _11: std::ptr::metadata::PtrComponents<[u32]>; let mut _12: std::ptr::metadata::PtrRepr<[u32]>; - scope 13 { + scope 17 { + } + } + } + } + scope 7 (inlined <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::runtime::<u32>) { + debug this => std::ops::Range<usize>{ .0 => _15, .1 => _16, }; + debug slice => _5; + scope 8 (inlined ptr::mut_ptr::<impl *mut [u32]>::len) { + debug self => _5; + let mut _14: *const [u32]; + scope 9 (inlined std::ptr::metadata::<[u32]>) { + debug ptr => _14; + scope 10 { } } } @@ -63,9 +76,10 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) -> _4 = move (_2.1: usize); StorageLive(_5); _5 = &raw mut (*_1); + StorageLive(_6); StorageLive(_14); StorageLive(_15); - StorageLive(_6); + StorageLive(_16); _6 = SubUnchecked(_4, _3); StorageLive(_8); StorageLive(_7); @@ -86,9 +100,10 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) -> StorageDead(_12); StorageDead(_9); StorageDead(_8); - StorageDead(_6); - StorageDead(_14); + StorageDead(_16); StorageDead(_15); + StorageDead(_14); + StorageDead(_6); StorageDead(_5); _0 = &mut (*_13); return; diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir index 2f5d356a26d..8dd2cd7900f 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir @@ -17,37 +17,50 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) -> debug slice => _5; let mut _7: *mut u32; let mut _8: *mut u32; - let _14: usize; let _15: usize; + let _16: usize; scope 4 { - debug this => std::ops::Range<usize>{ .0 => _14, .1 => _15, }; + debug this => std::ops::Range<usize>{ .0 => _15, .1 => _16, }; scope 5 { let _6: usize; scope 6 { debug new_len => _6; - scope 7 (inlined ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) { + scope 11 (inlined ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) { debug self => _5; } - scope 8 (inlined ptr::mut_ptr::<impl *mut u32>::add) { + scope 12 (inlined ptr::mut_ptr::<impl *mut u32>::add) { debug self => _7; debug count => _3; - scope 9 { + scope 13 { } } - scope 10 (inlined slice_from_raw_parts_mut::<u32>) { + scope 14 (inlined slice_from_raw_parts_mut::<u32>) { debug data => _8; debug len => _6; let mut _9: *mut (); - scope 11 (inlined ptr::mut_ptr::<impl *mut u32>::cast::<()>) { + scope 15 (inlined ptr::mut_ptr::<impl *mut u32>::cast::<()>) { debug self => _8; } - scope 12 (inlined std::ptr::from_raw_parts_mut::<[u32]>) { + scope 16 (inlined std::ptr::from_raw_parts_mut::<[u32]>) { debug data_address => _9; debug metadata => _6; let mut _10: *const (); let mut _11: std::ptr::metadata::PtrComponents<[u32]>; let mut _12: std::ptr::metadata::PtrRepr<[u32]>; - scope 13 { + scope 17 { + } + } + } + } + scope 7 (inlined <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::runtime::<u32>) { + debug this => std::ops::Range<usize>{ .0 => _15, .1 => _16, }; + debug slice => _5; + scope 8 (inlined ptr::mut_ptr::<impl *mut [u32]>::len) { + debug self => _5; + let mut _14: *const [u32]; + scope 9 (inlined std::ptr::metadata::<[u32]>) { + debug ptr => _14; + scope 10 { } } } @@ -63,9 +76,10 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) -> _4 = move (_2.1: usize); StorageLive(_5); _5 = &raw mut (*_1); + StorageLive(_6); StorageLive(_14); StorageLive(_15); - StorageLive(_6); + StorageLive(_16); _6 = SubUnchecked(_4, _3); StorageLive(_8); StorageLive(_7); @@ -86,9 +100,10 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) -> StorageDead(_12); StorageDead(_9); StorageDead(_8); - StorageDead(_6); - StorageDead(_14); + StorageDead(_16); StorageDead(_15); + StorageDead(_14); + StorageDead(_6); StorageDead(_5); _0 = &mut (*_13); return; diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir index 4edf4b4fb44..4afe2eda188 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir @@ -75,17 +75,19 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _8 = Lt(move _6, move _7); StorageDead(_7); StorageDead(_6); - StorageDead(_22); - StorageDead(_21); switchInt(move _8) -> [0: bb2, otherwise: bb3]; } bb2: { + StorageDead(_22); + StorageDead(_21); _9 = Option::<usize>::None; goto -> bb5; } bb3: { + StorageDead(_22); + StorageDead(_21); _10 = (_5.0: usize); StorageLive(_11); _11 = <usize as Step>::forward_unchecked(_10, const 1_usize) -> [return: bb4, unwind unreachable]; diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir index 8bd072fd625..48092608d9c 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir @@ -75,17 +75,19 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _8 = Lt(move _6, move _7); StorageDead(_7); StorageDead(_6); - StorageDead(_22); - StorageDead(_21); switchInt(move _8) -> [0: bb2, otherwise: bb3]; } bb2: { + StorageDead(_22); + StorageDead(_21); _9 = Option::<usize>::None; goto -> bb5; } bb3: { + StorageDead(_22); + StorageDead(_21); _10 = (_5.0: usize); StorageLive(_11); _11 = <usize as Step>::forward_unchecked(_10, const 1_usize) -> [return: bb4, unwind: bb12]; diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir index 70efdbf4b34..566b6af95ba 100644 --- a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir +++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir @@ -19,17 +19,16 @@ fn array_casts() -> () { let mut _18: &usize; let _19: usize; let mut _22: bool; - let mut _23: bool; + let mut _23: usize; let mut _24: usize; - let mut _25: usize; - let mut _26: !; - let _28: !; - let mut _29: core::panicking::AssertKind; - let mut _30: &usize; - let _31: &usize; - let mut _32: &usize; - let _33: &usize; - let mut _34: std::option::Option<std::fmt::Arguments<'_>>; + let mut _25: !; + let _27: !; + let mut _28: core::panicking::AssertKind; + let mut _29: &usize; + let _30: &usize; + let mut _31: &usize; + let _32: &usize; + let mut _33: std::option::Option<std::fmt::Arguments<'_>>; scope 1 { debug x => _1; let _2: *mut usize; @@ -45,15 +44,15 @@ fn array_casts() -> () { debug p => _9; let _20: &usize; let _21: &usize; - let mut _35: &usize; + let mut _34: &usize; scope 6 { } scope 7 { debug left_val => _20; debug right_val => _21; - let _27: core::panicking::AssertKind; + let _26: core::panicking::AssertKind; scope 8 { - debug kind => _27; + debug kind => _26; } } } @@ -110,9 +109,9 @@ fn array_casts() -> () { _15 = (*_16); _14 = &_15; StorageLive(_18); - _35 = const _; - Retag(_35); - _18 = &(*_35); + _34 = const _; + Retag(_34); + _18 = &(*_34); _13 = (move _14, move _18); Retag(_13); StorageDead(_18); @@ -125,39 +124,16 @@ fn array_casts() -> () { Retag(_21); StorageLive(_22); StorageLive(_23); + _23 = (*_20); StorageLive(_24); - _24 = (*_20); - StorageLive(_25); - _25 = (*_21); - _23 = Eq(move _24, move _25); - StorageDead(_25); - StorageDead(_24); - _22 = Not(move _23); - StorageDead(_23); + _24 = (*_21); + _22 = Eq(move _23, move _24); switchInt(move _22) -> [0: bb4, otherwise: bb3]; } bb3: { - StorageLive(_27); - _27 = core::panicking::AssertKind::Eq; - StorageLive(_28); - StorageLive(_29); - _29 = move _27; - StorageLive(_30); - StorageLive(_31); - _31 = &(*_20); - _30 = &(*_31); - StorageLive(_32); - StorageLive(_33); - _33 = &(*_21); - _32 = &(*_33); - StorageLive(_34); - _34 = Option::<Arguments<'_>>::None; - Retag(_34); - _28 = core::panicking::assert_failed::<usize, usize>(move _29, move _30, move _32, move _34) -> unwind unreachable; - } - - bb4: { + StorageDead(_24); + StorageDead(_23); _12 = const (); StorageDead(_22); StorageDead(_21); @@ -173,4 +149,26 @@ fn array_casts() -> () { StorageDead(_1); return; } + + bb4: { + StorageDead(_24); + StorageDead(_23); + StorageLive(_26); + _26 = core::panicking::AssertKind::Eq; + StorageLive(_27); + StorageLive(_28); + _28 = move _26; + StorageLive(_29); + StorageLive(_30); + _30 = &(*_20); + _29 = &(*_30); + StorageLive(_31); + StorageLive(_32); + _32 = &(*_21); + _31 = &(*_32); + StorageLive(_33); + _33 = Option::<Arguments<'_>>::None; + Retag(_33); + _27 = core::panicking::assert_failed::<usize, usize>(move _28, move _29, move _31, move _33) -> unwind unreachable; + } } diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir index cfa9628d498..d0d3176320b 100644 --- a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir +++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir @@ -19,17 +19,16 @@ fn array_casts() -> () { let mut _18: &usize; let _19: usize; let mut _22: bool; - let mut _23: bool; + let mut _23: usize; let mut _24: usize; - let mut _25: usize; - let mut _26: !; - let _28: !; - let mut _29: core::panicking::AssertKind; - let mut _30: &usize; - let _31: &usize; - let mut _32: &usize; - let _33: &usize; - let mut _34: std::option::Option<std::fmt::Arguments<'_>>; + let mut _25: !; + let _27: !; + let mut _28: core::panicking::AssertKind; + let mut _29: &usize; + let _30: &usize; + let mut _31: &usize; + let _32: &usize; + let mut _33: std::option::Option<std::fmt::Arguments<'_>>; scope 1 { debug x => _1; let _2: *mut usize; @@ -45,15 +44,15 @@ fn array_casts() -> () { debug p => _9; let _20: &usize; let _21: &usize; - let mut _35: &usize; + let mut _34: &usize; scope 6 { } scope 7 { debug left_val => _20; debug right_val => _21; - let _27: core::panicking::AssertKind; + let _26: core::panicking::AssertKind; scope 8 { - debug kind => _27; + debug kind => _26; } } } @@ -110,9 +109,9 @@ fn array_casts() -> () { _15 = (*_16); _14 = &_15; StorageLive(_18); - _35 = const _; - Retag(_35); - _18 = &(*_35); + _34 = const _; + Retag(_34); + _18 = &(*_34); _13 = (move _14, move _18); Retag(_13); StorageDead(_18); @@ -125,39 +124,16 @@ fn array_casts() -> () { Retag(_21); StorageLive(_22); StorageLive(_23); + _23 = (*_20); StorageLive(_24); - _24 = (*_20); - StorageLive(_25); - _25 = (*_21); - _23 = Eq(move _24, move _25); - StorageDead(_25); - StorageDead(_24); - _22 = Not(move _23); - StorageDead(_23); + _24 = (*_21); + _22 = Eq(move _23, move _24); switchInt(move _22) -> [0: bb4, otherwise: bb3]; } bb3: { - StorageLive(_27); - _27 = core::panicking::AssertKind::Eq; - StorageLive(_28); - StorageLive(_29); - _29 = move _27; - StorageLive(_30); - StorageLive(_31); - _31 = &(*_20); - _30 = &(*_31); - StorageLive(_32); - StorageLive(_33); - _33 = &(*_21); - _32 = &(*_33); - StorageLive(_34); - _34 = Option::<Arguments<'_>>::None; - Retag(_34); - _28 = core::panicking::assert_failed::<usize, usize>(move _29, move _30, move _32, move _34) -> unwind continue; - } - - bb4: { + StorageDead(_24); + StorageDead(_23); _12 = const (); StorageDead(_22); StorageDead(_21); @@ -173,4 +149,26 @@ fn array_casts() -> () { StorageDead(_1); return; } + + bb4: { + StorageDead(_24); + StorageDead(_23); + StorageLive(_26); + _26 = core::panicking::AssertKind::Eq; + StorageLive(_27); + StorageLive(_28); + _28 = move _26; + StorageLive(_29); + StorageLive(_30); + _30 = &(*_20); + _29 = &(*_30); + StorageLive(_31); + StorageLive(_32); + _32 = &(*_21); + _31 = &(*_32); + StorageLive(_33); + _33 = Option::<Arguments<'_>>::None; + Retag(_33); + _27 = core::panicking::assert_failed::<usize, usize>(move _28, move _29, move _31, move _33) -> unwind continue; + } } diff --git a/tests/run-coverage/lazy_boolean.coverage b/tests/run-coverage/lazy_boolean.coverage index 2d927a08356..8f14082ef68 100644 --- a/tests/run-coverage/lazy_boolean.coverage +++ b/tests/run-coverage/lazy_boolean.coverage @@ -32,7 +32,7 @@ ^0 LL| | LL| | if - LL| 1| ! + LL| | ! LL| 1| is_true LL| 0| { LL| 0| a = 2 diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml index 913d72932b9..520481d3bba 100644 --- a/tests/rustdoc-gui/sidebar.goml +++ b/tests/rustdoc-gui/sidebar.goml @@ -25,24 +25,24 @@ call-function: ( "check-colors", { "theme": "ayu", - "color": "rgb(197, 197, 197)", - "background_color": "rgb(20, 25, 31)", + "color": "#c5c5c5", + "background_color": "#14191f", } ) call-function: ( "check-colors", { "theme": "dark", - "color": "rgb(221, 221, 221)", - "background_color": "rgb(80, 80, 80)", + "color": "#ddd", + "background_color": "#505050", } ) call-function: ( "check-colors", { "theme": "light", - "color": "rgb(0, 0, 0)", - "background_color": "rgb(245, 245, 245)", + "color": "black", + "background_color": "#f5f5f5", } ) @@ -55,7 +55,7 @@ assert-text: (".sidebar > .location", "Crate test_docs") assert-count: (".sidebar .location", 1) assert-count: (".sidebar h2", 1) assert-text: ("#all-types", "All Items") -assert-css: ("#all-types", {"color": "rgb(53, 109, 164)"}) +assert-css: ("#all-types", {"color": "#356da4"}) // We check that we have the crates list and that the "current" on is "test_docs". assert-text: (".sidebar-elems ul.crate > li > a.current", "test_docs") // And we're also supposed to have the list of items in the current module. @@ -88,7 +88,7 @@ assert-property: ("html", {"scrollTop": "0"}) // We now go back to the crate page to click on the "lib2" crate link. go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" assert-property: (".sidebar", {"clientWidth": "200"}) -assert-css: (".sidebar-elems ul.crate > li:first-child > a", {"color": "rgb(53, 109, 164)"}) +assert-css: (".sidebar-elems ul.crate > li:first-child > a", {"color": "#356da4"}) click: ".sidebar-elems ul.crate > li:first-child > a" // PAGE: lib2/index.html @@ -140,7 +140,7 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" assert-property: (".sidebar", {"clientWidth": "200"}) click: "//ul[@class='block mod']/preceding-sibling::h3/a" // PAGE: index.html -assert-css: ("#modules", {"background-color": "rgb(253, 255, 211)"}) +assert-css: ("#modules", {"background-color": "#fdffd3"}) // Finally, assert that the `[+]/[−]` toggle doesn't affect sidebar width. click: "#toggle-all-docs" diff --git a/tests/rustdoc-js-std/full-path-function.js b/tests/rustdoc-js-std/full-path-function.js new file mode 100644 index 00000000000..ac157b3aadf --- /dev/null +++ b/tests/rustdoc-js-std/full-path-function.js @@ -0,0 +1,7 @@ +const EXPECTED = { + 'query': 'vec::vec -> usize', + 'others': [ + { 'path': 'std::vec::Vec', 'name': 'len' }, + { 'path': 'std::vec::Vec', 'name': 'capacity' }, + ], +}; diff --git a/tests/rustdoc-js/full-path-function.js b/tests/rustdoc-js/full-path-function.js new file mode 100644 index 00000000000..48be51b156f --- /dev/null +++ b/tests/rustdoc-js/full-path-function.js @@ -0,0 +1,43 @@ +// exact-check + +const EXPECTED = [ + { + 'query': 'sac -> usize', + 'others': [ + { 'path': 'full_path_function::b::Sac', 'name': 'bar' }, + { 'path': 'full_path_function::b::Sac', 'name': 'len' }, + { 'path': 'full_path_function::sac::Sac', 'name': 'len' }, + ], + }, + { + 'query': 'b::sac -> usize', + 'others': [ + { 'path': 'full_path_function::b::Sac', 'name': 'bar' }, + { 'path': 'full_path_function::b::Sac', 'name': 'len' }, + ], + }, + { + 'query': 'b::sac -> u32', + 'others': [ + { 'path': 'full_path_function::b::Sac', 'name': 'bar2' }, + ], + }, + { + 'query': 'string::string -> u32', + 'others': [ + { 'path': 'full_path_function::b::Sac', 'name': 'string' }, + ], + }, + { + 'query': 'alloc::string::string -> u32', + 'others': [ + { 'path': 'full_path_function::b::Sac', 'name': 'string' }, + ], + }, + { + 'query': 'alloc::string -> u32', + 'others': [ + { 'path': 'full_path_function::b::Sac', 'name': 'string' }, + ], + }, +]; diff --git a/tests/rustdoc-js/full-path-function.rs b/tests/rustdoc-js/full-path-function.rs new file mode 100644 index 00000000000..8dcc3f2b69d --- /dev/null +++ b/tests/rustdoc-js/full-path-function.rs @@ -0,0 +1,17 @@ +pub mod sac { + pub struct Sac; + + impl Sac { + pub fn len(&self) -> usize { 0 } + } +} + +pub mod b { + pub struct Sac; + impl Sac { + pub fn len(&self) -> usize { 0 } + pub fn bar(&self, w: u32) -> usize { 0 } + pub fn bar2(&self, w: u32) -> u32 { 0 } + pub fn string(w: String) -> u32 { 0 } + } +} diff --git a/tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs b/tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs index 644d0699e9d..df88530071b 100644 --- a/tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs +++ b/tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs @@ -65,3 +65,22 @@ pub trait HigherRankedBoundTrait1<'e> where for<'l> Self: 'e + 'l {} pub trait AmbiguousBoundTrait<'a, 'b>: 'a + 'b {} pub struct AmbiguousBoundWrapper<'a, 'b, T: ?Sized + 'a + 'b>(&'a T, &'b T); + +// Trait objects inside of another trait object, a trait bound or an associated type. + +pub trait Inner {} +pub trait Outer<T: ?Sized> {} +pub trait Base { + type Type<T: ?Sized>; +} +impl Base for () { + type Type<T: ?Sized> = (); +} + +pub type NestedTraitObjects = dyn Outer<dyn Inner>; + +pub fn apit_rpit(o: impl Outer<dyn Inner>) -> impl Outer<dyn Inner> { + o +} + +pub type AssocTy = <() as Base>::Type<dyn Inner>; diff --git a/tests/rustdoc/inline_cross/dyn_trait.rs b/tests/rustdoc/inline_cross/dyn_trait.rs index 1de01af83d1..679972f035a 100644 --- a/tests/rustdoc/inline_cross/dyn_trait.rs +++ b/tests/rustdoc/inline_cross/dyn_trait.rs @@ -128,3 +128,18 @@ pub use dyn_trait::BareAmbiguousBoundEarly1; // @has user/type.BareAmbiguousBoundStatic.html // @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'o, 'o> + 'static;" pub use dyn_trait::BareAmbiguousBoundStatic; + +// Regression test for issue #115179: + +// @has user/type.NestedTraitObjects.html +// @has - '//*[@class="rust item-decl"]//code' "dyn Outer<dyn Inner>;" +pub use dyn_trait::NestedTraitObjects; + +// @has user/fn.apit_rpit.html +// @has - '//pre[@class="rust item-decl"]' \ +// "apit_rpit(o: impl Outer<dyn Inner>) -> impl Outer<dyn Inner>" +pub use dyn_trait::apit_rpit; + +// @has user/type.AssocTy.html +// @has - '//*[@class="rust item-decl"]//code' "<() as Base>::Type<dyn Inner>" +pub use dyn_trait::AssocTy; diff --git a/tests/rustdoc/show-const-contents.rs b/tests/rustdoc/show-const-contents.rs index 69e742ee747..91df03adbbc 100644 --- a/tests/rustdoc/show-const-contents.rs +++ b/tests/rustdoc/show-const-contents.rs @@ -47,7 +47,7 @@ pub struct MyTypeWithStr(&'static str); // @!hasraw show_const_contents/constant.MY_TYPE_WITH_STR.html '; //' pub const MY_TYPE_WITH_STR: MyTypeWithStr = MyTypeWithStr("show this"); -// @hasraw show_const_contents/constant.PI.html '= 3.14159265358979323846264338327950288f32;' +// @hasraw show_const_contents/constant.PI.html '= 3.14159265358979323846264338327950288_f32;' // @hasraw show_const_contents/constant.PI.html '; // 3.14159274f32' pub use std::f32::consts::PI; diff --git a/tests/ui/argument-suggestions/two-mismatch-notes.stderr b/tests/ui/argument-suggestions/two-mismatch-notes.stderr index 38cf23ddc38..70cc60255c7 100644 --- a/tests/ui/argument-suggestions/two-mismatch-notes.stderr +++ b/tests/ui/argument-suggestions/two-mismatch-notes.stderr @@ -11,7 +11,6 @@ LL | foo(f, w); | ^ = note: expected fn pointer `fn(i32)` found fn item `fn(u32) {f}` - = note: when the arguments and return types match, functions can be coerced to function pointers note: expected `Wrapper<i32>`, found `Wrapper<isize>` --> $DIR/two-mismatch-notes.rs:10:12 | diff --git a/tests/ui/associated-consts/double-elided.rs b/tests/ui/associated-consts/double-elided.rs new file mode 100644 index 00000000000..fd0317781bb --- /dev/null +++ b/tests/ui/associated-consts/double-elided.rs @@ -0,0 +1,12 @@ +struct S; + +impl S { + const C: &&str = &""; + //~^ WARN `&` without an explicit lifetime name cannot be used here + //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //~| WARN `&` without an explicit lifetime name cannot be used here + //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //~| ERROR in type `&&str`, reference has a longer lifetime than the data it references +} + +fn main() {} diff --git a/tests/ui/associated-consts/double-elided.stderr b/tests/ui/associated-consts/double-elided.stderr new file mode 100644 index 00000000000..ba4e6a23e27 --- /dev/null +++ b/tests/ui/associated-consts/double-elided.stderr @@ -0,0 +1,47 @@ +warning: `&` without an explicit lifetime name cannot be used here + --> $DIR/double-elided.rs:4:14 + | +LL | const C: &&str = &""; + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010> + = note: `#[warn(elided_lifetimes_in_associated_constant)]` on by default +help: use the `'static` lifetime + | +LL | const C: &'static &str = &""; + | +++++++ + +warning: `&` without an explicit lifetime name cannot be used here + --> $DIR/double-elided.rs:4:15 + | +LL | const C: &&str = &""; + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010> +help: use the `'static` lifetime + | +LL | const C: &&'static str = &""; + | +++++++ + +error[E0491]: in type `&&str`, reference has a longer lifetime than the data it references + --> $DIR/double-elided.rs:4:5 + | +LL | const C: &&str = &""; + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: the pointer is valid for the anonymous lifetime as defined here + --> $DIR/double-elided.rs:4:14 + | +LL | const C: &&str = &""; + | ^ +note: but the referenced data is only valid for the anonymous lifetime as defined here + --> $DIR/double-elided.rs:4:14 + | +LL | const C: &&str = &""; + | ^ + +error: aborting due to previous error; 2 warnings emitted + +For more information about this error, try `rustc --explain E0491`. diff --git a/tests/ui/associated-inherent-types/private-in-public.rs b/tests/ui/associated-inherent-types/private-in-public.rs index e9e189f95c9..7797a2a16a5 100644 --- a/tests/ui/associated-inherent-types/private-in-public.rs +++ b/tests/ui/associated-inherent-types/private-in-public.rs @@ -1,26 +1,15 @@ +// check-pass + #![feature(inherent_associated_types)] -#![feature(type_privacy_lints)] #![allow(incomplete_features)] #![crate_type = "lib"] -#![deny(private_in_public)] -#![warn(private_interfaces)] - -// In this test both old and new private-in-public diagnostic were emitted. -// Old diagnostic will be deleted soon. -// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. pub type PubAlias0 = PubTy::PrivAssocTy; -//~^ ERROR private associated type `PubTy::PrivAssocTy` in public interface (error E0446) -//~| WARNING this was previously accepted -//~| WARNING associated type `PubTy::PrivAssocTy` is more private than the item `PubAlias0` +//~^ WARNING associated type `PubTy::PrivAssocTy` is more private than the item `PubAlias0` pub type PubAlias1 = PrivTy::PubAssocTy; -//~^ ERROR private type `PrivTy` in public interface (error E0446) -//~| WARNING this was previously accepted -//~| WARNING type `PrivTy` is more private than the item `PubAlias1` +//~^ WARNING type `PrivTy` is more private than the item `PubAlias1` pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>; -//~^ ERROR private type `PrivTy` in public interface (error E0446) -//~| WARNING this was previously accepted -//~| WARNING type `PrivTy` is more private than the item `PubAlias2` +//~^ WARNING type `PrivTy` is more private than the item `PubAlias2` pub struct PubTy; impl PubTy { diff --git a/tests/ui/associated-inherent-types/private-in-public.stderr b/tests/ui/associated-inherent-types/private-in-public.stderr index 65d187c1bcd..076bbd78ae9 100644 --- a/tests/ui/associated-inherent-types/private-in-public.stderr +++ b/tests/ui/associated-inherent-types/private-in-public.stderr @@ -1,75 +1,39 @@ -error: private associated type `PubTy::PrivAssocTy` in public interface (error E0446) - --> $DIR/private-in-public.rs:12:1 - | -LL | pub type PubAlias0 = PubTy::PrivAssocTy; - | ^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> -note: the lint level is defined here - --> $DIR/private-in-public.rs:5:9 - | -LL | #![deny(private_in_public)] - | ^^^^^^^^^^^^^^^^^ - warning: associated type `PubTy::PrivAssocTy` is more private than the item `PubAlias0` - --> $DIR/private-in-public.rs:12:1 + --> $DIR/private-in-public.rs:7:1 | LL | pub type PubAlias0 = PubTy::PrivAssocTy; | ^^^^^^^^^^^^^^^^^^ type alias `PubAlias0` is reachable at visibility `pub` | note: but associated type `PubTy::PrivAssocTy` is only usable at visibility `pub(crate)` - --> $DIR/private-in-public.rs:27:5 + --> $DIR/private-in-public.rs:16:5 | LL | type PrivAssocTy = (); | ^^^^^^^^^^^^^^^^ -note: the lint level is defined here - --> $DIR/private-in-public.rs:6:9 - | -LL | #![warn(private_interfaces)] - | ^^^^^^^^^^^^^^^^^^ - -error: private type `PrivTy` in public interface (error E0446) - --> $DIR/private-in-public.rs:16:1 - | -LL | pub type PubAlias1 = PrivTy::PubAssocTy; - | ^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> + = note: `#[warn(private_interfaces)]` on by default warning: type `PrivTy` is more private than the item `PubAlias1` - --> $DIR/private-in-public.rs:16:1 + --> $DIR/private-in-public.rs:9:1 | LL | pub type PubAlias1 = PrivTy::PubAssocTy; | ^^^^^^^^^^^^^^^^^^ type alias `PubAlias1` is reachable at visibility `pub` | note: but type `PrivTy` is only usable at visibility `pub(crate)` - --> $DIR/private-in-public.rs:31:1 + --> $DIR/private-in-public.rs:20:1 | LL | struct PrivTy; | ^^^^^^^^^^^^^ -error: private type `PrivTy` in public interface (error E0446) - --> $DIR/private-in-public.rs:20:1 - | -LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>; - | ^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> - warning: type `PrivTy` is more private than the item `PubAlias2` - --> $DIR/private-in-public.rs:20:1 + --> $DIR/private-in-public.rs:11:1 | LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>; | ^^^^^^^^^^^^^^^^^^ type alias `PubAlias2` is reachable at visibility `pub` | note: but type `PrivTy` is only usable at visibility `pub(crate)` - --> $DIR/private-in-public.rs:31:1 + --> $DIR/private-in-public.rs:20:1 | LL | struct PrivTy; | ^^^^^^^^^^^^^ -error: aborting due to 3 previous errors; 3 warnings emitted +warning: 3 warnings emitted diff --git a/tests/ui/attributes/issue-115264-expr-field.rs b/tests/ui/attributes/issue-115264-expr-field.rs new file mode 100644 index 00000000000..f53ac4aee66 --- /dev/null +++ b/tests/ui/attributes/issue-115264-expr-field.rs @@ -0,0 +1,17 @@ +// Regression test for issue 115264 +// Tests that retrieving the ident of the X::foo field +// in main() does not cause an ICE + +// check-pass + +#[allow(dead_code)] +struct X { + foo: i32, +} + +fn main() { + let _ = X { + #[doc(alias = "StructItem")] + foo: 123, + }; +} diff --git a/tests/ui/attributes/issue-115264-pat-field.rs b/tests/ui/attributes/issue-115264-pat-field.rs new file mode 100644 index 00000000000..8c6bbe16726 --- /dev/null +++ b/tests/ui/attributes/issue-115264-pat-field.rs @@ -0,0 +1,19 @@ +// Regression test for issue 115264 +// Tests that retrieving the ident of 'foo' variable in +// the pattern inside main() does not cause an ICE + +// check-pass + +struct X { + foo: i32, +} + +#[allow(unused_variables)] +fn main() { + let X { + #[doc(alias = "StructItem")] + foo + } = X { + foo: 123 + }; +} diff --git a/tests/ui/c-variadic/variadic-ffi-1.stderr b/tests/ui/c-variadic/variadic-ffi-1.stderr index c7899338197..4beea83d8a5 100644 --- a/tests/ui/c-variadic/variadic-ffi-1.stderr +++ b/tests/ui/c-variadic/variadic-ffi-1.stderr @@ -46,7 +46,6 @@ LL | let x: unsafe extern "C" fn(f: isize, x: u8) = foo; | = note: expected fn pointer `unsafe extern "C" fn(_, _)` found fn item `unsafe extern "C" fn(_, _, ...) {foo}` - = note: when the arguments and return types match, functions can be coerced to function pointers error[E0308]: mismatched types --> $DIR/variadic-ffi-1.rs:26:54 @@ -58,7 +57,6 @@ LL | let y: extern "C" fn(f: isize, x: u8, ...) = bar; | = note: expected fn pointer `extern "C" fn(_, _, ...)` found fn item `extern "C" fn(_, _) {bar}` - = note: when the arguments and return types match, functions can be coerced to function pointers error[E0617]: can't pass `f32` to variadic function --> $DIR/variadic-ffi-1.rs:28:19 diff --git a/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs index e5464a4253f..8023b998a40 100644 --- a/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs +++ b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs @@ -1,12 +1,6 @@ #![crate_type = "lib"] #![feature(generic_const_exprs)] -#![feature(type_privacy_lints)] #![allow(incomplete_features)] -#![warn(private_interfaces)] - -// In this test both old and new private-in-public diagnostic were emitted. -// Old diagnostic will be deleted soon. -// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. pub struct Const<const U: u8>; @@ -21,7 +15,6 @@ where { type AssocTy = Const<{ my_const_fn(U) }>; //~^ ERROR private type - //~| WARNING type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy` fn assoc_fn() -> Self::AssocTy { Const } diff --git a/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr b/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr index 16fae6b5c63..2d9de8805bb 100644 --- a/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr +++ b/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr @@ -1,5 +1,5 @@ error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface - --> $DIR/eval-privacy.rs:22:5 + --> $DIR/eval-privacy.rs:16:5 | LL | type AssocTy = Const<{ my_const_fn(U) }>; | ^^^^^^^^^^^^ can't leak private type @@ -7,23 +7,6 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>; LL | const fn my_const_fn(val: u8) -> u8 { | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private -warning: type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy` - --> $DIR/eval-privacy.rs:22:5 - | -LL | type AssocTy = Const<{ my_const_fn(U) }>; - | ^^^^^^^^^^^^ associated type `<Const<U> as Trait>::AssocTy` is reachable at visibility `pub` - | -note: but type `fn(u8) -> u8 {my_const_fn}` is only usable at visibility `pub(crate)` - --> $DIR/eval-privacy.rs:30:1 - | -LL | const fn my_const_fn(val: u8) -> u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: the lint level is defined here - --> $DIR/eval-privacy.rs:5:9 - | -LL | #![warn(private_interfaces)] - | ^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/error-codes/E0445.rs b/tests/ui/error-codes/E0445.rs deleted file mode 100644 index 9f29c81673e..00000000000 --- a/tests/ui/error-codes/E0445.rs +++ /dev/null @@ -1,23 +0,0 @@ -#![feature(type_privacy_lints)] -#[warn(private_bounds)] -#[warn(private_interfaces)] - -// In this test both old and new private-in-public diagnostic were emitted. -// Old diagnostic will be deleted soon. -// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. - -trait Foo { - fn dummy(&self) { } -} - -pub trait Bar : Foo {} -//~^ ERROR private trait `Foo` in public interface [E0445] -//~| WARNING trait `Foo` is more private than the item `Bar` -pub struct Bar2<T: Foo>(pub T); -//~^ ERROR private trait `Foo` in public interface [E0445] -//~| WARNING trait `Foo` is more private than the item `Bar2` -pub fn foo<T: Foo> (t: T) {} -//~^ ERROR private trait `Foo` in public interface [E0445] -//~| WARNING trait `Foo` is more private than the item `foo` - -fn main() {} diff --git a/tests/ui/error-codes/E0445.stderr b/tests/ui/error-codes/E0445.stderr deleted file mode 100644 index 4f940868ff9..00000000000 --- a/tests/ui/error-codes/E0445.stderr +++ /dev/null @@ -1,71 +0,0 @@ -error[E0445]: private trait `Foo` in public interface - --> $DIR/E0445.rs:13:1 - | -LL | trait Foo { - | --------- `Foo` declared as private -... -LL | pub trait Bar : Foo {} - | ^^^^^^^^^^^^^^^^^^^ can't leak private trait - -warning: trait `Foo` is more private than the item `Bar` - --> $DIR/E0445.rs:13:1 - | -LL | pub trait Bar : Foo {} - | ^^^^^^^^^^^^^^^^^^^ trait `Bar` is reachable at visibility `pub` - | -note: but trait `Foo` is only usable at visibility `pub(crate)` - --> $DIR/E0445.rs:9:1 - | -LL | trait Foo { - | ^^^^^^^^^ -note: the lint level is defined here - --> $DIR/E0445.rs:2:8 - | -LL | #[warn(private_bounds)] - | ^^^^^^^^^^^^^^ - -error[E0445]: private trait `Foo` in public interface - --> $DIR/E0445.rs:16:1 - | -LL | trait Foo { - | --------- `Foo` declared as private -... -LL | pub struct Bar2<T: Foo>(pub T); - | ^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait - -warning: trait `Foo` is more private than the item `Bar2` - --> $DIR/E0445.rs:16:1 - | -LL | pub struct Bar2<T: Foo>(pub T); - | ^^^^^^^^^^^^^^^^^^^^^^^ struct `Bar2` is reachable at visibility `pub` - | -note: but trait `Foo` is only usable at visibility `pub(crate)` - --> $DIR/E0445.rs:9:1 - | -LL | trait Foo { - | ^^^^^^^^^ - -error[E0445]: private trait `Foo` in public interface - --> $DIR/E0445.rs:19:1 - | -LL | trait Foo { - | --------- `Foo` declared as private -... -LL | pub fn foo<T: Foo> (t: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait - -warning: trait `Foo` is more private than the item `foo` - --> $DIR/E0445.rs:19:1 - | -LL | pub fn foo<T: Foo> (t: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ function `foo` is reachable at visibility `pub` - | -note: but trait `Foo` is only usable at visibility `pub(crate)` - --> $DIR/E0445.rs:9:1 - | -LL | trait Foo { - | ^^^^^^^^^ - -error: aborting due to 3 previous errors; 3 warnings emitted - -For more information about this error, try `rustc --explain E0445`. diff --git a/tests/ui/error-codes/E0446.rs b/tests/ui/error-codes/E0446.rs index f61c7e54616..6d6c4f97c06 100644 --- a/tests/ui/error-codes/E0446.rs +++ b/tests/ui/error-codes/E0446.rs @@ -1,9 +1,14 @@ -mod foo { - struct Bar(u32); +struct Bar; +trait PrivTr {} - pub fn bar() -> Bar { //~ ERROR E0446 - Bar(0) - } +pub trait PubTr { + type Alias1; + type Alias2; +} + +impl PubTr for u8 { + type Alias1 = Bar; //~ ERROR E0446 + type Alias2 = Box<dyn PrivTr>; //~ ERROR E0446 } fn main() {} diff --git a/tests/ui/error-codes/E0446.stderr b/tests/ui/error-codes/E0446.stderr index b6a195c40a9..2951e69d1c2 100644 --- a/tests/ui/error-codes/E0446.stderr +++ b/tests/ui/error-codes/E0446.stderr @@ -1,12 +1,21 @@ error[E0446]: private type `Bar` in public interface - --> $DIR/E0446.rs:4:5 + --> $DIR/E0446.rs:10:5 | -LL | struct Bar(u32); - | ---------- `Bar` declared as private -LL | -LL | pub fn bar() -> Bar { - | ^^^^^^^^^^^^^^^^^^^ can't leak private type +LL | struct Bar; + | ---------- `Bar` declared as private +... +LL | type Alias1 = Bar; + | ^^^^^^^^^^^ can't leak private type -error: aborting due to previous error +error[E0446]: private trait `PrivTr` in public interface + --> $DIR/E0446.rs:11:5 + | +LL | trait PrivTr {} + | ------------ `PrivTr` declared as private +... +LL | type Alias2 = Box<dyn PrivTr>; + | ^^^^^^^^^^^ can't leak private trait + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/feature-gates/feature-gate-type_privacy_lints.rs b/tests/ui/feature-gates/feature-gate-type_privacy_lints.rs index aad64c9d073..8bb9736f1b4 100644 --- a/tests/ui/feature-gates/feature-gate-type_privacy_lints.rs +++ b/tests/ui/feature-gates/feature-gate-type_privacy_lints.rs @@ -1,11 +1,5 @@ // check-pass -#![warn(private_interfaces)] //~ WARN unknown lint - //~| WARN unknown lint - //~| WARN unknown lint -#![warn(private_bounds)] //~ WARN unknown lint - //~| WARN unknown lint - //~| WARN unknown lint #![warn(unnameable_types)] //~ WARN unknown lint //~| WARN unknown lint //~| WARN unknown lint diff --git a/tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr b/tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr index 79cc974cca1..4349fea6f89 100644 --- a/tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr +++ b/tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr @@ -1,26 +1,5 @@ -warning: unknown lint: `private_interfaces` - --> $DIR/feature-gate-type_privacy_lints.rs:3:1 - | -LL | #![warn(private_interfaces)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: the `private_interfaces` lint is unstable - = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information - = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable - = note: `#[warn(unknown_lints)]` on by default - -warning: unknown lint: `private_bounds` - --> $DIR/feature-gate-type_privacy_lints.rs:6:1 - | -LL | #![warn(private_bounds)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: the `private_bounds` lint is unstable - = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information - = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable - warning: unknown lint: `unnameable_types` - --> $DIR/feature-gate-type_privacy_lints.rs:9:1 + --> $DIR/feature-gate-type_privacy_lints.rs:3:1 | LL | #![warn(unnameable_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,29 +7,10 @@ LL | #![warn(unnameable_types)] = note: the `unnameable_types` lint is unstable = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable - -warning: unknown lint: `private_interfaces` - --> $DIR/feature-gate-type_privacy_lints.rs:3:1 - | -LL | #![warn(private_interfaces)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: the `private_interfaces` lint is unstable - = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information - = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable - -warning: unknown lint: `private_bounds` - --> $DIR/feature-gate-type_privacy_lints.rs:6:1 - | -LL | #![warn(private_bounds)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: the `private_bounds` lint is unstable - = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information - = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable + = note: `#[warn(unknown_lints)]` on by default warning: unknown lint: `unnameable_types` - --> $DIR/feature-gate-type_privacy_lints.rs:9:1 + --> $DIR/feature-gate-type_privacy_lints.rs:3:1 | LL | #![warn(unnameable_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -59,28 +19,8 @@ LL | #![warn(unnameable_types)] = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable -warning: unknown lint: `private_interfaces` - --> $DIR/feature-gate-type_privacy_lints.rs:3:1 - | -LL | #![warn(private_interfaces)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: the `private_interfaces` lint is unstable - = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information - = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable - -warning: unknown lint: `private_bounds` - --> $DIR/feature-gate-type_privacy_lints.rs:6:1 - | -LL | #![warn(private_bounds)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: the `private_bounds` lint is unstable - = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information - = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable - warning: unknown lint: `unnameable_types` - --> $DIR/feature-gate-type_privacy_lints.rs:9:1 + --> $DIR/feature-gate-type_privacy_lints.rs:3:1 | LL | #![warn(unnameable_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -89,5 +29,5 @@ LL | #![warn(unnameable_types)] = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable -warning: 9 warnings emitted +warning: 3 warnings emitted diff --git a/tests/ui/fn/fn-pointer-mismatch.stderr b/tests/ui/fn/fn-pointer-mismatch.stderr index a674babcb32..87ece845b83 100644 --- a/tests/ui/fn/fn-pointer-mismatch.stderr +++ b/tests/ui/fn/fn-pointer-mismatch.stderr @@ -80,7 +80,6 @@ LL | let e: &fn(u32) -> u32 = &foo; = note: expected reference `&fn(u32) -> u32` found reference `&fn(u32) -> u32 {foo}` = note: fn items are distinct from fn pointers - = note: when the arguments and return types match, functions can be coerced to function pointers help: consider casting to a fn pointer | LL | let e: &fn(u32) -> u32 = &(foo as fn(u32) -> u32); diff --git a/tests/ui/fn/signature-error-reporting-under-verbose.rs b/tests/ui/fn/signature-error-reporting-under-verbose.rs index 12ff113c913..d00cbd8a0f2 100644 --- a/tests/ui/fn/signature-error-reporting-under-verbose.rs +++ b/tests/ui/fn/signature-error-reporting-under-verbose.rs @@ -12,5 +12,4 @@ fn main() { //~| NOTE expected fn pointer, found fn item //~| NOTE expected fn pointer `fn(i32, u32)` //~| NOTE arguments to this function are incorrect - //~| NOTE when the arguments and return types match, functions can be coerced to function pointers } diff --git a/tests/ui/fn/signature-error-reporting-under-verbose.stderr b/tests/ui/fn/signature-error-reporting-under-verbose.stderr index f4498db7259..067ee824d5d 100644 --- a/tests/ui/fn/signature-error-reporting-under-verbose.stderr +++ b/tests/ui/fn/signature-error-reporting-under-verbose.stderr @@ -8,7 +8,6 @@ LL | needs_ptr(foo); | = note: expected fn pointer `fn(i32, u32)` found fn item `fn(i32, i32) {foo}` - = note: when the arguments and return types match, functions can be coerced to function pointers note: function defined here --> $DIR/signature-error-reporting-under-verbose.rs:5:4 | diff --git a/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs b/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs new file mode 100644 index 00000000000..49d36d6c99c --- /dev/null +++ b/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs @@ -0,0 +1,19 @@ +// check-pass + +#![feature(associated_type_bounds, return_position_impl_trait_in_trait)] + +trait Trait { + type Type; + + fn method(&self) -> impl Trait<Type: '_>; +} + +impl Trait for () { + type Type = (); + + fn method(&self) -> impl Trait<Type: '_> { + () + } +} + +fn main() {} diff --git a/tests/ui/imports/ambiguous-4.rs b/tests/ui/imports/ambiguous-4.rs index 10f883339c3..24ae33784c5 100644 --- a/tests/ui/imports/ambiguous-4.rs +++ b/tests/ui/imports/ambiguous-4.rs @@ -1,4 +1,4 @@ -// check-pass +// build-pass // aux-build: ../ambiguous-4-extern.rs extern crate ambiguous_4_extern; diff --git a/tests/ui/infinite/infinite-type-alias-mutual-recursion.feature.stderr b/tests/ui/infinite/infinite-type-alias-mutual-recursion.feature.stderr new file mode 100644 index 00000000000..8b8fc46dfc5 --- /dev/null +++ b/tests/ui/infinite/infinite-type-alias-mutual-recursion.feature.stderr @@ -0,0 +1,27 @@ +error[E0275]: overflow evaluating the requirement `X2` + --> $DIR/infinite-type-alias-mutual-recursion.rs:6:11 + | +LL | type X1 = X2; + | ^^ + | + = note: in case this is a recursive type alias, consider using a struct, enum, or union instead + +error[E0275]: overflow evaluating the requirement `X3` + --> $DIR/infinite-type-alias-mutual-recursion.rs:9:11 + | +LL | type X2 = X3; + | ^^ + | + = note: in case this is a recursive type alias, consider using a struct, enum, or union instead + +error[E0275]: overflow evaluating the requirement `X1` + --> $DIR/infinite-type-alias-mutual-recursion.rs:11:11 + | +LL | type X3 = X1; + | ^^ + | + = note: in case this is a recursive type alias, consider using a struct, enum, or union instead + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/infinite/infinite-type-alias-mutual-recursion.stderr b/tests/ui/infinite/infinite-type-alias-mutual-recursion.gated.stderr index bbdb1f70b80..ec63688fa8b 100644 --- a/tests/ui/infinite/infinite-type-alias-mutual-recursion.stderr +++ b/tests/ui/infinite/infinite-type-alias-mutual-recursion.gated.stderr @@ -1,16 +1,16 @@ error[E0391]: cycle detected when expanding type alias `X1` - --> $DIR/infinite-type-alias-mutual-recursion.rs:1:11 + --> $DIR/infinite-type-alias-mutual-recursion.rs:6:11 | LL | type X1 = X2; | ^^ | note: ...which requires expanding type alias `X2`... - --> $DIR/infinite-type-alias-mutual-recursion.rs:3:11 + --> $DIR/infinite-type-alias-mutual-recursion.rs:9:11 | LL | type X2 = X3; | ^^ note: ...which requires expanding type alias `X3`... - --> $DIR/infinite-type-alias-mutual-recursion.rs:4:11 + --> $DIR/infinite-type-alias-mutual-recursion.rs:11:11 | LL | type X3 = X1; | ^^ @@ -19,12 +19,13 @@ LL | type X3 = X1; = help: consider using a struct, enum, or union instead to break the cycle = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information note: cycle used when collecting item types in top-level module - --> $DIR/infinite-type-alias-mutual-recursion.rs:1:1 + --> $DIR/infinite-type-alias-mutual-recursion.rs:3:1 | -LL | / type X1 = X2; +LL | / #![cfg_attr(feature, feature(lazy_type_alias))] +LL | | #![allow(incomplete_features)] LL | | -LL | | type X2 = X3; -LL | | type X3 = X1; +LL | | type X1 = X2; +... | LL | | LL | | fn main() {} | |____________^ diff --git a/tests/ui/infinite/infinite-type-alias-mutual-recursion.rs b/tests/ui/infinite/infinite-type-alias-mutual-recursion.rs index 5381eedcfac..90c941c634e 100644 --- a/tests/ui/infinite/infinite-type-alias-mutual-recursion.rs +++ b/tests/ui/infinite/infinite-type-alias-mutual-recursion.rs @@ -1,6 +1,14 @@ +// revisions: feature gated + +#![cfg_attr(feature, feature(lazy_type_alias))] +#![allow(incomplete_features)] + type X1 = X2; -//~^ ERROR cycle detected when expanding type alias `X1` +//[gated]~^ ERROR cycle detected when expanding type alias `X1` +//[feature]~^^ ERROR: overflow evaluating the requirement `X2` type X2 = X3; +//[feature]~^ ERROR: overflow evaluating the requirement `X3` type X3 = X1; +//[feature]~^ ERROR: overflow evaluating the requirement `X1` fn main() {} diff --git a/tests/ui/infinite/infinite-vec-type-recursion.feature.stderr b/tests/ui/infinite/infinite-vec-type-recursion.feature.stderr new file mode 100644 index 00000000000..3a146215905 --- /dev/null +++ b/tests/ui/infinite/infinite-vec-type-recursion.feature.stderr @@ -0,0 +1,11 @@ +error[E0275]: overflow evaluating the requirement `X` + --> $DIR/infinite-vec-type-recursion.rs:6:10 + | +LL | type X = Vec<X>; + | ^^^^^^ + | + = note: in case this is a recursive type alias, consider using a struct, enum, or union instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/infinite/infinite-vec-type-recursion.stderr b/tests/ui/infinite/infinite-vec-type-recursion.gated.stderr index a21b033a9a9..e47d9b652fb 100644 --- a/tests/ui/infinite/infinite-vec-type-recursion.stderr +++ b/tests/ui/infinite/infinite-vec-type-recursion.gated.stderr @@ -1,5 +1,5 @@ error[E0391]: cycle detected when expanding type alias `X` - --> $DIR/infinite-vec-type-recursion.rs:1:14 + --> $DIR/infinite-vec-type-recursion.rs:6:14 | LL | type X = Vec<X>; | ^ @@ -9,11 +9,14 @@ LL | type X = Vec<X>; = help: consider using a struct, enum, or union instead to break the cycle = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information note: cycle used when collecting item types in top-level module - --> $DIR/infinite-vec-type-recursion.rs:1:1 + --> $DIR/infinite-vec-type-recursion.rs:3:1 | -LL | / type X = Vec<X>; -LL | | +LL | / #![cfg_attr(feature, feature(lazy_type_alias))] +LL | | #![allow(incomplete_features)] LL | | +LL | | type X = Vec<X>; +... | +LL | | #[rustfmt::skip] LL | | fn main() { let b: X = Vec::new(); } | |____________________________________^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information diff --git a/tests/ui/infinite/infinite-vec-type-recursion.rs b/tests/ui/infinite/infinite-vec-type-recursion.rs index 35681822598..71ab4a33013 100644 --- a/tests/ui/infinite/infinite-vec-type-recursion.rs +++ b/tests/ui/infinite/infinite-vec-type-recursion.rs @@ -1,4 +1,11 @@ +// revisions: feature gated + +#![cfg_attr(feature, feature(lazy_type_alias))] +#![allow(incomplete_features)] + type X = Vec<X>; -//~^ ERROR cycle detected +//[gated]~^ ERROR cycle detected +//[feature]~^^ ERROR: overflow evaluating the requirement `X` +#[rustfmt::skip] fn main() { let b: X = Vec::new(); } diff --git a/tests/ui/issues/issue-10764.stderr b/tests/ui/issues/issue-10764.stderr index fcb45affe2c..4d8a85a1397 100644 --- a/tests/ui/issues/issue-10764.stderr +++ b/tests/ui/issues/issue-10764.stderr @@ -8,7 +8,6 @@ LL | fn main() { f(bar) } | = note: expected fn pointer `fn()` found fn item `extern "C" fn() {bar}` - = note: when the arguments and return types match, functions can be coerced to function pointers note: function defined here --> $DIR/issue-10764.rs:1:4 | diff --git a/tests/ui/issues/issue-18389.rs b/tests/ui/issues/issue-18389.rs index 05a5decf462..26b607f4081 100644 --- a/tests/ui/issues/issue-18389.rs +++ b/tests/ui/issues/issue-18389.rs @@ -1,9 +1,4 @@ -#![feature(type_privacy_lints)] -#![warn(private_bounds)] - -// In this test both old and new private-in-public diagnostic were emitted. -// Old diagnostic will be deleted soon. -// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. +// check-pass use std::any::Any; use std::any::TypeId; @@ -12,8 +7,7 @@ trait Private<P, R> { fn call(&self, p: P, r: R); } pub trait Public: Private< -//~^ ERROR private trait `Private<<Self as Public>::P, <Self as Public>::R>` in public interface -//~| WARNING trait `Private<<Self as Public>::P, <Self as Public>::R>` is more private than the item `Public` +//~^ WARNING trait `Private<<Self as Public>::P, <Self as Public>::R>` is more private than the item `Public` <Self as Public>::P, <Self as Public>::R > { diff --git a/tests/ui/issues/issue-18389.stderr b/tests/ui/issues/issue-18389.stderr index 18ffc4177d7..4706d1ba177 100644 --- a/tests/ui/issues/issue-18389.stderr +++ b/tests/ui/issues/issue-18389.stderr @@ -1,39 +1,19 @@ -error[E0445]: private trait `Private<<Self as Public>::P, <Self as Public>::R>` in public interface - --> $DIR/issue-18389.rs:14:1 - | -LL | trait Private<P, R> { - | ------------------- `Private<<Self as Public>::P, <Self as Public>::R>` declared as private -... -LL | / pub trait Public: Private< -LL | | -LL | | -LL | | <Self as Public>::P, -LL | | <Self as Public>::R -LL | | > { - | |_^ can't leak private trait - warning: trait `Private<<Self as Public>::P, <Self as Public>::R>` is more private than the item `Public` - --> $DIR/issue-18389.rs:14:1 + --> $DIR/issue-18389.rs:9:1 | LL | / pub trait Public: Private< LL | | -LL | | LL | | <Self as Public>::P, LL | | <Self as Public>::R LL | | > { | |_^ trait `Public` is reachable at visibility `pub` | note: but trait `Private<<Self as Public>::P, <Self as Public>::R>` is only usable at visibility `pub(crate)` - --> $DIR/issue-18389.rs:11:1 + --> $DIR/issue-18389.rs:6:1 | LL | trait Private<P, R> { | ^^^^^^^^^^^^^^^^^^^ -note: the lint level is defined here - --> $DIR/issue-18389.rs:2:9 - | -LL | #![warn(private_bounds)] - | ^^^^^^^^^^^^^^ + = note: `#[warn(private_bounds)]` on by default -error: aborting due to previous error; 1 warning emitted +warning: 1 warning emitted -For more information about this error, try `rustc --explain E0445`. diff --git a/tests/ui/lint/issue-99387.rs b/tests/ui/lint/issue-99387.rs index ba5031167e3..571d4194fe7 100644 --- a/tests/ui/lint/issue-99387.rs +++ b/tests/ui/lint/issue-99387.rs @@ -2,7 +2,7 @@ //! opaque types. #![feature(type_alias_impl_trait)] -#![allow(private_in_public)] +#![allow(private_interfaces)] pub type Successors<'a> = impl Iterator<Item = &'a ()>; diff --git a/tests/ui/lint/lint-ctypes-fn.rs b/tests/ui/lint/lint-ctypes-fn.rs index d3b36a9d59c..14831e24718 100644 --- a/tests/ui/lint/lint-ctypes-fn.rs +++ b/tests/ui/lint/lint-ctypes-fn.rs @@ -1,6 +1,6 @@ #![feature(rustc_private)] -#![allow(private_in_public)] +#![allow(private_interfaces)] #![deny(improper_ctypes_definitions)] extern crate libc; diff --git a/tests/ui/lint/lint-ctypes.rs b/tests/ui/lint/lint-ctypes.rs index 9165e14b7ff..3dd731625f4 100644 --- a/tests/ui/lint/lint-ctypes.rs +++ b/tests/ui/lint/lint-ctypes.rs @@ -1,6 +1,6 @@ #![feature(rustc_private)] -#![allow(private_in_public)] +#![allow(private_interfaces)] #![deny(improper_ctypes)] extern crate libc; diff --git a/tests/ui/lint/unused/unused-parens-issue-106413.rs b/tests/ui/lint/unused/unused-parens-issue-106413.rs new file mode 100644 index 00000000000..7e76ab073b4 --- /dev/null +++ b/tests/ui/lint/unused/unused-parens-issue-106413.rs @@ -0,0 +1,32 @@ +// check-pass +#![warn(unused_parens)] + +fn id<T>(t: T) -> T { t } + +fn main() { + // This should not warn + let _ = 1 as (i32) < 2; + let _ = id(1 as (i32) < 2); + let _ = id(1 as i32) + as (i32) < 2; + // These should warn + let _ = 1 as ((i32)) < 2; //~WARN unnecessary parentheses + let _ = 1 as (i32); //~WARN unnecessary parentheses + let _ = 1 as (i32) > 2; //~WARN unnecessary parentheses + let _ = id(1 as (i32)) //~WARN unnecessary parentheses + as (i32) < 2; + let _ = id(1 as (i32)) < 2; //~WARN unnecessary parentheses + + // This should not warn + let _ = 1 as (i32) << 2; + let _ = id(1 as (i32) << 2); + let _ = id(1 as i32) + as (i32) << 2; + // These should warn + let _ = 1 as ((i32)) << 2; //~WARN unnecessary parentheses + let _ = 1 as (i32); //~WARN unnecessary parentheses + let _ = 1 as (i32) >> 2; //~WARN unnecessary parentheses + let _ = id(1 as (i32)) //~WARN unnecessary parentheses + as (i32) << 2; + let _ = id(1 as (i32)) << 2; //~WARN unnecessary parentheses +} diff --git a/tests/ui/lint/unused/unused-parens-issue-106413.stderr b/tests/ui/lint/unused/unused-parens-issue-106413.stderr new file mode 100644 index 00000000000..d2d8f76d967 --- /dev/null +++ b/tests/ui/lint/unused/unused-parens-issue-106413.stderr @@ -0,0 +1,127 @@ +warning: unnecessary parentheses around type + --> $DIR/unused-parens-issue-106413.rs:13:19 + | +LL | let _ = 1 as ((i32)) < 2; + | ^ ^ + | +note: the lint level is defined here + --> $DIR/unused-parens-issue-106413.rs:2:9 + | +LL | #![warn(unused_parens)] + | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - let _ = 1 as ((i32)) < 2; +LL + let _ = 1 as (i32) < 2; + | + +warning: unnecessary parentheses around type + --> $DIR/unused-parens-issue-106413.rs:14:18 + | +LL | let _ = 1 as (i32); + | ^ ^ + | +help: remove these parentheses + | +LL - let _ = 1 as (i32); +LL + let _ = 1 as i32; + | + +warning: unnecessary parentheses around type + --> $DIR/unused-parens-issue-106413.rs:15:18 + | +LL | let _ = 1 as (i32) > 2; + | ^ ^ + | +help: remove these parentheses + | +LL - let _ = 1 as (i32) > 2; +LL + let _ = 1 as i32 > 2; + | + +warning: unnecessary parentheses around type + --> $DIR/unused-parens-issue-106413.rs:16:21 + | +LL | let _ = id(1 as (i32)) + | ^ ^ + | +help: remove these parentheses + | +LL - let _ = id(1 as (i32)) +LL + let _ = id(1 as i32) + | + +warning: unnecessary parentheses around type + --> $DIR/unused-parens-issue-106413.rs:18:21 + | +LL | let _ = id(1 as (i32)) < 2; + | ^ ^ + | +help: remove these parentheses + | +LL - let _ = id(1 as (i32)) < 2; +LL + let _ = id(1 as i32) < 2; + | + +warning: unnecessary parentheses around type + --> $DIR/unused-parens-issue-106413.rs:26:19 + | +LL | let _ = 1 as ((i32)) << 2; + | ^ ^ + | +help: remove these parentheses + | +LL - let _ = 1 as ((i32)) << 2; +LL + let _ = 1 as (i32) << 2; + | + +warning: unnecessary parentheses around type + --> $DIR/unused-parens-issue-106413.rs:27:18 + | +LL | let _ = 1 as (i32); + | ^ ^ + | +help: remove these parentheses + | +LL - let _ = 1 as (i32); +LL + let _ = 1 as i32; + | + +warning: unnecessary parentheses around type + --> $DIR/unused-parens-issue-106413.rs:28:18 + | +LL | let _ = 1 as (i32) >> 2; + | ^ ^ + | +help: remove these parentheses + | +LL - let _ = 1 as (i32) >> 2; +LL + let _ = 1 as i32 >> 2; + | + +warning: unnecessary parentheses around type + --> $DIR/unused-parens-issue-106413.rs:29:21 + | +LL | let _ = id(1 as (i32)) + | ^ ^ + | +help: remove these parentheses + | +LL - let _ = id(1 as (i32)) +LL + let _ = id(1 as i32) + | + +warning: unnecessary parentheses around type + --> $DIR/unused-parens-issue-106413.rs:31:21 + | +LL | let _ = id(1 as (i32)) << 2; + | ^ ^ + | +help: remove these parentheses + | +LL - let _ = id(1 as (i32)) << 2; +LL + let _ = id(1 as i32) << 2; + | + +warning: 10 warnings emitted + diff --git a/tests/ui/mismatched_types/normalize-fn-sig.stderr b/tests/ui/mismatched_types/normalize-fn-sig.stderr index e3a0646550c..252e56387ba 100644 --- a/tests/ui/mismatched_types/normalize-fn-sig.stderr +++ b/tests/ui/mismatched_types/normalize-fn-sig.stderr @@ -8,7 +8,6 @@ LL | needs_i32_ref_fn(foo::<()>); | = note: expected fn pointer `fn(&'static i32, i32)` found fn item `fn(i32, &'static i32) {foo::<()>}` - = note: when the arguments and return types match, functions can be coerced to function pointers note: function defined here --> $DIR/normalize-fn-sig.rs:11:4 | diff --git a/tests/ui/nll/missing-universe-cause-issue-114907.rs b/tests/ui/nll/missing-universe-cause-issue-114907.rs new file mode 100644 index 00000000000..94acdccfcf2 --- /dev/null +++ b/tests/ui/nll/missing-universe-cause-issue-114907.rs @@ -0,0 +1,40 @@ +// This is a non-regression test for issue #114907 where an ICE happened because of missing +// `UniverseInfo`s accessed during diagnostics. +// +// A couple notes: +// - the `FnOnce` bounds need an arg that is a reference +// - a custom `Drop` is needed somewhere in the type that `accept` returns, to create universes +// during liveness and dropck outlives computation + +// check-fail + +trait Role { + type Inner; +} + +struct HandshakeCallback<C>(C); +impl<C: FnOnce(&())> Role for HandshakeCallback<C> { + type Inner = (); +} + +struct Handshake<R: Role> { + _inner: Option<R::Inner>, +} +impl<R: Role> Drop for Handshake<R> { + fn drop(&mut self) {} +} + +fn accept<C: FnOnce(&())>(_: C) -> Handshake<HandshakeCallback<C>> { + todo!() +} + +fn main() { + let callback = |_| {}; + accept(callback); + //~^ ERROR mismatched types + //~| ERROR mismatched types + //~| ERROR implementation of `FnOnce` is not general enough + //~| ERROR implementation of `FnOnce` is not general enough + //~| ERROR higher-ranked subtype error + //~| ERROR higher-ranked subtype error +} diff --git a/tests/ui/nll/missing-universe-cause-issue-114907.stderr b/tests/ui/nll/missing-universe-cause-issue-114907.stderr new file mode 100644 index 00000000000..c3dd4257a73 --- /dev/null +++ b/tests/ui/nll/missing-universe-cause-issue-114907.stderr @@ -0,0 +1,79 @@ +error[E0308]: mismatched types + --> $DIR/missing-universe-cause-issue-114907.rs:33:5 + | +LL | accept(callback); + | ^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected trait `for<'a> FnOnce<(&'a (),)>` + found trait `FnOnce<(&(),)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/missing-universe-cause-issue-114907.rs:32:20 + | +LL | let callback = |_| {}; + | ^^^ +note: the lifetime requirement is introduced here + --> $DIR/missing-universe-cause-issue-114907.rs:27:14 + | +LL | fn accept<C: FnOnce(&())>(_: C) -> Handshake<HandshakeCallback<C>> { + | ^^^^^^^^^^^ +help: consider specifying the type of the closure parameters + | +LL | let callback = |_: &_| {}; + | ~~~~~~~ + +error: implementation of `FnOnce` is not general enough + --> $DIR/missing-universe-cause-issue-114907.rs:33:5 + | +LL | accept(callback); + | ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2` + +error: implementation of `FnOnce` is not general enough + --> $DIR/missing-universe-cause-issue-114907.rs:33:5 + | +LL | accept(callback); + | ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2` + +error[E0308]: mismatched types + --> $DIR/missing-universe-cause-issue-114907.rs:33:5 + | +LL | accept(callback); + | ^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected trait `for<'a> FnOnce<(&'a (),)>` + found trait `FnOnce<(&(),)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/missing-universe-cause-issue-114907.rs:32:20 + | +LL | let callback = |_| {}; + | ^^^ +note: the lifetime requirement is introduced here + --> $DIR/missing-universe-cause-issue-114907.rs:20:21 + | +LL | struct Handshake<R: Role> { + | ^^^^ +help: consider specifying the type of the closure parameters + | +LL | let callback = |_: &_| {}; + | ~~~~~~~ + +error: higher-ranked subtype error + --> $DIR/missing-universe-cause-issue-114907.rs:33:21 + | +LL | accept(callback); + | ^ + +error: higher-ranked subtype error + --> $DIR/missing-universe-cause-issue-114907.rs:33:21 + | +LL | accept(callback); + | ^ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/privacy/associated-item-privacy-inherent.rs b/tests/ui/privacy/associated-item-privacy-inherent.rs index 7b7c734a99a..81703ae1067 100644 --- a/tests/ui/privacy/associated-item-privacy-inherent.rs +++ b/tests/ui/privacy/associated-item-privacy-inherent.rs @@ -1,5 +1,5 @@ #![feature(decl_macro, associated_type_defaults)] -#![allow(unused, private_in_public)] +#![allow(private_interfaces)] mod priv_nominal { pub struct Pub; diff --git a/tests/ui/privacy/associated-item-privacy-trait.rs b/tests/ui/privacy/associated-item-privacy-trait.rs index c686a21772e..db77a6a7258 100644 --- a/tests/ui/privacy/associated-item-privacy-trait.rs +++ b/tests/ui/privacy/associated-item-privacy-trait.rs @@ -1,5 +1,5 @@ #![feature(decl_macro, associated_type_defaults)] -#![allow(unused, private_in_public)] +#![allow(private_interfaces, private_bounds)] mod priv_trait { trait PrivTr { diff --git a/tests/ui/privacy/associated-item-privacy-type-binding.rs b/tests/ui/privacy/associated-item-privacy-type-binding.rs index 9826b83a35d..95a4fbf639c 100644 --- a/tests/ui/privacy/associated-item-privacy-type-binding.rs +++ b/tests/ui/privacy/associated-item-privacy-type-binding.rs @@ -1,5 +1,5 @@ #![feature(decl_macro, associated_type_defaults)] -#![allow(unused, private_in_public)] +#![allow(private_interfaces, private_bounds)] mod priv_trait { trait PrivTr { diff --git a/tests/ui/privacy/effective_visibilities_full_priv.rs b/tests/ui/privacy/effective_visibilities_full_priv.rs index a26ae3bd122..b96eddcab67 100644 --- a/tests/ui/privacy/effective_visibilities_full_priv.rs +++ b/tests/ui/privacy/effective_visibilities_full_priv.rs @@ -1,5 +1,5 @@ #![feature(rustc_attrs)] -#![allow(private_in_public)] +#![allow(private_interfaces)] struct SemiPriv; diff --git a/tests/ui/privacy/issue-30079.rs b/tests/ui/privacy/issue-30079.rs index a02a932d057..ddba629f528 100644 --- a/tests/ui/privacy/issue-30079.rs +++ b/tests/ui/privacy/issue-30079.rs @@ -3,8 +3,7 @@ struct SemiPriv; mod m1 { struct Priv; impl ::SemiPriv { - pub fn f(_: Priv) {} //~ WARN private type `m1::Priv` in public interface - //~^ WARNING hard error + pub fn f(_: Priv) {} //~ WARN type `m1::Priv` is more private than the item `m1::<impl SemiPriv>::f` } impl Priv { diff --git a/tests/ui/privacy/issue-30079.stderr b/tests/ui/privacy/issue-30079.stderr index 9179ff339bf..f1facba7cd2 100644 --- a/tests/ui/privacy/issue-30079.stderr +++ b/tests/ui/privacy/issue-30079.stderr @@ -1,15 +1,18 @@ -warning: private type `m1::Priv` in public interface (error E0446) +warning: type `m1::Priv` is more private than the item `m1::<impl SemiPriv>::f` --> $DIR/issue-30079.rs:6:9 | LL | pub fn f(_: Priv) {} - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ associated function `m1::<impl SemiPriv>::f` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> - = note: `#[warn(private_in_public)]` on by default +note: but type `m1::Priv` is only usable at visibility `pub(self)` + --> $DIR/issue-30079.rs:4:5 + | +LL | struct Priv; + | ^^^^^^^^^^^ + = note: `#[warn(private_interfaces)]` on by default error[E0446]: private type `m2::Priv` in public interface - --> $DIR/issue-30079.rs:18:9 + --> $DIR/issue-30079.rs:17:9 | LL | struct Priv; | ----------- `m2::Priv` declared as private @@ -18,7 +21,7 @@ LL | type Target = Priv; | ^^^^^^^^^^^ can't leak private type error[E0446]: private type `m3::Priv` in public interface - --> $DIR/issue-30079.rs:35:9 + --> $DIR/issue-30079.rs:34:9 | LL | struct Priv; | ----------- `m3::Priv` declared as private diff --git a/tests/ui/privacy/private-in-public-assoc-ty.rs b/tests/ui/privacy/private-in-public-assoc-ty.rs index d4d379bdb73..5f7c4bcf265 100644 --- a/tests/ui/privacy/private-in-public-assoc-ty.rs +++ b/tests/ui/privacy/private-in-public-assoc-ty.rs @@ -22,14 +22,11 @@ mod m { // applies only to the aliased types, not bounds. pub trait PubTr { type Alias1: PrivTr; - //~^ WARN private trait `PrivTr` in public interface - //~| WARN this was previously accepted + //~^ WARN trait `PrivTr` is more private than the item `PubTr::Alias1` type Alias2: PubTrAux1<Priv> = u8; - //~^ WARN private type `Priv` in public interface - //~| WARN this was previously accepted + //~^ WARN type `Priv` is more private than the item `PubTr::Alias2` type Alias3: PubTrAux2<A = Priv> = u8; - //~^ WARN private type `Priv` in public interface - //~| WARN this was previously accepted + //~^ WARN type `Priv` is more private than the item `PubTr::Alias3` type Alias4 = Priv; //~^ ERROR private type `Priv` in public interface diff --git a/tests/ui/privacy/private-in-public-assoc-ty.stderr b/tests/ui/privacy/private-in-public-assoc-ty.stderr index a59027d81d2..0931e6d9971 100644 --- a/tests/ui/privacy/private-in-public-assoc-ty.stderr +++ b/tests/ui/privacy/private-in-public-assoc-ty.stderr @@ -7,36 +7,45 @@ LL | struct Priv; LL | type A = Priv; | ^^^^^^ can't leak private type -warning: private trait `PrivTr` in public interface (error E0445) +warning: trait `PrivTr` is more private than the item `PubTr::Alias1` --> $DIR/private-in-public-assoc-ty.rs:24:9 | LL | type Alias1: PrivTr; - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ associated type `PubTr::Alias1` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> - = note: `#[warn(private_in_public)]` on by default +note: but trait `PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-assoc-ty.rs:9:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ + = note: `#[warn(private_bounds)]` on by default -warning: private type `Priv` in public interface (error E0446) - --> $DIR/private-in-public-assoc-ty.rs:27:9 +warning: type `Priv` is more private than the item `PubTr::Alias2` + --> $DIR/private-in-public-assoc-ty.rs:26:9 | LL | type Alias2: PubTrAux1<Priv> = u8; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated type `PubTr::Alias2` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: but type `Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-assoc-ty.rs:8:5 + | +LL | struct Priv; + | ^^^^^^^^^^^ -warning: private type `Priv` in public interface (error E0446) - --> $DIR/private-in-public-assoc-ty.rs:30:9 +warning: type `Priv` is more private than the item `PubTr::Alias3` + --> $DIR/private-in-public-assoc-ty.rs:28:9 | LL | type Alias3: PubTrAux2<A = Priv> = u8; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated type `PubTr::Alias3` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: but type `Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-assoc-ty.rs:8:5 + | +LL | struct Priv; + | ^^^^^^^^^^^ error[E0446]: private type `Priv` in public interface - --> $DIR/private-in-public-assoc-ty.rs:34:9 + --> $DIR/private-in-public-assoc-ty.rs:31:9 | LL | struct Priv; | ----------- `Priv` declared as private @@ -45,7 +54,7 @@ LL | type Alias4 = Priv; | ^^^^^^^^^^^ can't leak private type error[E0446]: private type `Priv` in public interface - --> $DIR/private-in-public-assoc-ty.rs:41:9 + --> $DIR/private-in-public-assoc-ty.rs:38:9 | LL | struct Priv; | ----------- `Priv` declared as private @@ -53,8 +62,8 @@ LL | struct Priv; LL | type Alias1 = Priv; | ^^^^^^^^^^^ can't leak private type -error[E0445]: private trait `PrivTr` in public interface - --> $DIR/private-in-public-assoc-ty.rs:44:9 +error[E0446]: private trait `PrivTr` in public interface + --> $DIR/private-in-public-assoc-ty.rs:41:9 | LL | trait PrivTr {} | ------------ `PrivTr` declared as private @@ -64,5 +73,4 @@ LL | type Exist = impl PrivTr; error: aborting due to 4 previous errors; 3 warnings emitted -Some errors have detailed explanations: E0445, E0446. -For more information about an error, try `rustc --explain E0445`. +For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/privacy/private-in-public-lint.rs b/tests/ui/privacy/private-in-public-lint.rs deleted file mode 100644 index 8b6e4360160..00000000000 --- a/tests/ui/privacy/private-in-public-lint.rs +++ /dev/null @@ -1,19 +0,0 @@ -mod m1 { - pub struct Pub; - struct Priv; - - impl Pub { - pub fn f() -> Priv {Priv} //~ ERROR private type `m1::Priv` in public interface - } -} - -mod m2 { - pub struct Pub; - struct Priv; - - impl Pub { - pub fn f() -> Priv {Priv} //~ ERROR private type `m2::Priv` in public interface - } -} - -fn main() {} diff --git a/tests/ui/privacy/private-in-public-lint.stderr b/tests/ui/privacy/private-in-public-lint.stderr deleted file mode 100644 index 1e98e3bed14..00000000000 --- a/tests/ui/privacy/private-in-public-lint.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0446]: private type `m1::Priv` in public interface - --> $DIR/private-in-public-lint.rs:6:9 - | -LL | struct Priv; - | ----------- `m1::Priv` declared as private -... -LL | pub fn f() -> Priv {Priv} - | ^^^^^^^^^^^^^^^^^^ can't leak private type - -error[E0446]: private type `m2::Priv` in public interface - --> $DIR/private-in-public-lint.rs:15:9 - | -LL | struct Priv; - | ----------- `m2::Priv` declared as private -... -LL | pub fn f() -> Priv {Priv} - | ^^^^^^^^^^^^^^^^^^ can't leak private type - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/privacy/private-in-public-non-principal-2.rs b/tests/ui/privacy/private-in-public-non-principal-2.rs index db451d33429..d7223c647c0 100644 --- a/tests/ui/privacy/private-in-public-non-principal-2.rs +++ b/tests/ui/privacy/private-in-public-non-principal-2.rs @@ -1,7 +1,7 @@ #![feature(auto_traits)] #![feature(negative_impls)] -#[allow(private_in_public)] +#[allow(private_interfaces)] mod m { pub trait PubPrincipal {} auto trait PrivNonPrincipal {} diff --git a/tests/ui/privacy/private-in-public-non-principal.rs b/tests/ui/privacy/private-in-public-non-principal.rs index a2284c93027..e348a181651 100644 --- a/tests/ui/privacy/private-in-public-non-principal.rs +++ b/tests/ui/privacy/private-in-public-non-principal.rs @@ -1,19 +1,11 @@ #![feature(auto_traits)] #![feature(negative_impls)] -#![feature(type_privacy_lints)] -#![deny(private_interfaces)] - -// In this test both old and new private-in-public diagnostic were emitted. -// Old diagnostic will be deleted soon. -// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. pub trait PubPrincipal {} auto trait PrivNonPrincipal {} pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} } -//~^ WARN private trait `PrivNonPrincipal` in public interface -//~| WARN this was previously accepted -//~| ERROR trait `PrivNonPrincipal` is more private than the item `leak_dyn_nonprincipal` +//~^ WARN trait `PrivNonPrincipal` is more private than the item `leak_dyn_nonprincipal` #[deny(missing_docs)] fn container() { diff --git a/tests/ui/privacy/private-in-public-non-principal.stderr b/tests/ui/privacy/private-in-public-non-principal.stderr index 1387f59cbde..63512f462f5 100644 --- a/tests/ui/privacy/private-in-public-non-principal.stderr +++ b/tests/ui/privacy/private-in-public-non-principal.stderr @@ -1,41 +1,27 @@ -warning: private trait `PrivNonPrincipal` in public interface (error E0445) - --> $DIR/private-in-public-non-principal.rs:13:1 - | -LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> - = note: `#[warn(private_in_public)]` on by default - -error: trait `PrivNonPrincipal` is more private than the item `leak_dyn_nonprincipal` - --> $DIR/private-in-public-non-principal.rs:13:1 +warning: trait `PrivNonPrincipal` is more private than the item `leak_dyn_nonprincipal` + --> $DIR/private-in-public-non-principal.rs:7:1 | LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `leak_dyn_nonprincipal` is reachable at visibility `pub` | note: but trait `PrivNonPrincipal` is only usable at visibility `pub(crate)` - --> $DIR/private-in-public-non-principal.rs:11:1 + --> $DIR/private-in-public-non-principal.rs:5:1 | LL | auto trait PrivNonPrincipal {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: the lint level is defined here - --> $DIR/private-in-public-non-principal.rs:4:9 - | -LL | #![deny(private_interfaces)] - | ^^^^^^^^^^^^^^^^^^ + = note: `#[warn(private_interfaces)]` on by default error: missing documentation for an associated function - --> $DIR/private-in-public-non-principal.rs:21:9 + --> $DIR/private-in-public-non-principal.rs:13:9 | LL | pub fn check_doc_lint() {} | ^^^^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/private-in-public-non-principal.rs:18:8 + --> $DIR/private-in-public-non-principal.rs:10:8 | LL | #[deny(missing_docs)] | ^^^^^^^^^^^^ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to previous error; 1 warning emitted diff --git a/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs b/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs index fe6ed46734c..3fb543e9624 100644 --- a/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs +++ b/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs @@ -1,7 +1,7 @@ // build-pass (FIXME(62277): could be check-pass?) #![feature(impl_trait_in_assoc_type)] #![feature(type_alias_impl_trait)] -#![deny(private_in_public)] +#![deny(private_interfaces, private_bounds)] pub type Pub = impl Default; diff --git a/tests/ui/privacy/private-in-public-warn.rs b/tests/ui/privacy/private-in-public-warn.rs index 0fa1de975b0..99d318e36be 100644 --- a/tests/ui/privacy/private-in-public-warn.rs +++ b/tests/ui/privacy/private-in-public-warn.rs @@ -2,7 +2,7 @@ // This test also ensures that the checks are performed even inside private modules. #![feature(associated_type_defaults)] -#![deny(private_in_public)] +#![deny(private_interfaces, private_bounds)] #![allow(improper_ctypes)] mod types { @@ -12,30 +12,21 @@ mod types { type Alias; } - pub type Alias = Priv; //~ ERROR private type `types::Priv` in public interface - //~^ WARNING hard error + pub type Alias = Priv; //~ ERROR type `types::Priv` is more private than the item `types::Alias` pub enum E { - V1(Priv), //~ ERROR private type `types::Priv` in public interface - //~^ WARNING hard error - V2 { field: Priv }, //~ ERROR private type `types::Priv` in public interface - //~^ WARNING hard error + V1(Priv), //~ ERROR type `types::Priv` is more private than the item `E::V1::0` + V2 { field: Priv }, //~ ERROR type `types::Priv` is more private than the item `E::V2::field` } pub trait Tr { - const C: Priv = Priv; //~ ERROR private type `types::Priv` in public interface - //~^ WARNING hard error + const C: Priv = Priv; //~ ERROR type `types::Priv` is more private than the item `Tr::C` type Alias = Priv; //~ ERROR private type `types::Priv` in public interface - fn f1(arg: Priv) {} //~ ERROR private type `types::Priv` in public interface - //~^ WARNING hard error - fn f2() -> Priv { panic!() } //~ ERROR private type `types::Priv` in public interface - //~^ WARNING hard error + fn f1(arg: Priv) {} //~ ERROR type `types::Priv` is more private than the item `Tr::f1` + fn f2() -> Priv { panic!() } //~ ERROR type `types::Priv` is more private than the item `Tr::f2` } extern "C" { - pub static ES: Priv; //~ ERROR private type `types::Priv` in public interface - //~^ WARNING hard error - pub fn ef1(arg: Priv); //~ ERROR private type `types::Priv` in public interface - //~^ WARNING hard error - pub fn ef2() -> Priv; //~ ERROR private type `types::Priv` in public interface - //~^ WARNING hard error + pub static ES: Priv; //~ ERROR type `types::Priv` is more private than the item `types::ES` + pub fn ef1(arg: Priv); //~ ERROR type `types::Priv` is more private than the item `types::ef1` + pub fn ef2() -> Priv; //~ ERROR type `types::Priv` is more private than the item `types::ef2` } impl PubTr for Pub { type Alias = Priv; //~ ERROR private type `types::Priv` in public interface @@ -47,22 +38,16 @@ mod traits { pub struct Pub<T>(T); pub trait PubTr {} - pub type Alias<T: PrivTr> = T; //~ ERROR private trait `traits::PrivTr` in public interface - //~| WARNING hard error - //~| WARNING bounds on generic parameters are not enforced in type aliases - pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface - //~^ WARNING hard error - pub trait Tr2<T: PrivTr> {} //~ ERROR private trait `traits::PrivTr` in public interface - //~^ WARNING hard error + pub type Alias<T: PrivTr> = T; //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Alias` + //~^ WARNING bounds on generic parameters are not enforced in type aliases + pub trait Tr1: PrivTr {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr1` + pub trait Tr2<T: PrivTr> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr2` pub trait Tr3 { type Alias: PrivTr; - //~^ ERROR private trait `traits::PrivTr` in public interface - //~| WARNING hard error - fn f<T: PrivTr>(arg: T) {} //~ ERROR private trait `traits::PrivTr` in public interface - //~^ WARNING hard error + //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::Alias` + fn f<T: PrivTr>(arg: T) {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::f` } - impl<T: PrivTr> Pub<T> {} //~ ERROR private trait `traits::PrivTr` in public interface - //~^ WARNING hard error + impl<T: PrivTr> Pub<T> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Pub<T>` impl<T: PrivTr> PubTr for Pub<T> {} // OK, trait impl predicates } @@ -72,20 +57,16 @@ mod traits_where { pub trait PubTr {} pub type Alias<T> where T: PrivTr = T; - //~^ ERROR private trait `traits_where::PrivTr` in public interface - //~| WARNING hard error + //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Alias` //~| WARNING where clauses are not enforced in type aliases pub trait Tr2<T> where T: PrivTr {} - //~^ ERROR private trait `traits_where::PrivTr` in public interface - //~| WARNING hard error + //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2` pub trait Tr3 { fn f<T>(arg: T) where T: PrivTr {} - //~^ ERROR private trait `traits_where::PrivTr` in public interface - //~| WARNING hard error + //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Tr3::f` } impl<T> Pub<T> where T: PrivTr {} - //~^ ERROR private trait `traits_where::PrivTr` in public interface - //~| WARNING hard error + //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Pub<T>` impl<T> PubTr for Pub<T> where T: PrivTr {} // OK, trait impl predicates } @@ -96,14 +77,10 @@ mod generics { pub trait PubTr<T> {} pub trait Tr1: PrivTr<Pub> {} - //~^ ERROR private trait `generics::PrivTr<generics::Pub>` in public interface - //~| WARNING hard error - pub trait Tr2: PubTr<Priv> {} //~ ERROR private type `generics::Priv` in public interface - //~^ WARNING hard error - pub trait Tr3: PubTr<[Priv; 1]> {} //~ ERROR private type `generics::Priv` in public interface - //~^ WARNING hard error - pub trait Tr4: PubTr<Pub<Priv>> {} //~ ERROR private type `generics::Priv` in public interface - //~^ WARNING hard error + //~^ ERROR trait `generics::PrivTr<generics::Pub>` is more private than the item `generics::Tr1` + pub trait Tr2: PubTr<Priv> {} //~ ERROR type `generics::Priv` is more private than the item `generics::Tr2` + pub trait Tr3: PubTr<[Priv; 1]> {} //~ ERROR type `generics::Priv` is more private than the item `generics::Tr3` + pub trait Tr4: PubTr<Pub<Priv>> {} //~ ERROR type `generics::Priv` is more private than the item `Tr4` } mod impls { @@ -200,8 +177,7 @@ mod aliases_pub { pub trait Tr2: PrivUseAliasTr<PrivAlias> {} // OK impl PrivAlias { - pub fn f(arg: Priv) {} //~ ERROR private type `aliases_pub::Priv` in public interface - //~^ WARNING hard error + pub fn f(arg: Priv) {} //~ ERROR type `aliases_pub::Priv` is more private than the item `aliases_pub::<impl Pub2>::f` } impl PrivUseAliasTr for PrivUseAlias { type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in public interface @@ -244,13 +220,10 @@ mod aliases_priv { } pub trait Tr1: PrivUseAliasTr {} - //~^ ERROR private trait `PrivTr1` in public interface - //~| WARNING hard error + //~^ ERROR trait `PrivTr1` is more private than the item `aliases_priv::Tr1` pub trait Tr2: PrivUseAliasTr<PrivAlias> {} - //~^ ERROR private trait `PrivTr1<Priv2>` in public interface - //~| WARNING hard error - //~| ERROR private type `Priv2` in public interface - //~| WARNING hard error + //~^ ERROR trait `PrivTr1<Priv2>` is more private than the item `aliases_priv::Tr2` + //~| ERROR type `Priv2` is more private than the item `aliases_priv::Tr2` impl PrivUseAlias { pub fn f(arg: Priv) {} // OK diff --git a/tests/ui/privacy/private-in-public-warn.stderr b/tests/ui/privacy/private-in-public-warn.stderr index 66f91ce6fd6..6497b7ff535 100644 --- a/tests/ui/privacy/private-in-public-warn.stderr +++ b/tests/ui/privacy/private-in-public-warn.stderr @@ -1,46 +1,58 @@ -error: private type `types::Priv` in public interface (error E0446) +error: type `types::Priv` is more private than the item `types::Alias` --> $DIR/private-in-public-warn.rs:15:5 | LL | pub type Alias = Priv; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ type alias `types::Alias` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:9:5 + | +LL | struct Priv; + | ^^^^^^^^^^^ note: the lint level is defined here --> $DIR/private-in-public-warn.rs:5:9 | -LL | #![deny(private_in_public)] - | ^^^^^^^^^^^^^^^^^ +LL | #![deny(private_interfaces, private_bounds)] + | ^^^^^^^^^^^^^^^^^^ -error: private type `types::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:18:12 +error: type `types::Priv` is more private than the item `E::V1::0` + --> $DIR/private-in-public-warn.rs:17:12 | LL | V1(Priv), - | ^^^^ + | ^^^^ field `E::V1::0` is reachable at visibility `pub(crate)` + | +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:9:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +LL | struct Priv; + | ^^^^^^^^^^^ -error: private type `types::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:20:14 +error: type `types::Priv` is more private than the item `E::V2::field` + --> $DIR/private-in-public-warn.rs:18:14 | LL | V2 { field: Priv }, - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ field `E::V2::field` is reachable at visibility `pub(crate)` + | +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:9:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +LL | struct Priv; + | ^^^^^^^^^^^ -error: private type `types::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:24:9 +error: type `types::Priv` is more private than the item `Tr::C` + --> $DIR/private-in-public-warn.rs:21:9 | LL | const C: Priv = Priv; - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ associated constant `Tr::C` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:9:5 + | +LL | struct Priv; + | ^^^^^^^^^^^ error[E0446]: private type `types::Priv` in public interface - --> $DIR/private-in-public-warn.rs:26:9 + --> $DIR/private-in-public-warn.rs:22:9 | LL | struct Priv; | ----------- `types::Priv` declared as private @@ -48,53 +60,68 @@ LL | struct Priv; LL | type Alias = Priv; | ^^^^^^^^^^ can't leak private type -error: private type `types::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:27:9 +error: type `types::Priv` is more private than the item `Tr::f1` + --> $DIR/private-in-public-warn.rs:23:9 | LL | fn f1(arg: Priv) {} - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ associated function `Tr::f1` is reachable at visibility `pub(crate)` + | +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:9:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +LL | struct Priv; + | ^^^^^^^^^^^ -error: private type `types::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:29:9 +error: type `types::Priv` is more private than the item `Tr::f2` + --> $DIR/private-in-public-warn.rs:24:9 | LL | fn f2() -> Priv { panic!() } - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ associated function `Tr::f2` is reachable at visibility `pub(crate)` + | +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:9:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +LL | struct Priv; + | ^^^^^^^^^^^ -error: private type `types::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:33:9 +error: type `types::Priv` is more private than the item `types::ES` + --> $DIR/private-in-public-warn.rs:27:9 | LL | pub static ES: Priv; - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ static `types::ES` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:9:5 + | +LL | struct Priv; + | ^^^^^^^^^^^ -error: private type `types::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:35:9 +error: type `types::Priv` is more private than the item `types::ef1` + --> $DIR/private-in-public-warn.rs:28:9 | LL | pub fn ef1(arg: Priv); - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ function `types::ef1` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:9:5 + | +LL | struct Priv; + | ^^^^^^^^^^^ -error: private type `types::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:37:9 +error: type `types::Priv` is more private than the item `types::ef2` + --> $DIR/private-in-public-warn.rs:29:9 | LL | pub fn ef2() -> Priv; - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ function `types::ef2` is reachable at visibility `pub(crate)` + | +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:9:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +LL | struct Priv; + | ^^^^^^^^^^^ error[E0446]: private type `types::Priv` in public interface - --> $DIR/private-in-public-warn.rs:41:9 + --> $DIR/private-in-public-warn.rs:32:9 | LL | struct Priv; | ----------- `types::Priv` declared as private @@ -102,134 +129,181 @@ LL | struct Priv; LL | type Alias = Priv; | ^^^^^^^^^^ can't leak private type -error: private trait `traits::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:50:5 +error: trait `traits::PrivTr` is more private than the item `traits::Alias` + --> $DIR/private-in-public-warn.rs:41:5 | LL | pub type Alias<T: PrivTr> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ type alias `traits::Alias` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:37:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/private-in-public-warn.rs:5:29 + | +LL | #![deny(private_interfaces, private_bounds)] + | ^^^^^^^^^^^^^^ -error: private trait `traits::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:53:5 +error: trait `traits::PrivTr` is more private than the item `traits::Tr1` + --> $DIR/private-in-public-warn.rs:43:5 | LL | pub trait Tr1: PrivTr {} - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ trait `traits::Tr1` is reachable at visibility `pub(crate)` + | +note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:37:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +LL | trait PrivTr {} + | ^^^^^^^^^^^^ -error: private trait `traits::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:55:5 +error: trait `traits::PrivTr` is more private than the item `traits::Tr2` + --> $DIR/private-in-public-warn.rs:44:5 | LL | pub trait Tr2<T: PrivTr> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ trait `traits::Tr2` is reachable at visibility `pub(crate)` + | +note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:37:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +LL | trait PrivTr {} + | ^^^^^^^^^^^^ -error: private trait `traits::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:58:9 +error: trait `traits::PrivTr` is more private than the item `traits::Tr3::Alias` + --> $DIR/private-in-public-warn.rs:46:9 | LL | type Alias: PrivTr; - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ associated type `traits::Tr3::Alias` is reachable at visibility `pub(crate)` + | +note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:37:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +LL | trait PrivTr {} + | ^^^^^^^^^^^^ -error: private trait `traits::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:61:9 +error: trait `traits::PrivTr` is more private than the item `traits::Tr3::f` + --> $DIR/private-in-public-warn.rs:48:9 | LL | fn f<T: PrivTr>(arg: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits::Tr3::f` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:37:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ -error: private trait `traits::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:64:5 +error: trait `traits::PrivTr` is more private than the item `traits::Pub<T>` + --> $DIR/private-in-public-warn.rs:50:5 | LL | impl<T: PrivTr> Pub<T> {} - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ implementation `traits::Pub<T>` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:37:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ -error: private trait `traits_where::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:74:5 +error: trait `traits_where::PrivTr` is more private than the item `traits_where::Alias` + --> $DIR/private-in-public-warn.rs:59:5 | LL | pub type Alias<T> where T: PrivTr = T; - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ type alias `traits_where::Alias` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:55:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ -error: private trait `traits_where::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:78:5 +error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2` + --> $DIR/private-in-public-warn.rs:62:5 | LL | pub trait Tr2<T> where T: PrivTr {} - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ trait `traits_where::Tr2` is reachable at visibility `pub(crate)` + | +note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:55:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +LL | trait PrivTr {} + | ^^^^^^^^^^^^ -error: private trait `traits_where::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:82:9 +error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr3::f` + --> $DIR/private-in-public-warn.rs:65:9 | LL | fn f<T>(arg: T) where T: PrivTr {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits_where::Tr3::f` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:55:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ -error: private trait `traits_where::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:86:5 +error: trait `traits_where::PrivTr` is more private than the item `traits_where::Pub<T>` + --> $DIR/private-in-public-warn.rs:68:5 | LL | impl<T> Pub<T> where T: PrivTr {} - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ implementation `traits_where::Pub<T>` is reachable at visibility `pub(crate)` + | +note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:55:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +LL | trait PrivTr {} + | ^^^^^^^^^^^^ -error: private trait `generics::PrivTr<generics::Pub>` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:98:5 +error: trait `generics::PrivTr<generics::Pub>` is more private than the item `generics::Tr1` + --> $DIR/private-in-public-warn.rs:79:5 | LL | pub trait Tr1: PrivTr<Pub> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr1` is reachable at visibility `pub(crate)` + | +note: but trait `generics::PrivTr<generics::Pub>` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:76:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +LL | trait PrivTr<T> {} + | ^^^^^^^^^^^^^^^ -error: private type `generics::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:101:5 +error: type `generics::Priv` is more private than the item `generics::Tr2` + --> $DIR/private-in-public-warn.rs:81:5 | LL | pub trait Tr2: PubTr<Priv> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr2` is reachable at visibility `pub(crate)` + | +note: but type `generics::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:74:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +LL | struct Priv<T = u8>(T); + | ^^^^^^^^^^^^^^^^^^^ -error: private type `generics::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:103:5 +error: type `generics::Priv` is more private than the item `generics::Tr3` + --> $DIR/private-in-public-warn.rs:82:5 | LL | pub trait Tr3: PubTr<[Priv; 1]> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr3` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: but type `generics::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:74:5 + | +LL | struct Priv<T = u8>(T); + | ^^^^^^^^^^^^^^^^^^^ -error: private type `generics::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:105:5 +error: type `generics::Priv` is more private than the item `Tr4` + --> $DIR/private-in-public-warn.rs:83:5 | LL | pub trait Tr4: PubTr<Pub<Priv>> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `Tr4` is reachable at visibility `pub(crate)` + | +note: but type `generics::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:74:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +LL | struct Priv<T = u8>(T); + | ^^^^^^^^^^^^^^^^^^^ error[E0446]: private type `impls::Priv` in public interface - --> $DIR/private-in-public-warn.rs:132:9 + --> $DIR/private-in-public-warn.rs:109:9 | LL | struct Priv; | ----------- `impls::Priv` declared as private @@ -237,17 +311,20 @@ LL | struct Priv; LL | type Alias = Priv; | ^^^^^^^^^^ can't leak private type -error: private type `aliases_pub::Priv` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:203:9 +error: type `aliases_pub::Priv` is more private than the item `aliases_pub::<impl Pub2>::f` + --> $DIR/private-in-public-warn.rs:180:9 | LL | pub fn f(arg: Priv) {} - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ associated function `aliases_pub::<impl Pub2>::f` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: but type `aliases_pub::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:153:5 + | +LL | struct Priv; + | ^^^^^^^^^^^ error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:207:9 + --> $DIR/private-in-public-warn.rs:183:9 | LL | struct Priv; | ----------- `aliases_pub::Priv` declared as private @@ -256,7 +333,7 @@ LL | type Check = Priv; | ^^^^^^^^^^ can't leak private type error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:210:9 + --> $DIR/private-in-public-warn.rs:186:9 | LL | struct Priv; | ----------- `aliases_pub::Priv` declared as private @@ -265,7 +342,7 @@ LL | type Check = Priv; | ^^^^^^^^^^ can't leak private type error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:213:9 + --> $DIR/private-in-public-warn.rs:189:9 | LL | struct Priv; | ----------- `aliases_pub::Priv` declared as private @@ -274,7 +351,7 @@ LL | type Check = Priv; | ^^^^^^^^^^ can't leak private type error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:216:9 + --> $DIR/private-in-public-warn.rs:192:9 | LL | struct Priv; | ----------- `aliases_pub::Priv` declared as private @@ -282,35 +359,44 @@ LL | struct Priv; LL | type Check = Priv; | ^^^^^^^^^^ can't leak private type -error: private trait `PrivTr1` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:246:5 +error: trait `PrivTr1` is more private than the item `aliases_priv::Tr1` + --> $DIR/private-in-public-warn.rs:222:5 | LL | pub trait Tr1: PrivUseAliasTr {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr1` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: but trait `PrivTr1` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:208:5 + | +LL | trait PrivTr1<T = u8> { + | ^^^^^^^^^^^^^^^^^^^^^ -error: private trait `PrivTr1<Priv2>` in public interface (error E0445) - --> $DIR/private-in-public-warn.rs:249:5 +error: trait `PrivTr1<Priv2>` is more private than the item `aliases_priv::Tr2` + --> $DIR/private-in-public-warn.rs:224:5 | LL | pub trait Tr2: PrivUseAliasTr<PrivAlias> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr2` is reachable at visibility `pub(crate)` | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: but trait `PrivTr1<Priv2>` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:208:5 + | +LL | trait PrivTr1<T = u8> { + | ^^^^^^^^^^^^^^^^^^^^^ -error: private type `Priv2` in public interface (error E0446) - --> $DIR/private-in-public-warn.rs:249:5 +error: type `Priv2` is more private than the item `aliases_priv::Tr2` + --> $DIR/private-in-public-warn.rs:224:5 | LL | pub trait Tr2: PrivUseAliasTr<PrivAlias> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr2` is reachable at visibility `pub(crate)` + | +note: but type `Priv2` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:206:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +LL | struct Priv2; + | ^^^^^^^^^^^^ warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/private-in-public-warn.rs:50:23 + --> $DIR/private-in-public-warn.rs:41:23 | LL | pub type Alias<T: PrivTr> = T; | ^^^^^^ @@ -323,7 +409,7 @@ LL + pub type Alias<T> = T; | warning: where clauses are not enforced in type aliases - --> $DIR/private-in-public-warn.rs:74:29 + --> $DIR/private-in-public-warn.rs:59:29 | LL | pub type Alias<T> where T: PrivTr = T; | ^^^^^^^^^ diff --git a/tests/ui/privacy/private-in-public.rs b/tests/ui/privacy/private-in-public.rs index dbd1c483f81..f54f9e38faa 100644 --- a/tests/ui/privacy/private-in-public.rs +++ b/tests/ui/privacy/private-in-public.rs @@ -1,3 +1,5 @@ +// check-pass + // Private types and traits are not allowed in public interfaces. // This test also ensures that the checks are performed even inside private modules. @@ -10,16 +12,16 @@ mod types { type Alias; } - pub const C: Priv = Priv; //~ ERROR private type `types::Priv` in public interface - pub static S: Priv = Priv; //~ ERROR private type `types::Priv` in public interface - pub fn f1(arg: Priv) {} //~ ERROR private type `types::Priv` in public interface - pub fn f2() -> Priv { panic!() } //~ ERROR private type `types::Priv` in public interface - pub struct S1(pub Priv); //~ ERROR private type `types::Priv` in public interface - pub struct S2 { pub field: Priv } //~ ERROR private type `types::Priv` in public interface + pub const C: Priv = Priv; //~ WARNING type `types::Priv` is more private than the item `C` + pub static S: Priv = Priv; //~ WARNING type `types::Priv` is more private than the item `S` + pub fn f1(arg: Priv) {} //~ WARNING `types::Priv` is more private than the item `types::f1` + pub fn f2() -> Priv { panic!() } //~ WARNING type `types::Priv` is more private than the item `types::f2` + pub struct S1(pub Priv); //~ WARNING type `types::Priv` is more private than the item `types::S1::0` + pub struct S2 { pub field: Priv } //~ WARNING `types::Priv` is more private than the item `S2::field` impl Pub { - pub const C: Priv = Priv; //~ ERROR private type `types::Priv` in public interface - pub fn f1(arg: Priv) {} //~ ERROR private type `types::Priv` in public interface - pub fn f2() -> Priv { panic!() } //~ ERROR private type `types::Priv` in public interface + pub const C: Priv = Priv; //~ WARNING type `types::Priv` is more private than the item `types::Pub::C` + pub fn f1(arg: Priv) {} //~ WARNING type `types::Priv` is more private than the item `types::Pub::f1` + pub fn f2() -> Priv { panic!() } //~ WARNING type `types::Priv` is more private than the item `types::Pub::f2` } } @@ -28,11 +30,11 @@ mod traits { pub struct Pub<T>(T); pub trait PubTr {} - pub enum E<T: PrivTr> { V(T) } //~ ERROR private trait `traits::PrivTr` in public interface - pub fn f<T: PrivTr>(arg: T) {} //~ ERROR private trait `traits::PrivTr` in public interface - pub struct S1<T: PrivTr>(T); //~ ERROR private trait `traits::PrivTr` in public interface - impl<T: PrivTr> Pub<T> { //~ ERROR private trait `traits::PrivTr` in public interface - pub fn f<U: PrivTr>(arg: U) {} //~ ERROR private trait `traits::PrivTr` in public interface + pub enum E<T: PrivTr> { V(T) } //~ WARNING trait `traits::PrivTr` is more private than the item `traits::E` + pub fn f<T: PrivTr>(arg: T) {} //~ WARNING trait `traits::PrivTr` is more private than the item `traits::f` + pub struct S1<T: PrivTr>(T); //~ WARNING trait `traits::PrivTr` is more private than the item `traits::S1` + impl<T: PrivTr> Pub<T> { //~ WARNING trait `traits::PrivTr` is more private than the item `traits::Pub<T>` + pub fn f<U: PrivTr>(arg: U) {} //~ WARNING trait `traits::PrivTr` is more private than the item `traits::Pub::<T>::f` } } @@ -42,15 +44,15 @@ mod traits_where { pub trait PubTr {} pub enum E<T> where T: PrivTr { V(T) } - //~^ ERROR private trait `traits_where::PrivTr` in public interface + //~^ WARNING trait `traits_where::PrivTr` is more private than the item `traits_where::E` pub fn f<T>(arg: T) where T: PrivTr {} - //~^ ERROR private trait `traits_where::PrivTr` in public interface + //~^ WARNING trait `traits_where::PrivTr` is more private than the item `traits_where::f` pub struct S1<T>(T) where T: PrivTr; - //~^ ERROR private trait `traits_where::PrivTr` in public interface + //~^ WARNING trait `traits_where::PrivTr` is more private than the item `traits_where::S1` impl<T> Pub<T> where T: PrivTr { - //~^ ERROR private trait `traits_where::PrivTr` in public interface + //~^ WARNING trait `traits_where::PrivTr` is more private than the item `traits_where::Pub<T>` pub fn f<U>(arg: U) where U: PrivTr {} - //~^ ERROR private trait `traits_where::PrivTr` in public interface + //~^ WARNING trait `traits_where::PrivTr` is more private than the item `traits_where::Pub::<T>::f` } } @@ -60,10 +62,10 @@ mod generics { trait PrivTr<T> {} pub trait PubTr<T> {} - pub fn f1(arg: [Priv; 1]) {} //~ ERROR private type `generics::Priv` in public interface - pub fn f2(arg: Pub<Priv>) {} //~ ERROR private type `generics::Priv` in public interface + pub fn f1(arg: [Priv; 1]) {} //~ WARNING type `generics::Priv` is more private than the item `generics::f1` + pub fn f2(arg: Pub<Priv>) {} //~ WARNING type `generics::Priv` is more private than the item `generics::f2` pub fn f3(arg: Priv<Pub>) {} - //~^ ERROR private type `generics::Priv<generics::Pub>` in public interface + //~^ WARNING type `generics::Priv<generics::Pub>` is more private than the item `generics::f3` } mod impls { @@ -77,7 +79,7 @@ mod impls { } impl Pub { - pub fn f(arg: Priv) {} //~ ERROR private type `impls::Priv` in public interface + pub fn f(arg: Priv) {} //~ WARNING type `impls::Priv` is more private than the item `impls::Pub::f` } } @@ -102,11 +104,11 @@ mod aliases_pub { // This should be OK, but associated type aliases are not substituted yet pub fn f3(arg: <Priv as PrivTr>::Assoc) {} - //~^ ERROR private trait `aliases_pub::PrivTr` in public interface - //~| ERROR private type `aliases_pub::Priv` in public interface + //~^ WARNING trait `aliases_pub::PrivTr` is more private than the item `aliases_pub::f3` + //~| WARNING type `aliases_pub::Priv` is more private than the item `aliases_pub::f3` impl PrivUseAlias { - pub fn f(arg: Priv) {} //~ ERROR private type `aliases_pub::Priv` in public interface + pub fn f(arg: Priv) {} } } @@ -128,11 +130,11 @@ mod aliases_priv { } impl PrivTr for Priv {} - pub fn f1(arg: PrivUseAlias) {} //~ ERROR private type `Priv1` in public interface - pub fn f2(arg: PrivAlias) {} //~ ERROR private type `Priv2` in public interface + pub fn f1(arg: PrivUseAlias) {} //~ WARNING type `Priv1` is more private than the item `aliases_priv::f1` + pub fn f2(arg: PrivAlias) {} //~ WARNING type `Priv2` is more private than the item `aliases_priv::f2` pub fn f3(arg: <Priv as PrivTr>::Assoc) {} - //~^ ERROR private trait `aliases_priv::PrivTr` in public interface - //~| ERROR private type `aliases_priv::Priv` in public interface + //~^ WARNING trait `aliases_priv::PrivTr` is more private than the item `aliases_priv::f3` + //~| WARNING type `aliases_priv::Priv` is more private than the item `aliases_priv::f3` } mod aliases_params { @@ -141,8 +143,8 @@ mod aliases_params { type Result<T> = ::std::result::Result<T, Priv>; pub fn f2(arg: PrivAliasGeneric) {} - //~^ ERROR private type `aliases_params::Priv` in public interface - pub fn f3(arg: Result<u8>) {} //~ ERROR private type `aliases_params::Priv` in public interface + //~^ WARNING type `aliases_params::Priv` is more private than the item `aliases_params::f2` + pub fn f3(arg: Result<u8>) {} //~ WARNING type `aliases_params::Priv` is more private than the item `aliases_params::f3` } fn main() {} diff --git a/tests/ui/privacy/private-in-public.stderr b/tests/ui/privacy/private-in-public.stderr index 887eebf53ef..d8f9fd00716 100644 --- a/tests/ui/privacy/private-in-public.stderr +++ b/tests/ui/privacy/private-in-public.stderr @@ -1,292 +1,376 @@ -error[E0446]: private type `types::Priv` in public interface - --> $DIR/private-in-public.rs:13:5 +warning: type `types::Priv` is more private than the item `C` + --> $DIR/private-in-public.rs:15:5 | -LL | struct Priv; - | ----------- `types::Priv` declared as private -... LL | pub const C: Priv = Priv; - | ^^^^^^^^^^^^^^^^^ can't leak private type - -error[E0446]: private type `types::Priv` in public interface - --> $DIR/private-in-public.rs:14:5 + | ^^^^^^^^^^^^^^^^^ constant `C` is reachable at visibility `pub(crate)` | -LL | struct Priv; - | ----------- `types::Priv` declared as private -... -LL | pub static S: Priv = Priv; - | ^^^^^^^^^^^^^^^^^^ can't leak private type - -error[E0446]: private type `types::Priv` in public interface - --> $DIR/private-in-public.rs:15:5 +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:9:5 | LL | struct Priv; - | ----------- `types::Priv` declared as private -... -LL | pub fn f1(arg: Priv) {} - | ^^^^^^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^ + = note: `#[warn(private_interfaces)]` on by default -error[E0446]: private type `types::Priv` in public interface +warning: type `types::Priv` is more private than the item `S` --> $DIR/private-in-public.rs:16:5 | +LL | pub static S: Priv = Priv; + | ^^^^^^^^^^^^^^^^^^ static `S` is reachable at visibility `pub(crate)` + | +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:9:5 + | LL | struct Priv; - | ----------- `types::Priv` declared as private -... -LL | pub fn f2() -> Priv { panic!() } - | ^^^^^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^ -error[E0446]: private type `types::Priv` in public interface - --> $DIR/private-in-public.rs:17:19 +warning: type `types::Priv` is more private than the item `types::f1` + --> $DIR/private-in-public.rs:17:5 + | +LL | pub fn f1(arg: Priv) {} + | ^^^^^^^^^^^^^^^^^^^^ function `types::f1` is reachable at visibility `pub(crate)` + | +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:9:5 | LL | struct Priv; - | ----------- `types::Priv` declared as private -... -LL | pub struct S1(pub Priv); - | ^^^^^^^^ can't leak private type + | ^^^^^^^^^^^ -error[E0446]: private type `types::Priv` in public interface - --> $DIR/private-in-public.rs:18:21 +warning: type `types::Priv` is more private than the item `types::f2` + --> $DIR/private-in-public.rs:18:5 + | +LL | pub fn f2() -> Priv { panic!() } + | ^^^^^^^^^^^^^^^^^^^ function `types::f2` is reachable at visibility `pub(crate)` + | +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:9:5 | LL | struct Priv; - | ----------- `types::Priv` declared as private -... -LL | pub struct S2 { pub field: Priv } - | ^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^ -error[E0446]: private type `types::Priv` in public interface - --> $DIR/private-in-public.rs:20:9 +warning: type `types::Priv` is more private than the item `types::S1::0` + --> $DIR/private-in-public.rs:19:19 + | +LL | pub struct S1(pub Priv); + | ^^^^^^^^ field `types::S1::0` is reachable at visibility `pub(crate)` + | +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:9:5 | LL | struct Priv; - | ----------- `types::Priv` declared as private -... -LL | pub const C: Priv = Priv; - | ^^^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^ -error[E0446]: private type `types::Priv` in public interface - --> $DIR/private-in-public.rs:21:9 +warning: type `types::Priv` is more private than the item `S2::field` + --> $DIR/private-in-public.rs:20:21 + | +LL | pub struct S2 { pub field: Priv } + | ^^^^^^^^^^^^^^^ field `S2::field` is reachable at visibility `pub(crate)` + | +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:9:5 | LL | struct Priv; - | ----------- `types::Priv` declared as private -... -LL | pub fn f1(arg: Priv) {} - | ^^^^^^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^ -error[E0446]: private type `types::Priv` in public interface +warning: type `types::Priv` is more private than the item `types::Pub::C` --> $DIR/private-in-public.rs:22:9 | +LL | pub const C: Priv = Priv; + | ^^^^^^^^^^^^^^^^^ associated constant `types::Pub::C` is reachable at visibility `pub(crate)` + | +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:9:5 + | LL | struct Priv; - | ----------- `types::Priv` declared as private -... -LL | pub fn f2() -> Priv { panic!() } - | ^^^^^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^ -error[E0445]: private trait `traits::PrivTr` in public interface - --> $DIR/private-in-public.rs:31:5 +warning: type `types::Priv` is more private than the item `types::Pub::f1` + --> $DIR/private-in-public.rs:23:9 | -LL | trait PrivTr {} - | ------------ `traits::PrivTr` declared as private -... -LL | pub enum E<T: PrivTr> { V(T) } - | ^^^^^^^^^^^^^^^^^^^^^ can't leak private trait +LL | pub fn f1(arg: Priv) {} + | ^^^^^^^^^^^^^^^^^^^^ associated function `types::Pub::f1` is reachable at visibility `pub(crate)` + | +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:9:5 + | +LL | struct Priv; + | ^^^^^^^^^^^ -error[E0445]: private trait `traits::PrivTr` in public interface - --> $DIR/private-in-public.rs:32:5 +warning: type `types::Priv` is more private than the item `types::Pub::f2` + --> $DIR/private-in-public.rs:24:9 | -LL | trait PrivTr {} - | ------------ `traits::PrivTr` declared as private -... -LL | pub fn f<T: PrivTr>(arg: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait +LL | pub fn f2() -> Priv { panic!() } + | ^^^^^^^^^^^^^^^^^^^ associated function `types::Pub::f2` is reachable at visibility `pub(crate)` + | +note: but type `types::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:9:5 + | +LL | struct Priv; + | ^^^^^^^^^^^ -error[E0445]: private trait `traits::PrivTr` in public interface +warning: trait `traits::PrivTr` is more private than the item `traits::E` --> $DIR/private-in-public.rs:33:5 | +LL | pub enum E<T: PrivTr> { V(T) } + | ^^^^^^^^^^^^^^^^^^^^^ enum `traits::E` is reachable at visibility `pub(crate)` + | +note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:29:5 + | LL | trait PrivTr {} - | ------------ `traits::PrivTr` declared as private -... -LL | pub struct S1<T: PrivTr>(T); - | ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait + | ^^^^^^^^^^^^ + = note: `#[warn(private_bounds)]` on by default -error[E0445]: private trait `traits::PrivTr` in public interface +warning: trait `traits::PrivTr` is more private than the item `traits::f` --> $DIR/private-in-public.rs:34:5 | +LL | pub fn f<T: PrivTr>(arg: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `traits::f` is reachable at visibility `pub(crate)` + | +note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:29:5 + | LL | trait PrivTr {} - | ------------ `traits::PrivTr` declared as private -... -LL | impl<T: PrivTr> Pub<T> { - | ^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait + | ^^^^^^^^^^^^ -error[E0445]: private trait `traits::PrivTr` in public interface - --> $DIR/private-in-public.rs:35:9 +warning: trait `traits::PrivTr` is more private than the item `traits::S1` + --> $DIR/private-in-public.rs:35:5 + | +LL | pub struct S1<T: PrivTr>(T); + | ^^^^^^^^^^^^^^^^^^^^^^^^ struct `traits::S1` is reachable at visibility `pub(crate)` + | +note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:29:5 | LL | trait PrivTr {} - | ------------ `traits::PrivTr` declared as private -... -LL | pub fn f<U: PrivTr>(arg: U) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait + | ^^^^^^^^^^^^ -error[E0445]: private trait `traits_where::PrivTr` in public interface - --> $DIR/private-in-public.rs:44:5 +warning: trait `traits::PrivTr` is more private than the item `traits::Pub<T>` + --> $DIR/private-in-public.rs:36:5 + | +LL | impl<T: PrivTr> Pub<T> { + | ^^^^^^^^^^^^^^^^^^^^^^ implementation `traits::Pub<T>` is reachable at visibility `pub(crate)` + | +note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:29:5 | LL | trait PrivTr {} - | ------------ `traits_where::PrivTr` declared as private -... -LL | pub enum E<T> where T: PrivTr { V(T) } - | ^^^^^^^^^^^^^ can't leak private trait + | ^^^^^^^^^^^^ -error[E0445]: private trait `traits_where::PrivTr` in public interface +warning: trait `traits::PrivTr` is more private than the item `traits::Pub::<T>::f` + --> $DIR/private-in-public.rs:37:9 + | +LL | pub fn f<U: PrivTr>(arg: U) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits::Pub::<T>::f` is reachable at visibility `pub(crate)` + | +note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:29:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ + +warning: trait `traits_where::PrivTr` is more private than the item `traits_where::E` --> $DIR/private-in-public.rs:46:5 | +LL | pub enum E<T> where T: PrivTr { V(T) } + | ^^^^^^^^^^^^^ enum `traits_where::E` is reachable at visibility `pub(crate)` + | +note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:42:5 + | LL | trait PrivTr {} - | ------------ `traits_where::PrivTr` declared as private -... -LL | pub fn f<T>(arg: T) where T: PrivTr {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait + | ^^^^^^^^^^^^ -error[E0445]: private trait `traits_where::PrivTr` in public interface +warning: trait `traits_where::PrivTr` is more private than the item `traits_where::f` --> $DIR/private-in-public.rs:48:5 | +LL | pub fn f<T>(arg: T) where T: PrivTr {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `traits_where::f` is reachable at visibility `pub(crate)` + | +note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:42:5 + | LL | trait PrivTr {} - | ------------ `traits_where::PrivTr` declared as private -... -LL | pub struct S1<T>(T) where T: PrivTr; - | ^^^^^^^^^^^^^^^^ can't leak private trait + | ^^^^^^^^^^^^ -error[E0445]: private trait `traits_where::PrivTr` in public interface +warning: trait `traits_where::PrivTr` is more private than the item `traits_where::S1` --> $DIR/private-in-public.rs:50:5 | +LL | pub struct S1<T>(T) where T: PrivTr; + | ^^^^^^^^^^^^^^^^ struct `traits_where::S1` is reachable at visibility `pub(crate)` + | +note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:42:5 + | LL | trait PrivTr {} - | ------------ `traits_where::PrivTr` declared as private -... -LL | impl<T> Pub<T> where T: PrivTr { - | ^^^^^^^^^^^^^^ can't leak private trait + | ^^^^^^^^^^^^ -error[E0445]: private trait `traits_where::PrivTr` in public interface - --> $DIR/private-in-public.rs:52:9 +warning: trait `traits_where::PrivTr` is more private than the item `traits_where::Pub<T>` + --> $DIR/private-in-public.rs:52:5 + | +LL | impl<T> Pub<T> where T: PrivTr { + | ^^^^^^^^^^^^^^ implementation `traits_where::Pub<T>` is reachable at visibility `pub(crate)` + | +note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:42:5 | LL | trait PrivTr {} - | ------------ `traits_where::PrivTr` declared as private -... + | ^^^^^^^^^^^^ + +warning: trait `traits_where::PrivTr` is more private than the item `traits_where::Pub::<T>::f` + --> $DIR/private-in-public.rs:54:9 + | LL | pub fn f<U>(arg: U) where U: PrivTr {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits_where::Pub::<T>::f` is reachable at visibility `pub(crate)` + | +note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:42:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ -error[E0446]: private type `generics::Priv` in public interface - --> $DIR/private-in-public.rs:63:5 +warning: type `generics::Priv` is more private than the item `generics::f1` + --> $DIR/private-in-public.rs:65:5 | -LL | struct Priv<T = u8>(T); - | ------------------- `generics::Priv` declared as private -... LL | pub fn f1(arg: [Priv; 1]) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type - -error[E0446]: private type `generics::Priv` in public interface - --> $DIR/private-in-public.rs:64:5 + | ^^^^^^^^^^^^^^^^^^^^^^^^^ function `generics::f1` is reachable at visibility `pub(crate)` + | +note: but type `generics::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:60:5 | LL | struct Priv<T = u8>(T); - | ------------------- `generics::Priv` declared as private -... -LL | pub fn f2(arg: Pub<Priv>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^^^^^^^^^ -error[E0446]: private type `generics::Priv<generics::Pub>` in public interface - --> $DIR/private-in-public.rs:65:5 +warning: type `generics::Priv` is more private than the item `generics::f2` + --> $DIR/private-in-public.rs:66:5 + | +LL | pub fn f2(arg: Pub<Priv>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ function `generics::f2` is reachable at visibility `pub(crate)` + | +note: but type `generics::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:60:5 | LL | struct Priv<T = u8>(T); - | ------------------- `generics::Priv<generics::Pub>` declared as private -... + | ^^^^^^^^^^^^^^^^^^^ + +warning: type `generics::Priv<generics::Pub>` is more private than the item `generics::f3` + --> $DIR/private-in-public.rs:67:5 + | LL | pub fn f3(arg: Priv<Pub>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^^^^^^^^^^^^^^^ function `generics::f3` is reachable at visibility `pub(crate)` + | +note: but type `generics::Priv<generics::Pub>` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:60:5 + | +LL | struct Priv<T = u8>(T); + | ^^^^^^^^^^^^^^^^^^^ -error[E0446]: private type `impls::Priv` in public interface - --> $DIR/private-in-public.rs:80:9 +warning: type `impls::Priv` is more private than the item `impls::Pub::f` + --> $DIR/private-in-public.rs:82:9 | -LL | struct Priv; - | ----------- `impls::Priv` declared as private -... LL | pub fn f(arg: Priv) {} - | ^^^^^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^^^^^^^^^ associated function `impls::Pub::f` is reachable at visibility `pub(crate)` + | +note: but type `impls::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:72:5 + | +LL | struct Priv; + | ^^^^^^^^^^^ -error[E0445]: private trait `aliases_pub::PrivTr` in public interface - --> $DIR/private-in-public.rs:104:5 +warning: trait `aliases_pub::PrivTr` is more private than the item `aliases_pub::f3` + --> $DIR/private-in-public.rs:106:5 | -LL | trait PrivTr { - | ------------ `aliases_pub::PrivTr` declared as private -... LL | pub fn f3(arg: <Priv as PrivTr>::Assoc) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_pub::f3` is reachable at visibility `pub(crate)` + | +note: but trait `aliases_pub::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:100:5 + | +LL | trait PrivTr { + | ^^^^^^^^^^^^ -error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public.rs:104:5 +warning: type `aliases_pub::Priv` is more private than the item `aliases_pub::f3` + --> $DIR/private-in-public.rs:106:5 | -LL | struct Priv; - | ----------- `aliases_pub::Priv` declared as private -... LL | pub fn f3(arg: <Priv as PrivTr>::Assoc) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type - -error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public.rs:109:9 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_pub::f3` is reachable at visibility `pub(crate)` + | +note: but type `aliases_pub::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:87:5 | LL | struct Priv; - | ----------- `aliases_pub::Priv` declared as private -... -LL | pub fn f(arg: Priv) {} - | ^^^^^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^ -error[E0446]: private type `Priv1` in public interface - --> $DIR/private-in-public.rs:131:5 +warning: type `Priv1` is more private than the item `aliases_priv::f1` + --> $DIR/private-in-public.rs:133:5 | -LL | struct Priv1; - | ------------ `Priv1` declared as private -... LL | pub fn f1(arg: PrivUseAlias) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_priv::f1` is reachable at visibility `pub(crate)` + | +note: but type `Priv1` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:118:5 + | +LL | struct Priv1; + | ^^^^^^^^^^^^ -error[E0446]: private type `Priv2` in public interface - --> $DIR/private-in-public.rs:132:5 +warning: type `Priv2` is more private than the item `aliases_priv::f2` + --> $DIR/private-in-public.rs:134:5 | -LL | struct Priv2; - | ------------ `Priv2` declared as private -... LL | pub fn f2(arg: PrivAlias) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_priv::f2` is reachable at visibility `pub(crate)` + | +note: but type `Priv2` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:119:5 + | +LL | struct Priv2; + | ^^^^^^^^^^^^ -error[E0445]: private trait `aliases_priv::PrivTr` in public interface - --> $DIR/private-in-public.rs:133:5 +warning: trait `aliases_priv::PrivTr` is more private than the item `aliases_priv::f3` + --> $DIR/private-in-public.rs:135:5 | -LL | trait PrivTr { - | ------------ `aliases_priv::PrivTr` declared as private -... LL | pub fn f3(arg: <Priv as PrivTr>::Assoc) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_priv::f3` is reachable at visibility `pub(crate)` + | +note: but trait `aliases_priv::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:128:5 + | +LL | trait PrivTr { + | ^^^^^^^^^^^^ -error[E0446]: private type `aliases_priv::Priv` in public interface - --> $DIR/private-in-public.rs:133:5 +warning: type `aliases_priv::Priv` is more private than the item `aliases_priv::f3` + --> $DIR/private-in-public.rs:135:5 | -LL | struct Priv; - | ----------- `aliases_priv::Priv` declared as private -... LL | pub fn f3(arg: <Priv as PrivTr>::Assoc) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type - -error[E0446]: private type `aliases_params::Priv` in public interface - --> $DIR/private-in-public.rs:143:5 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_priv::f3` is reachable at visibility `pub(crate)` + | +note: but type `aliases_priv::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:116:5 | LL | struct Priv; - | ----------- `aliases_params::Priv` declared as private -... -LL | pub fn f2(arg: PrivAliasGeneric) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^ -error[E0446]: private type `aliases_params::Priv` in public interface +warning: type `aliases_params::Priv` is more private than the item `aliases_params::f2` --> $DIR/private-in-public.rs:145:5 | +LL | pub fn f2(arg: PrivAliasGeneric) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_params::f2` is reachable at visibility `pub(crate)` + | +note: but type `aliases_params::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:141:5 + | LL | struct Priv; - | ----------- `aliases_params::Priv` declared as private -... + | ^^^^^^^^^^^ + +warning: type `aliases_params::Priv` is more private than the item `aliases_params::f3` + --> $DIR/private-in-public.rs:147:5 + | LL | pub fn f3(arg: Result<u8>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_params::f3` is reachable at visibility `pub(crate)` + | +note: but type `aliases_params::Priv` is only usable at visibility `pub(self)` + --> $DIR/private-in-public.rs:141:5 + | +LL | struct Priv; + | ^^^^^^^^^^^ -error: aborting due to 32 previous errors +warning: 31 warnings emitted -Some errors have detailed explanations: E0445, E0446. -For more information about an error, try `rustc --explain E0445`. diff --git a/tests/ui/privacy/private-inferred-type-2.rs b/tests/ui/privacy/private-inferred-type-2.rs index 15b263b3814..1c4c52bea28 100644 --- a/tests/ui/privacy/private-inferred-type-2.rs +++ b/tests/ui/privacy/private-inferred-type-2.rs @@ -1,4 +1,5 @@ // aux-build:private-inferred-type.rs +#![allow(private_interfaces)] extern crate private_inferred_type as ext; diff --git a/tests/ui/privacy/private-inferred-type-2.stderr b/tests/ui/privacy/private-inferred-type-2.stderr index 3a0fc03b4d5..8a905f5d88a 100644 --- a/tests/ui/privacy/private-inferred-type-2.stderr +++ b/tests/ui/privacy/private-inferred-type-2.stderr @@ -1,17 +1,17 @@ error: type `Priv` is private - --> $DIR/private-inferred-type-2.rs:16:5 + --> $DIR/private-inferred-type-2.rs:17:5 | LL | m::Pub::get_priv; | ^^^^^^^^^^^^^^^^ private type error: type `Priv` is private - --> $DIR/private-inferred-type-2.rs:17:5 + --> $DIR/private-inferred-type-2.rs:18:5 | LL | m::Pub::static_method; | ^^^^^^^^^^^^^^^^^^^^^ private type error: type `ext::Priv` is private - --> $DIR/private-inferred-type-2.rs:18:5 + --> $DIR/private-inferred-type-2.rs:19:5 | LL | ext::Pub::static_method; | ^^^^^^^^^^^^^^^^^^^^^^^ private type diff --git a/tests/ui/privacy/private-inferred-type.rs b/tests/ui/privacy/private-inferred-type.rs index e8743dd968f..8c07226fe0e 100644 --- a/tests/ui/privacy/private-inferred-type.rs +++ b/tests/ui/privacy/private-inferred-type.rs @@ -1,5 +1,5 @@ #![feature(decl_macro)] -#![allow(private_in_public)] +#![allow(private_interfaces)] mod m { fn priv_fn() {} diff --git a/tests/ui/privacy/private-type-in-interface.rs b/tests/ui/privacy/private-type-in-interface.rs index 7fbdbaf5f31..39e0bf23cac 100644 --- a/tests/ui/privacy/private-type-in-interface.rs +++ b/tests/ui/privacy/private-type-in-interface.rs @@ -1,6 +1,7 @@ // aux-build:private-inferred-type.rs #![allow(warnings)] +#![allow(private_interfaces)] extern crate private_inferred_type as ext; diff --git a/tests/ui/privacy/private-type-in-interface.stderr b/tests/ui/privacy/private-type-in-interface.stderr index 4e87caa3415..03225d84fdb 100644 --- a/tests/ui/privacy/private-type-in-interface.stderr +++ b/tests/ui/privacy/private-type-in-interface.stderr @@ -1,53 +1,53 @@ error: type `Priv` is private - --> $DIR/private-type-in-interface.rs:15:9 + --> $DIR/private-type-in-interface.rs:16:9 | LL | fn f(_: m::Alias) {} | ^^^^^^^^ private type error: type `Priv` is private - --> $DIR/private-type-in-interface.rs:15:6 + --> $DIR/private-type-in-interface.rs:16:6 | LL | fn f(_: m::Alias) {} | ^ private type error: type `ext::Priv` is private - --> $DIR/private-type-in-interface.rs:17:13 + --> $DIR/private-type-in-interface.rs:18:13 | LL | fn f_ext(_: ext::Alias) {} | ^^^^^^^^^^ private type error: type `ext::Priv` is private - --> $DIR/private-type-in-interface.rs:17:10 + --> $DIR/private-type-in-interface.rs:18:10 | LL | fn f_ext(_: ext::Alias) {} | ^ private type error: type `Priv` is private - --> $DIR/private-type-in-interface.rs:21:6 + --> $DIR/private-type-in-interface.rs:22:6 | LL | impl m::Alias {} | ^^^^^^^^ private type error: type `ext::Priv` is private - --> $DIR/private-type-in-interface.rs:22:14 + --> $DIR/private-type-in-interface.rs:23:14 | LL | impl Tr1 for ext::Alias {} | ^^^^^^^^^^ private type error: type `Priv` is private - --> $DIR/private-type-in-interface.rs:23:10 + --> $DIR/private-type-in-interface.rs:24:10 | LL | type A = <m::Alias as m::Trait>::X; | ^^^^^^^^^^^^^^^^^^^^^^^^^ private type error: type `Priv` is private - --> $DIR/private-type-in-interface.rs:27:11 + --> $DIR/private-type-in-interface.rs:28:11 | LL | fn g() -> impl Tr2<m::Alias> { 0 } | ^^^^^^^^^^^^^^^^^^ private type error: type `ext::Priv` is private - --> $DIR/private-type-in-interface.rs:28:15 + --> $DIR/private-type-in-interface.rs:29:15 | LL | fn g_ext() -> impl Tr2<ext::Alias> { 0 } | ^^^^^^^^^^^^^^^^^^^^ private type diff --git a/tests/ui/privacy/restricted/private-in-public.rs b/tests/ui/privacy/restricted/private-in-public.rs index 1e3dbdf73b9..80a7e6ad0a7 100644 --- a/tests/ui/privacy/restricted/private-in-public.rs +++ b/tests/ui/privacy/restricted/private-in-public.rs @@ -1,10 +1,11 @@ +// check-pass mod foo { struct Priv; mod bar { use foo::Priv; pub(super) fn f(_: Priv) {} - pub(crate) fn g(_: Priv) {} //~ ERROR E0446 - pub(crate) fn h(_: Priv) {} //~ ERROR E0446 + pub(crate) fn g(_: Priv) {} + pub(crate) fn h(_: Priv) {} } } diff --git a/tests/ui/privacy/restricted/private-in-public.stderr b/tests/ui/privacy/restricted/private-in-public.stderr deleted file mode 100644 index 65d996f0f07..00000000000 --- a/tests/ui/privacy/restricted/private-in-public.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0446]: private type `Priv` in public interface - --> $DIR/private-in-public.rs:6:9 - | -LL | struct Priv; - | ----------- `Priv` declared as private -... -LL | pub(crate) fn g(_: Priv) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type - -error[E0446]: private type `Priv` in public interface - --> $DIR/private-in-public.rs:7:9 - | -LL | struct Priv; - | ----------- `Priv` declared as private -... -LL | pub(crate) fn h(_: Priv) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/privacy/unnameable_types.rs b/tests/ui/privacy/unnameable_types.rs index 46e24915259..e35aaec5b3b 100644 --- a/tests/ui/privacy/unnameable_types.rs +++ b/tests/ui/privacy/unnameable_types.rs @@ -1,5 +1,4 @@ #![feature(type_privacy_lints)] -#![allow(private_in_public)] #![deny(unnameable_types)] mod m { diff --git a/tests/ui/privacy/unnameable_types.stderr b/tests/ui/privacy/unnameable_types.stderr index 90412752575..d68a11c9728 100644 --- a/tests/ui/privacy/unnameable_types.stderr +++ b/tests/ui/privacy/unnameable_types.stderr @@ -1,23 +1,23 @@ error: struct `PubStruct` is reachable but cannot be named - --> $DIR/unnameable_types.rs:6:5 + --> $DIR/unnameable_types.rs:5:5 | LL | pub struct PubStruct(pub i32); | ^^^^^^^^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)` | note: the lint level is defined here - --> $DIR/unnameable_types.rs:3:9 + --> $DIR/unnameable_types.rs:2:9 | LL | #![deny(unnameable_types)] | ^^^^^^^^^^^^^^^^ error: enum `PubE` is reachable but cannot be named - --> $DIR/unnameable_types.rs:8:5 + --> $DIR/unnameable_types.rs:7:5 | LL | pub enum PubE { | ^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)` error: trait `PubTr` is reachable but cannot be named - --> $DIR/unnameable_types.rs:12:5 + --> $DIR/unnameable_types.rs:11:5 | LL | pub trait PubTr { | ^^^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)` diff --git a/tests/ui/privacy/where-priv-type.rs b/tests/ui/privacy/where-priv-type.rs index 2e0a6b3e72c..cd9cce7ec3e 100644 --- a/tests/ui/privacy/where-priv-type.rs +++ b/tests/ui/privacy/where-priv-type.rs @@ -3,14 +3,7 @@ #![crate_type = "lib"] #![feature(generic_const_exprs)] -#![feature(type_privacy_lints)] #![allow(incomplete_features)] -#![warn(private_bounds)] -#![warn(private_interfaces)] - -// In this test both old and new private-in-public diagnostic were emitted. -// Old diagnostic will be deleted soon. -// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. struct PrivTy; trait PrivTr {} @@ -23,42 +16,33 @@ impl PubTrWithAssocTy for PrivTy { type AssocTy = PrivTy; } pub struct S -//~^ WARNING private type `PrivTy` in public interface -//~| WARNING hard error -//~| WARNING type `PrivTy` is more private than the item `S` +//~^ WARNING type `PrivTy` is more private than the item `S` where PrivTy: {} pub enum E -//~^ WARNING private type `PrivTy` in public interface -//~| WARNING hard error -//~| WARNING type `PrivTy` is more private than the item `E` +//~^ WARNING type `PrivTy` is more private than the item `E` where PrivTy: {} pub fn f() -//~^ WARNING private type `PrivTy` in public interface -//~| WARNING hard error -//~| WARNING type `PrivTy` is more private than the item `f` +//~^ WARNING type `PrivTy` is more private than the item `f` where PrivTy: {} impl S -//~^ ERROR private type `PrivTy` in public interface -//~| WARNING type `PrivTy` is more private than the item `S` +//~^ WARNING type `PrivTy` is more private than the item `S` where PrivTy: { pub fn f() - //~^ WARNING private type `PrivTy` in public interface - //~| WARNING hard error - //~| WARNING type `PrivTy` is more private than the item `S::f` + //~^ WARNING type `PrivTy` is more private than the item `S::f` where PrivTy: {} @@ -90,7 +74,6 @@ where { type AssocTy = Const<{ my_const_fn(U) }>; //~^ ERROR private type - //~| WARNING type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy` fn assoc_fn() -> Self::AssocTy { Const } diff --git a/tests/ui/privacy/where-priv-type.stderr b/tests/ui/privacy/where-priv-type.stderr index d6baf22b3fb..dcc249c6351 100644 --- a/tests/ui/privacy/where-priv-type.stderr +++ b/tests/ui/privacy/where-priv-type.stderr @@ -1,136 +1,72 @@ -warning: private type `PrivTy` in public interface (error E0446) - --> $DIR/where-priv-type.rs:25:1 - | -LL | pub struct S - | ^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> - = note: `#[warn(private_in_public)]` on by default - warning: type `PrivTy` is more private than the item `S` - --> $DIR/where-priv-type.rs:25:1 + --> $DIR/where-priv-type.rs:18:1 | LL | pub struct S | ^^^^^^^^^^^^ struct `S` is reachable at visibility `pub` | note: but type `PrivTy` is only usable at visibility `pub(crate)` - --> $DIR/where-priv-type.rs:15:1 + --> $DIR/where-priv-type.rs:8:1 | LL | struct PrivTy; | ^^^^^^^^^^^^^ -note: the lint level is defined here - --> $DIR/where-priv-type.rs:8:9 - | -LL | #![warn(private_bounds)] - | ^^^^^^^^^^^^^^ - -warning: private type `PrivTy` in public interface (error E0446) - --> $DIR/where-priv-type.rs:34:1 - | -LL | pub enum E - | ^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> + = note: `#[warn(private_bounds)]` on by default warning: type `PrivTy` is more private than the item `E` - --> $DIR/where-priv-type.rs:34:1 + --> $DIR/where-priv-type.rs:25:1 | LL | pub enum E | ^^^^^^^^^^ enum `E` is reachable at visibility `pub` | note: but type `PrivTy` is only usable at visibility `pub(crate)` - --> $DIR/where-priv-type.rs:15:1 + --> $DIR/where-priv-type.rs:8:1 | LL | struct PrivTy; | ^^^^^^^^^^^^^ -warning: private type `PrivTy` in public interface (error E0446) - --> $DIR/where-priv-type.rs:43:1 - | -LL | / pub fn f() -LL | | -LL | | -LL | | -LL | | where -LL | | PrivTy: - | |___________^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> - warning: type `PrivTy` is more private than the item `f` - --> $DIR/where-priv-type.rs:43:1 + --> $DIR/where-priv-type.rs:32:1 | LL | / pub fn f() LL | | -LL | | -LL | | LL | | where LL | | PrivTy: | |___________^ function `f` is reachable at visibility `pub` | note: but type `PrivTy` is only usable at visibility `pub(crate)` - --> $DIR/where-priv-type.rs:15:1 + --> $DIR/where-priv-type.rs:8:1 | LL | struct PrivTy; | ^^^^^^^^^^^^^ -error[E0446]: private type `PrivTy` in public interface - --> $DIR/where-priv-type.rs:52:1 - | -LL | struct PrivTy; - | ------------- `PrivTy` declared as private -... -LL | impl S - | ^^^^^^ can't leak private type - warning: type `PrivTy` is more private than the item `S` - --> $DIR/where-priv-type.rs:52:1 + --> $DIR/where-priv-type.rs:39:1 | LL | impl S | ^^^^^^ implementation `S` is reachable at visibility `pub` | note: but type `PrivTy` is only usable at visibility `pub(crate)` - --> $DIR/where-priv-type.rs:15:1 + --> $DIR/where-priv-type.rs:8:1 | LL | struct PrivTy; | ^^^^^^^^^^^^^ -warning: private type `PrivTy` in public interface (error E0446) - --> $DIR/where-priv-type.rs:58:5 - | -LL | / pub fn f() -LL | | -LL | | -LL | | -LL | | where -LL | | PrivTy: - | |_______________^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> - warning: type `PrivTy` is more private than the item `S::f` - --> $DIR/where-priv-type.rs:58:5 + --> $DIR/where-priv-type.rs:44:5 | LL | / pub fn f() LL | | -LL | | -LL | | LL | | where LL | | PrivTy: | |_______________^ associated function `S::f` is reachable at visibility `pub` | note: but type `PrivTy` is only usable at visibility `pub(crate)` - --> $DIR/where-priv-type.rs:15:1 + --> $DIR/where-priv-type.rs:8:1 | LL | struct PrivTy; | ^^^^^^^^^^^^^ error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface - --> $DIR/where-priv-type.rs:91:5 + --> $DIR/where-priv-type.rs:75:5 | LL | type AssocTy = Const<{ my_const_fn(U) }>; | ^^^^^^^^^^^^ can't leak private type @@ -138,23 +74,6 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>; LL | const fn my_const_fn(val: u8) -> u8 { | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private -warning: type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy` - --> $DIR/where-priv-type.rs:91:5 - | -LL | type AssocTy = Const<{ my_const_fn(U) }>; - | ^^^^^^^^^^^^ associated type `<Const<U> as Trait>::AssocTy` is reachable at visibility `pub` - | -note: but type `fn(u8) -> u8 {my_const_fn}` is only usable at visibility `pub(crate)` - --> $DIR/where-priv-type.rs:99:1 - | -LL | const fn my_const_fn(val: u8) -> u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: the lint level is defined here - --> $DIR/where-priv-type.rs:9:9 - | -LL | #![warn(private_interfaces)] - | ^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors; 10 warnings emitted +error: aborting due to previous error; 5 warnings emitted For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/privacy/where-pub-type-impls-priv-trait.rs b/tests/ui/privacy/where-pub-type-impls-priv-trait.rs index c59fdb7c7a9..d5e797b52b3 100644 --- a/tests/ui/privacy/where-pub-type-impls-priv-trait.rs +++ b/tests/ui/privacy/where-pub-type-impls-priv-trait.rs @@ -1,14 +1,10 @@ +// check-pass + // priv-in-pub lint tests where the private trait bounds a public type #![crate_type = "lib"] #![feature(generic_const_exprs)] -#![feature(type_privacy_lints)] #![allow(incomplete_features)] -#![warn(private_bounds)] - -// In this test both old and new private-in-public diagnostic were emitted. -// Old diagnostic will be deleted soon. -// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. struct PrivTy; trait PrivTr {} @@ -22,38 +18,33 @@ impl PubTrWithAssocTy for PrivTy { type AssocTy = PrivTy; } pub struct S -//~^ ERROR private trait `PrivTr` in public interface -//~| WARNING trait `PrivTr` is more private than the item `S` +//~^ WARNING trait `PrivTr` is more private than the item `S` where PubTy: PrivTr {} pub enum E -//~^ ERROR private trait `PrivTr` in public interface -//~| WARNING trait `PrivTr` is more private than the item `E` +//~^ WARNING trait `PrivTr` is more private than the item `E` where PubTy: PrivTr {} pub fn f() -//~^ ERROR private trait `PrivTr` in public interface -//~| WARNING trait `PrivTr` is more private than the item `f` +//~^ WARNING trait `PrivTr` is more private than the item `f` where PubTy: PrivTr {} impl S -//~^ ERROR private trait `PrivTr` in public interface -//~| WARNING trait `PrivTr` is more private than the item `S` +//~^ WARNING trait `PrivTr` is more private than the item `S` where PubTy: PrivTr { pub fn f() - //~^ ERROR private trait `PrivTr` in public interface - //~| WARNING trait `PrivTr` is more private than the item `S::f` + //~^ WARNING trait `PrivTr` is more private than the item `S::f` where PubTy: PrivTr {} diff --git a/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr b/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr index e2d7ce44692..c476874332c 100644 --- a/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr +++ b/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr @@ -1,129 +1,69 @@ -error[E0445]: private trait `PrivTr` in public interface - --> $DIR/where-pub-type-impls-priv-trait.rs:24:1 - | -LL | trait PrivTr {} - | ------------ `PrivTr` declared as private -... -LL | pub struct S - | ^^^^^^^^^^^^ can't leak private trait - warning: trait `PrivTr` is more private than the item `S` - --> $DIR/where-pub-type-impls-priv-trait.rs:24:1 + --> $DIR/where-pub-type-impls-priv-trait.rs:20:1 | LL | pub struct S | ^^^^^^^^^^^^ struct `S` is reachable at visibility `pub` | note: but trait `PrivTr` is only usable at visibility `pub(crate)` - --> $DIR/where-pub-type-impls-priv-trait.rs:14:1 + --> $DIR/where-pub-type-impls-priv-trait.rs:10:1 | LL | trait PrivTr {} | ^^^^^^^^^^^^ -note: the lint level is defined here - --> $DIR/where-pub-type-impls-priv-trait.rs:7:9 - | -LL | #![warn(private_bounds)] - | ^^^^^^^^^^^^^^ - -error[E0445]: private trait `PrivTr` in public interface - --> $DIR/where-pub-type-impls-priv-trait.rs:32:1 - | -LL | trait PrivTr {} - | ------------ `PrivTr` declared as private -... -LL | pub enum E - | ^^^^^^^^^^ can't leak private trait + = note: `#[warn(private_bounds)]` on by default warning: trait `PrivTr` is more private than the item `E` - --> $DIR/where-pub-type-impls-priv-trait.rs:32:1 + --> $DIR/where-pub-type-impls-priv-trait.rs:27:1 | LL | pub enum E | ^^^^^^^^^^ enum `E` is reachable at visibility `pub` | note: but trait `PrivTr` is only usable at visibility `pub(crate)` - --> $DIR/where-pub-type-impls-priv-trait.rs:14:1 + --> $DIR/where-pub-type-impls-priv-trait.rs:10:1 | LL | trait PrivTr {} | ^^^^^^^^^^^^ -error[E0445]: private trait `PrivTr` in public interface - --> $DIR/where-pub-type-impls-priv-trait.rs:40:1 - | -LL | trait PrivTr {} - | ------------ `PrivTr` declared as private -... -LL | / pub fn f() -LL | | -LL | | -LL | | where -LL | | PubTy: PrivTr - | |_________________^ can't leak private trait - warning: trait `PrivTr` is more private than the item `f` - --> $DIR/where-pub-type-impls-priv-trait.rs:40:1 + --> $DIR/where-pub-type-impls-priv-trait.rs:34:1 | LL | / pub fn f() LL | | -LL | | LL | | where LL | | PubTy: PrivTr | |_________________^ function `f` is reachable at visibility `pub` | note: but trait `PrivTr` is only usable at visibility `pub(crate)` - --> $DIR/where-pub-type-impls-priv-trait.rs:14:1 + --> $DIR/where-pub-type-impls-priv-trait.rs:10:1 | LL | trait PrivTr {} | ^^^^^^^^^^^^ -error[E0445]: private trait `PrivTr` in public interface - --> $DIR/where-pub-type-impls-priv-trait.rs:48:1 - | -LL | trait PrivTr {} - | ------------ `PrivTr` declared as private -... -LL | impl S - | ^^^^^^ can't leak private trait - warning: trait `PrivTr` is more private than the item `S` - --> $DIR/where-pub-type-impls-priv-trait.rs:48:1 + --> $DIR/where-pub-type-impls-priv-trait.rs:41:1 | LL | impl S | ^^^^^^ implementation `S` is reachable at visibility `pub` | note: but trait `PrivTr` is only usable at visibility `pub(crate)` - --> $DIR/where-pub-type-impls-priv-trait.rs:14:1 + --> $DIR/where-pub-type-impls-priv-trait.rs:10:1 | LL | trait PrivTr {} | ^^^^^^^^^^^^ -error[E0445]: private trait `PrivTr` in public interface - --> $DIR/where-pub-type-impls-priv-trait.rs:54:5 - | -LL | trait PrivTr {} - | ------------ `PrivTr` declared as private -... -LL | / pub fn f() -LL | | -LL | | -LL | | where -LL | | PubTy: PrivTr - | |_____________________^ can't leak private trait - warning: trait `PrivTr` is more private than the item `S::f` - --> $DIR/where-pub-type-impls-priv-trait.rs:54:5 + --> $DIR/where-pub-type-impls-priv-trait.rs:46:5 | LL | / pub fn f() LL | | -LL | | LL | | where LL | | PubTy: PrivTr | |_____________________^ associated function `S::f` is reachable at visibility `pub` | note: but trait `PrivTr` is only usable at visibility `pub(crate)` - --> $DIR/where-pub-type-impls-priv-trait.rs:14:1 + --> $DIR/where-pub-type-impls-priv-trait.rs:10:1 | LL | trait PrivTr {} | ^^^^^^^^^^^^ -error: aborting due to 5 previous errors; 5 warnings emitted +warning: 5 warnings emitted -For more information about this error, try `rustc --explain E0445`. diff --git a/tests/ui/proc-macro/allowed-signatures.rs b/tests/ui/proc-macro/allowed-signatures.rs index 86850876112..ce327901b1a 100644 --- a/tests/ui/proc-macro/allowed-signatures.rs +++ b/tests/ui/proc-macro/allowed-signatures.rs @@ -3,7 +3,7 @@ // no-prefer-dynamic #![crate_type = "proc-macro"] -#![allow(private_in_public)] +#![allow(private_interfaces)] extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs index cdeea6224b2..7930964c83b 100644 --- a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs +++ b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs @@ -1,44 +1,24 @@ -#![feature(type_privacy_lints)] -#![allow(non_camel_case_types)] // genus is always capitalized -#![warn(private_interfaces)] -//~^ NOTE the lint level is defined here +// check-pass -// In this test both old and new private-in-public diagnostic were emitted. -// Old diagnostic will be deleted soon. -// See https://rust-lang.github.io/rfcs/2145-type-privacy.html. +#![allow(non_camel_case_types)] // genus is always capitalized pub(crate) struct Snail; -//~^ NOTE `Snail` declared as private -//~| NOTE but type `Snail` is only usable at visibility `pub(crate)` mod sea { pub(super) struct Turtle; - //~^ NOTE `Turtle` declared as crate-private - //~| NOTE but type `Turtle` is only usable at visibility `pub(crate)` } struct Tortoise; -//~^ NOTE `Tortoise` declared as private -//~| NOTE but type `Tortoise` is only usable at visibility `pub(crate)` pub struct Shell<T> { pub(crate) creature: T, } pub type Helix_pomatia = Shell<Snail>; -//~^ ERROR private type `Snail` in public interface -//~| WARNING type `Snail` is more private than the item `Helix_pomatia` -//~| NOTE can't leak private type -//~| NOTE type alias `Helix_pomatia` is reachable at visibility `pub` +//~^ WARNING type `Snail` is more private than the item `Helix_pomatia` pub type Dermochelys_coriacea = Shell<sea::Turtle>; -//~^ ERROR crate-private type `Turtle` in public interface -//~| WARNING type `Turtle` is more private than the item `Dermochelys_coriacea` -//~| NOTE can't leak crate-private type -//~| NOTE type alias `Dermochelys_coriacea` is reachable at visibility `pub` +//~^ WARNING type `Turtle` is more private than the item `Dermochelys_coriacea` pub type Testudo_graeca = Shell<Tortoise>; -//~^ ERROR private type `Tortoise` in public interface -//~| WARNING type `Tortoise` is more private than the item `Testudo_graeca` -//~| NOTE can't leak private type -//~| NOTE type alias `Testudo_graeca` is reachable at visibility `pub` +//~^ WARNING type `Tortoise` is more private than the item `Testudo_graeca` fn main() {} diff --git a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr index 20e51e1901f..26dfa2e7d4f 100644 --- a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr +++ b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr @@ -1,71 +1,39 @@ -error[E0446]: private type `Snail` in public interface - --> $DIR/issue-33174-restricted-type-in-public-interface.rs:28:1 - | -LL | pub(crate) struct Snail; - | ----------------------- `Snail` declared as private -... -LL | pub type Helix_pomatia = Shell<Snail>; - | ^^^^^^^^^^^^^^^^^^^^^^ can't leak private type - warning: type `Snail` is more private than the item `Helix_pomatia` - --> $DIR/issue-33174-restricted-type-in-public-interface.rs:28:1 + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:17:1 | LL | pub type Helix_pomatia = Shell<Snail>; | ^^^^^^^^^^^^^^^^^^^^^^ type alias `Helix_pomatia` is reachable at visibility `pub` | note: but type `Snail` is only usable at visibility `pub(crate)` - --> $DIR/issue-33174-restricted-type-in-public-interface.rs:10:1 + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:5:1 | LL | pub(crate) struct Snail; | ^^^^^^^^^^^^^^^^^^^^^^^ -note: the lint level is defined here - --> $DIR/issue-33174-restricted-type-in-public-interface.rs:3:9 - | -LL | #![warn(private_interfaces)] - | ^^^^^^^^^^^^^^^^^^ - -error[E0446]: crate-private type `Turtle` in public interface - --> $DIR/issue-33174-restricted-type-in-public-interface.rs:33:1 - | -LL | pub(super) struct Turtle; - | ------------------------ `Turtle` declared as crate-private -... -LL | pub type Dermochelys_coriacea = Shell<sea::Turtle>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak crate-private type + = note: `#[warn(private_interfaces)]` on by default warning: type `Turtle` is more private than the item `Dermochelys_coriacea` - --> $DIR/issue-33174-restricted-type-in-public-interface.rs:33:1 + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:19:1 | LL | pub type Dermochelys_coriacea = Shell<sea::Turtle>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type alias `Dermochelys_coriacea` is reachable at visibility `pub` | note: but type `Turtle` is only usable at visibility `pub(crate)` - --> $DIR/issue-33174-restricted-type-in-public-interface.rs:15:5 + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:8:5 | LL | pub(super) struct Turtle; | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0446]: private type `Tortoise` in public interface - --> $DIR/issue-33174-restricted-type-in-public-interface.rs:38:1 - | -LL | struct Tortoise; - | --------------- `Tortoise` declared as private -... -LL | pub type Testudo_graeca = Shell<Tortoise>; - | ^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type - warning: type `Tortoise` is more private than the item `Testudo_graeca` - --> $DIR/issue-33174-restricted-type-in-public-interface.rs:38:1 + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:21:1 | LL | pub type Testudo_graeca = Shell<Tortoise>; | ^^^^^^^^^^^^^^^^^^^^^^^ type alias `Testudo_graeca` is reachable at visibility `pub` | note: but type `Tortoise` is only usable at visibility `pub(crate)` - --> $DIR/issue-33174-restricted-type-in-public-interface.rs:20:1 + --> $DIR/issue-33174-restricted-type-in-public-interface.rs:11:1 | LL | struct Tortoise; | ^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors; 3 warnings emitted +warning: 3 warnings emitted -For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/range/range-1.stderr b/tests/ui/range/range-1.stderr index 277d9b2682d..ecfc56961ee 100644 --- a/tests/ui/range/range-1.stderr +++ b/tests/ui/range/range-1.stderr @@ -19,7 +19,7 @@ LL | for i in false..true {} i64 i128 usize - and 5 others + and 6 others = note: required for `std::ops::Range<bool>` to implement `Iterator` = note: required for `std::ops::Range<bool>` to implement `IntoIterator` diff --git a/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr b/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr index f2328cf3b24..a9a92b7a695 100644 --- a/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr +++ b/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr @@ -8,7 +8,6 @@ LL | let _: fn(&mut &isize, &mut &isize) = a; | = note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)` found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}` - = note: when the arguments and return types match, functions can be coerced to function pointers error: aborting due to previous error diff --git a/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr b/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr index 9c5004981d5..e96559937d4 100644 --- a/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr +++ b/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr @@ -8,7 +8,6 @@ LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; | = note: expected fn pointer `for<'a, 'b, 'c, 'd, 'e, 'f> fn(&'a mut &'b isize, &'c mut &'d isize, &'e mut &'f isize)` found fn item `for<'a, 'b, 'c> fn(&'a mut &isize, &'b mut &isize, &'c mut &isize) {a::<'_, '_, '_>}` - = note: when the arguments and return types match, functions can be coerced to function pointers error: aborting due to previous error diff --git a/tests/ui/regions/regions-fn-subtyping-return-static-fail.stderr b/tests/ui/regions/regions-fn-subtyping-return-static-fail.stderr index 766a3d0337c..8d82ff958ff 100644 --- a/tests/ui/regions/regions-fn-subtyping-return-static-fail.stderr +++ b/tests/ui/regions/regions-fn-subtyping-return-static-fail.stderr @@ -8,7 +8,6 @@ LL | want_G(baz); | = note: expected fn pointer `for<'cx> fn(&'cx S) -> &'static S` found fn item `for<'a> fn(&'a S) -> &'a S {baz}` - = note: when the arguments and return types match, functions can be coerced to function pointers note: function defined here --> $DIR/regions-fn-subtyping-return-static-fail.rs:20:4 | diff --git a/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr b/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr index 2fab2986567..53a5612d24f 100644 --- a/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr +++ b/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr @@ -8,7 +8,6 @@ LL | let _: fn(&mut &isize, &mut &isize) = a; | = note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)` found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}` - = note: when the arguments and return types match, functions can be coerced to function pointers error: aborting due to previous error diff --git a/tests/ui/reify-intrinsic.stderr b/tests/ui/reify-intrinsic.stderr index 9f9034a30c7..310b6c224e0 100644 --- a/tests/ui/reify-intrinsic.stderr +++ b/tests/ui/reify-intrinsic.stderr @@ -8,7 +8,6 @@ LL | let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::tr | = note: expected fn pointer `unsafe extern "rust-intrinsic" fn(isize) -> usize` found fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` - = note: when the arguments and return types match, functions can be coerced to function pointers error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid --> $DIR/reify-intrinsic.rs:11:13 diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr index b0ac5dc44ad..e08ffe42d6a 100644 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr +++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr @@ -13,7 +13,6 @@ LL | let foo: fn() = foo; found fn item `fn() {foo}` = note: fn items are distinct from fn pointers = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers - = note: when the arguments and return types match, functions can be coerced to function pointers help: consider casting to a fn pointer | LL | let foo: fn() = foo as fn(); diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr index b0ac5dc44ad..e08ffe42d6a 100644 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr +++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr @@ -13,7 +13,6 @@ LL | let foo: fn() = foo; found fn item `fn() {foo}` = note: fn items are distinct from fn pointers = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers - = note: when the arguments and return types match, functions can be coerced to function pointers help: consider casting to a fn pointer | LL | let foo: fn() = foo as fn(); diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.rs index e0dded15217..2c0571a7bdd 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.rs +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.rs @@ -1,19 +1,18 @@ +// check-pass + fn and_chain() { let z; if true && { z = 3; true} && z == 3 {} - //~^ ERROR E0381 } fn and_chain_2() { let z; true && { z = 3; true} && z == 3; - //~^ ERROR E0381 } fn or_chain() { let z; if false || { z = 3; false} || z == 3 {} - //~^ ERROR E0381 } fn main() { diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.stderr deleted file mode 100644 index 30d5a6779fc..00000000000 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0381]: used binding `z` is possibly-uninitialized - --> $DIR/chains-without-let.rs:3:34 - | -LL | let z; - | - binding declared here but left uninitialized -LL | if true && { z = 3; true} && z == 3 {} - | ----- ^ `z` used here but it is possibly-uninitialized - | | - | binding initialized here in some conditions - -error[E0381]: used binding `z` is possibly-uninitialized - --> $DIR/chains-without-let.rs:9:31 - | -LL | let z; - | - binding declared here but left uninitialized -LL | true && { z = 3; true} && z == 3; - | ----- ^ `z` used here but it is possibly-uninitialized - | | - | binding initialized here in some conditions - -error[E0381]: used binding `z` is possibly-uninitialized - --> $DIR/chains-without-let.rs:15:36 - | -LL | let z; - | - binding declared here but left uninitialized -LL | if false || { z = 3; false} || z == 3 {} - | ----- ^ `z` used here but it is possibly-uninitialized - | | - | binding initialized here in some conditions - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0381`. diff --git a/tests/ui/static/static-reference-to-fn-1.stderr b/tests/ui/static/static-reference-to-fn-1.stderr index b68352b5183..86c4eaa7eb4 100644 --- a/tests/ui/static/static-reference-to-fn-1.stderr +++ b/tests/ui/static/static-reference-to-fn-1.stderr @@ -7,7 +7,6 @@ LL | func: &foo, = note: expected reference `&fn() -> Option<isize>` found reference `&fn() -> Option<isize> {foo}` = note: fn items are distinct from fn pointers - = note: when the arguments and return types match, functions can be coerced to function pointers help: consider casting to a fn pointer | LL | func: &(foo as fn() -> Option<isize>), diff --git a/tests/ui/test-attrs/issue-36768.rs b/tests/ui/test-attrs/issue-36768.rs index f671cbc8205..7531f3621f5 100644 --- a/tests/ui/test-attrs/issue-36768.rs +++ b/tests/ui/test-attrs/issue-36768.rs @@ -1,6 +1,6 @@ // run-pass // compile-flags:--test -#![deny(private_in_public)] +#![deny(private_interfaces)] #[test] fn foo() {} mod foo {} diff --git a/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs index 546fcbaa3de..b6129163333 100644 --- a/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs +++ b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs @@ -1,3 +1,5 @@ +// check-pass + //! If visibility is assumed, a transmutation should be accepted even if the //! destination type contains an unreachable field (e.g., a public field with a //! private type). (This rule is distinct from type privacy, which still may @@ -29,7 +31,7 @@ mod dst { #[repr(C)] pub(self) struct Zst; // <- unreachable type #[repr(C)] pub(in super) struct Dst { - pub(in super) field: Zst, //~ ERROR private type + pub(in super) field: Zst, //~ WARNING type `dst::Zst` is more private than the item `Dst::field` } } diff --git a/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr index be83b7ce33f..80099388d63 100644 --- a/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr +++ b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr @@ -1,12 +1,15 @@ -error[E0446]: private type `dst::Zst` in public interface - --> $DIR/should_accept_if_dst_has_unreachable_field.rs:32:9 +warning: type `dst::Zst` is more private than the item `Dst::field` + --> $DIR/should_accept_if_dst_has_unreachable_field.rs:34:9 | -LL | #[repr(C)] pub(self) struct Zst; // <- unreachable type - | -------------------- `dst::Zst` declared as private -... LL | pub(in super) field: Zst, - | ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^^^^^^^^^^^^^^ field `Dst::field` is reachable at visibility `pub(crate)` + | +note: but type `dst::Zst` is only usable at visibility `pub(self)` + --> $DIR/should_accept_if_dst_has_unreachable_field.rs:31:16 + | +LL | #[repr(C)] pub(self) struct Zst; // <- unreachable type + | ^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(private_interfaces)]` on by default -error: aborting due to previous error +warning: 1 warning emitted -For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs index 9c8345a8e91..e7742058c57 100644 --- a/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs +++ b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs @@ -1,3 +1,5 @@ +// check-pass + //! The presence of an unreachable field in the source type (e.g., a public //! field with a private type does not affect transmutability. (This rule is //! distinct from type privacy, which still may forbid naming such types.) @@ -19,7 +21,7 @@ mod src { #[repr(C)] pub(self) struct Zst; // <- unreachable type #[repr(C)] pub(in super) struct Src { - pub(in super) field: Zst, //~ ERROR private type + pub(in super) field: Zst, //~ WARNING type `src::Zst` is more private than the item `Src::field` } } diff --git a/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr index 39b73302e36..55fb3392305 100644 --- a/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr +++ b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr @@ -1,12 +1,15 @@ -error[E0446]: private type `src::Zst` in public interface - --> $DIR/should_accept_if_src_has_unreachable_field.rs:22:9 +warning: type `src::Zst` is more private than the item `Src::field` + --> $DIR/should_accept_if_src_has_unreachable_field.rs:24:9 | -LL | #[repr(C)] pub(self) struct Zst; // <- unreachable type - | -------------------- `src::Zst` declared as private -... LL | pub(in super) field: Zst, - | ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type + | ^^^^^^^^^^^^^^^^^^^^^^^^ field `Src::field` is reachable at visibility `pub(crate)` + | +note: but type `src::Zst` is only usable at visibility `pub(self)` + --> $DIR/should_accept_if_src_has_unreachable_field.rs:21:16 + | +LL | #[repr(C)] pub(self) struct Zst; // <- unreachable type + | ^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(private_interfaces)]` on by default -error: aborting due to previous error +warning: 1 warning emitted -For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/type-alias-impl-trait/privacy.rs b/tests/ui/type-alias-impl-trait/privacy.rs index aa092f6f8ec..3efbfaf0916 100644 --- a/tests/ui/type-alias-impl-trait/privacy.rs +++ b/tests/ui/type-alias-impl-trait/privacy.rs @@ -1,8 +1,10 @@ +// check-pass + #![feature(type_alias_impl_trait)] type Foo = (impl Sized, u8); pub fn foo() -> Foo { - //~^ ERROR private type alias `Foo` in public interface + //~^ WARNING type alias `Foo` is more private than the item `foo` (42, 42) } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/privacy.stderr b/tests/ui/type-alias-impl-trait/privacy.stderr index e8c6039cdc8..50870905c30 100644 --- a/tests/ui/type-alias-impl-trait/privacy.stderr +++ b/tests/ui/type-alias-impl-trait/privacy.stderr @@ -1,11 +1,15 @@ -error[E0446]: private type alias `Foo` in public interface - --> $DIR/privacy.rs:4:1 +warning: type alias `Foo` is more private than the item `foo` + --> $DIR/privacy.rs:6:1 | -LL | type Foo = (impl Sized, u8); - | -------- `Foo` declared as private LL | pub fn foo() -> Foo { - | ^^^^^^^^^^^^^^^^^^^ can't leak private type alias + | ^^^^^^^^^^^^^^^^^^^ function `foo` is reachable at visibility `pub` + | +note: but type alias `Foo` is only usable at visibility `pub(crate)` + --> $DIR/privacy.rs:5:1 + | +LL | type Foo = (impl Sized, u8); + | ^^^^^^^^ + = note: `#[warn(private_interfaces)]` on by default -error: aborting due to previous error +warning: 1 warning emitted -For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/unsafe/initializing-ranged-via-ctor.rs b/tests/ui/unsafe/initializing-ranged-via-ctor.rs new file mode 100644 index 00000000000..ca44fa7e4e7 --- /dev/null +++ b/tests/ui/unsafe/initializing-ranged-via-ctor.rs @@ -0,0 +1,11 @@ +#![feature(rustc_attrs)] +#![allow(internal_features)] + +#[derive(Debug)] +#[rustc_layout_scalar_valid_range_start(2)] +struct NonZeroAndOneU8(u8); + +fn main() { + println!("{:?}", Some(1).map(NonZeroAndOneU8).unwrap()); + //~^ ERROR found `unsafe fn(u8) -> NonZeroAndOneU8 {NonZeroAndOneU8}` +} diff --git a/tests/ui/unsafe/initializing-ranged-via-ctor.stderr b/tests/ui/unsafe/initializing-ranged-via-ctor.stderr new file mode 100644 index 00000000000..d34554c6641 --- /dev/null +++ b/tests/ui/unsafe/initializing-ranged-via-ctor.stderr @@ -0,0 +1,16 @@ +error[E0277]: expected a `FnOnce<({integer},)>` closure, found `unsafe fn(u8) -> NonZeroAndOneU8 {NonZeroAndOneU8}` + --> $DIR/initializing-ranged-via-ctor.rs:9:34 + | +LL | println!("{:?}", Some(1).map(NonZeroAndOneU8).unwrap()); + | --- ^^^^^^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }` + | | + | required by a bound introduced by this call + | + = help: the trait `FnOnce<({integer},)>` is not implemented for fn item `unsafe fn(u8) -> NonZeroAndOneU8 {NonZeroAndOneU8}` + = note: unsafe function cannot be called generically without an unsafe block +note: required by a bound in `Option::<T>::map` + --> $SRC_DIR/core/src/option.rs:LL:COL + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/unsafe/ranged-ctor-as-fn-ptr.rs b/tests/ui/unsafe/ranged-ctor-as-fn-ptr.rs new file mode 100644 index 00000000000..a91e579510d --- /dev/null +++ b/tests/ui/unsafe/ranged-ctor-as-fn-ptr.rs @@ -0,0 +1,10 @@ +#![feature(rustc_attrs)] + +#[derive(Debug)] +#[rustc_layout_scalar_valid_range_start(2)] +struct NonZeroAndOneU8(u8); + +fn main() { + let x: fn(u8) -> NonZeroAndOneU8 = NonZeroAndOneU8; + //~^ ERROR mismatched types +} diff --git a/tests/ui/unsafe/ranged-ctor-as-fn-ptr.stderr b/tests/ui/unsafe/ranged-ctor-as-fn-ptr.stderr new file mode 100644 index 00000000000..660c4070451 --- /dev/null +++ b/tests/ui/unsafe/ranged-ctor-as-fn-ptr.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/ranged-ctor-as-fn-ptr.rs:8:40 + | +LL | let x: fn(u8) -> NonZeroAndOneU8 = NonZeroAndOneU8; + | ------------------------- ^^^^^^^^^^^^^^^ expected normal fn, found unsafe fn + | | + | expected due to this + | + = note: expected fn pointer `fn(_) -> NonZeroAndOneU8` + found struct constructor `unsafe fn(_) -> NonZeroAndOneU8 {NonZeroAndOneU8}` + = note: unsafe functions cannot be coerced into safe function pointers + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/triagebot.toml b/triagebot.toml index 6f7efd4c3db..6847e8a00be 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -585,7 +585,7 @@ cc = ["@nnethercote"] [assign] warn_non_default_branch = true contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html" -users_on_vacation = ["jyn514", "clubby789"] +users_on_vacation = ["jyn514", "clubby789", "spastorino"] [assign.adhoc_groups] compiler-team = [ |
