From 571b0fef01ea994cd9a81405283049b5595499c5 Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Mon, 13 Mar 2023 01:31:02 -0400 Subject: [PATCH 1/9] Clarify stability guarantee for lifetimes in enum discriminants --- library/core/src/mem/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index a67df7ed557a1..aa53aa29bdbf3 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1118,6 +1118,11 @@ impl fmt::Debug for Discriminant { /// /// [Reference]: ../../reference/items/enumerations.html#custom-discriminant-values-for-fieldless-enumerations /// +/// The value of a [`Discriminant`] is independent of any *lifetimes* in `T`. As such, reading +/// or writing a `Discriminant>` as a `Discriminant>` (whether via [`transmute`] or +/// otherwise) is always sound. Note that this is **not** true for other kinds of generic +/// parameters; `Discriminant>` and `Discriminant>` might be incompatible. +/// /// # Examples /// /// This can be used to compare enums that carry data, while disregarding From 19edb3ce808ee2b1190026b9d56cc6187e1ad9b1 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 24 Aug 2023 20:44:32 -0700 Subject: [PATCH 2/9] rustdoc: list matching impls on type aliases Remake of "List matching impls on type aliases" * 4b1d13d9841c815915433ca2a3088a8e3e97ad96 * 6f552c800b38b3e71c5e33a295e8b490d2018c71 * 2ce7cd906bde70d8cbd9b07b31c6a7bf1131c345 Partially reverts "Fix infinite loop when retrieving impls for type alias", but keeps the test case. This version of the PR avoids the infinite loop by structurally matching types instead of using full unification. This version does not support type alias trait bounds, but the compiler does not enforce those anyway (https://github.com/rust-lang/rust/issues/21903). --- src/librustdoc/html/render/mod.rs | 47 +++++++++++++-- tests/rustdoc/issue-32077-type-alias-impls.rs | 59 +++++++++++++++++++ 2 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 tests/rustdoc/issue-32077-type-alias-impls.rs diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index aef8f1a74fb5a..1d77ce74c80ea 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -54,6 +54,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::Mutability; use rustc_middle::middle::stability; +use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::TyCtxt; use rustc_span::{ symbol::{sym, Symbol}, @@ -62,6 +63,7 @@ use rustc_span::{ use serde::ser::{SerializeMap, SerializeSeq}; use serde::{Serialize, Serializer}; +use crate::clean::types::TypeAliasItem; use crate::clean::{self, ItemId, RenderedLink, SelfTy}; use crate::error::Error; use crate::formats::cache::Cache; @@ -1139,8 +1141,40 @@ fn render_assoc_items_inner( info!("Documenting associated items of {:?}", containing_item.name); let shared = Rc::clone(&cx.shared); let cache = &shared.cache; - let Some(v) = cache.impls.get(&it) else { return }; - let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none()); + let tcx = cx.tcx(); + let av = if let TypeAliasItem(ait) = &*containing_item.kind && + let aliased_clean_type = ait.item_type.as_ref().unwrap_or(&ait.type_) && + let Some(aliased_type_defid) = aliased_clean_type.def_id(cache) && + let Some(mut av) = cache.impls.get(&aliased_type_defid).cloned() && + let Some(alias_def_id) = containing_item.item_id.as_def_id() + { + // This branch of the compiler compares types structually, but does + // not check trait bounds. That's probably fine, since type aliases + // don't normally constrain on them anyway. + // https://github.com/rust-lang/rust/issues/21903 + // + // If that changes, then this will need to check them with type + // unification. + let aliased_ty = tcx.type_of(alias_def_id).skip_binder(); + let reject_cx = DeepRejectCtxt { + treat_obligation_params: TreatParams::AsCandidateKey, + }; + av.retain(|impl_| { + if let Some(impl_def_id) = impl_.impl_item.item_id.as_def_id() { + reject_cx.types_may_unify(aliased_ty, tcx.type_of(impl_def_id).skip_binder()) + } else { + false + } + }); + av + } else { + Vec::new() + }; + let blank = Vec::new(); + let v = cache.impls.get(&it).unwrap_or(&blank); + let (non_trait, traits): (Vec<_>, _) = + v.iter().chain(&av[..]).partition(|i| i.inner_impl().trait_.is_none()); + let mut saw_impls = FxHashSet::default(); if !non_trait.is_empty() { let mut tmp_buf = Buffer::html(); let (render_mode, id, class_html) = match what { @@ -1169,6 +1203,9 @@ fn render_assoc_items_inner( }; let mut impls_buf = Buffer::html(); for i in &non_trait { + if !saw_impls.insert(i.def_id()) { + continue; + } render_impl( &mut impls_buf, cx, @@ -1214,8 +1251,10 @@ fn render_assoc_items_inner( let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = traits.into_iter().partition(|t| t.inner_impl().kind.is_auto()); - let (blanket_impl, concrete): (Vec<&Impl>, _) = - concrete.into_iter().partition(|t| t.inner_impl().kind.is_blanket()); + let (blanket_impl, concrete): (Vec<&Impl>, _) = concrete + .into_iter() + .filter(|t| saw_impls.insert(t.def_id())) + .partition(|t| t.inner_impl().kind.is_blanket()); render_all_impls(w, cx, containing_item, &concrete, &synthetic, &blanket_impl); } diff --git a/tests/rustdoc/issue-32077-type-alias-impls.rs b/tests/rustdoc/issue-32077-type-alias-impls.rs new file mode 100644 index 0000000000000..555d0579bee79 --- /dev/null +++ b/tests/rustdoc/issue-32077-type-alias-impls.rs @@ -0,0 +1,59 @@ +// Regression test for . + +#![crate_name = "foo"] + +pub struct GenericStruct(T); + +impl GenericStruct { + pub fn on_gen(arg: T) {} +} + +impl GenericStruct { + pub fn on_u32(arg: u32) {} +} + +pub trait Foo {} +pub trait Bar {} + +impl Foo for GenericStruct {} +impl Bar for GenericStruct {} + +// @has 'foo/type.TypedefStruct.html' +// We check that we have the implementation of the type alias itself. +// @has - '//*[@id="impl-TypedefStruct"]/h3' 'impl TypedefStruct' +// @has - '//*[@id="method.on_alias"]/h4' 'pub fn on_alias()' +// @has - '//*[@id="impl-GenericStruct%3CT%3E"]/h3' 'impl GenericStruct' +// @has - '//*[@id="method.on_gen"]/h4' 'pub fn on_gen(arg: T)' +// @has - '//*[@id="impl-Foo-for-GenericStruct%3CT%3E"]/h3' 'impl Foo for GenericStruct' +// This trait implementation doesn't match the type alias parameters so shouldn't appear in docs. +// @!has - '//h3' 'impl Bar for GenericStruct {}' +// Same goes for the `Deref` impl. +// @!has - '//h2' 'Methods from Deref' +pub type TypedefStruct = GenericStruct; + +impl TypedefStruct { + pub fn on_alias() {} +} + +impl std::ops::Deref for GenericStruct { + type Target = u32; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +pub struct Wrap(GenericStruct); + +// @has 'foo/type.Alias.html' +// @has - '//h2' 'Methods from Deref' +// @has - '//*[@id="impl-Deref-for-Wrap%3CT%3E"]/h3' 'impl Deref for Wrap' +pub type Alias = Wrap; + +impl std::ops::Deref for Wrap { + type Target = GenericStruct; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} From 20768b270e9b56368051f6f9b2be29dd0a1acb36 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 8 Jun 2023 22:48:29 +0200 Subject: [PATCH 3/9] Fix intra-doc links from pointer appearing in windows HANDLE type alias --- library/core/src/ptr/mut_ptr.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 9dbb3f9d322c0..6d623b82c1cfe 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -109,7 +109,7 @@ impl *mut T { /// with [`cast_mut`] on `*const T` and may have documentation value if used instead of implicit /// coercion. /// - /// [`cast_mut`]: #method.cast_mut + /// [`cast_mut`]: pointer::cast_mut #[stable(feature = "ptr_const_cast", since = "1.65.0")] #[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")] #[rustc_diagnostic_item = "ptr_cast_const"] @@ -121,7 +121,7 @@ impl *mut T { /// Casts a pointer to its raw bits. /// /// This is equivalent to `as usize`, but is more specific to enhance readability. - /// The inverse method is [`from_bits`](#method.from_bits-1). + /// The inverse method is [`from_bits`](pointer#method.from_bits-1). /// /// In particular, `*p as usize` and `p as usize` will both compile for /// pointers to numeric types but do very different things, so using this @@ -157,7 +157,7 @@ impl *mut T { /// Creates a pointer from its raw bits. /// /// This is equivalent to `as *mut T`, but is more specific to enhance readability. - /// The inverse method is [`to_bits`](#method.to_bits-1). + /// The inverse method is [`to_bits`](pointer#method.to_bits-1). /// /// # Examples /// @@ -307,7 +307,7 @@ impl *mut T { /// /// For the mutable counterpart see [`as_mut`]. /// - /// [`as_uninit_ref`]: #method.as_uninit_ref-1 + /// [`as_uninit_ref`]: pointer#method.as_uninit_ref-1 /// [`as_mut`]: #method.as_mut /// /// # Safety @@ -373,7 +373,7 @@ impl *mut T { /// /// For the mutable counterpart see [`as_uninit_mut`]. /// - /// [`as_ref`]: #method.as_ref-1 + /// [`as_ref`]: pointer#method.as_ref-1 /// [`as_uninit_mut`]: #method.as_uninit_mut /// /// # Safety @@ -628,7 +628,7 @@ impl *mut T { /// For the shared counterpart see [`as_ref`]. /// /// [`as_uninit_mut`]: #method.as_uninit_mut - /// [`as_ref`]: #method.as_ref-1 + /// [`as_ref`]: pointer#method.as_ref-1 /// /// # Safety /// @@ -693,7 +693,7 @@ impl *mut T { /// For the shared counterpart see [`as_uninit_ref`]. /// /// [`as_mut`]: #method.as_mut - /// [`as_uninit_ref`]: #method.as_uninit_ref-1 + /// [`as_uninit_ref`]: pointer#method.as_uninit_ref-1 /// /// # Safety /// @@ -783,7 +783,7 @@ impl *mut T { /// /// This function is the inverse of [`offset`]. /// - /// [`offset`]: #method.offset-1 + /// [`offset`]: pointer#method.offset-1 /// /// # Safety /// @@ -2064,7 +2064,7 @@ impl *mut [T] { /// /// For the mutable counterpart see [`as_uninit_slice_mut`]. /// - /// [`as_ref`]: #method.as_ref-1 + /// [`as_ref`]: pointer#method.as_ref-1 /// [`as_uninit_slice_mut`]: #method.as_uninit_slice_mut /// /// # Safety From b3686c2fd6ad57912e1b0e778bedb0b9a05c73fa Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 25 Aug 2023 07:32:54 -0700 Subject: [PATCH 4/9] Add note about lazy_type_alias MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: León Orell Valerian Liehr --- src/librustdoc/html/render/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 1d77ce74c80ea..a85e8356c2f21 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1153,8 +1153,8 @@ fn render_assoc_items_inner( // don't normally constrain on them anyway. // https://github.com/rust-lang/rust/issues/21903 // - // If that changes, then this will need to check them with type - // unification. + // FIXME(lazy_type_alias): Once the feature is complete or stable, rewrite this to use type unification. + // Be aware of `tests/rustdoc/issue-112515-impl-ty-alias.rs` which might regress. let aliased_ty = tcx.type_of(alias_def_id).skip_binder(); let reject_cx = DeepRejectCtxt { treat_obligation_params: TreatParams::AsCandidateKey, From 14e59bb317c3c901bce83deb16ee9bfa5cc90e28 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 7 Sep 2023 06:27:10 +0000 Subject: [PATCH 5/9] Lint node for PRIVATE_BOUNDS is the item which has the bounds --- compiler/rustc_privacy/src/lib.rs | 7 ++++--- tests/ui/privacy/private-bounds-locally-allowed.rs | 7 +++++++ 2 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 tests/ui/privacy/private-bounds-locally-allowed.rs diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 906a36cdb25d1..aedc7b22725aa 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1463,14 +1463,15 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { }; let vis = self.tcx.local_visibility(local_def_id); - 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 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) => { - if vis_def_id == self.tcx.parent_module(hir_id).to_local_def_id() { + if vis_def_id + == self.tcx.parent_module_from_def_id(local_def_id).to_local_def_id() + { "private" } else if vis_def_id.is_top_level_module() { "crate-private" @@ -1504,7 +1505,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { }; self.tcx.emit_spanned_lint( lint, - hir_id, + self.tcx.hir().local_def_id_to_hir_id(self.item_def_id), span, PrivateInterfacesOrBoundsLint { item_span: span, diff --git a/tests/ui/privacy/private-bounds-locally-allowed.rs b/tests/ui/privacy/private-bounds-locally-allowed.rs new file mode 100644 index 0000000000000..96a007a64f630 --- /dev/null +++ b/tests/ui/privacy/private-bounds-locally-allowed.rs @@ -0,0 +1,7 @@ +// check-pass +// compile-flags: --crate-type=lib + +#[allow(private_bounds)] +pub trait Foo: FooImpl {} + +trait FooImpl {} From bb6dcf5f740f6147eaf8774509ca27adc47c009b Mon Sep 17 00:00:00 2001 From: Liu Dingming Date: Thu, 7 Sep 2023 17:34:41 +0800 Subject: [PATCH 6/9] Add `RegisterCodeGenFlags` to get full codegen flags list --- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 4ac739326d2dd..4b30a4fefd9d9 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -9,6 +9,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/CodeGen/CommandFlags.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/AssemblyAnnotationWriter.h" @@ -50,6 +51,8 @@ using namespace llvm; +static codegen::RegisterCodeGenFlags CGF; + typedef struct LLVMOpaquePass *LLVMPassRef; typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef; From 487766cef0faa12c3e744b8c754ea7c58427ec2f Mon Sep 17 00:00:00 2001 From: Liu Dingming Date: Thu, 7 Sep 2023 17:36:21 +0800 Subject: [PATCH 7/9] Using parsed codegen flags --- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 4b30a4fefd9d9..194ebe6d96890 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -424,7 +424,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( return nullptr; } - TargetOptions Options; + TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Trip); Options.FloatABIType = FloatABI::Default; if (UseSoftFloat) { From 967410c64031002500534863b8d945b9f21bb1c8 Mon Sep 17 00:00:00 2001 From: bohan Date: Fri, 8 Sep 2023 01:39:26 +0800 Subject: [PATCH 8/9] fix: return ealry when has tainted in mir-lint --- .../src/const_prop_lint.rs | 4 ++++ tests/ui/unsized/issue-115203.rs | 11 +++++++++++ tests/ui/unsized/issue-115203.stderr | 19 +++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 tests/ui/unsized/issue-115203.rs create mode 100644 tests/ui/unsized/issue-115203.stderr diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 4b51beed09558..b52827a1e88d8 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -39,6 +39,10 @@ pub struct ConstProp; impl<'tcx> MirLint<'tcx> for ConstProp { fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { + if body.tainted_by_errors.is_some() { + return; + } + // will be evaluated by miri and produce its errors there if body.source.promoted.is_some() { return; diff --git a/tests/ui/unsized/issue-115203.rs b/tests/ui/unsized/issue-115203.rs new file mode 100644 index 0000000000000..5fe7bd64288da --- /dev/null +++ b/tests/ui/unsized/issue-115203.rs @@ -0,0 +1,11 @@ +// compile-flags: --emit link + +fn main() { + let a: [i32; 0] = []; + match [a[..]] { + //~^ ERROR cannot move a value of type `[i32] + //~| ERROR cannot move out of type `[i32]`, a non-copy slice + [[]] => (), + _ => (), + } +} diff --git a/tests/ui/unsized/issue-115203.stderr b/tests/ui/unsized/issue-115203.stderr new file mode 100644 index 0000000000000..3ee734988c5a8 --- /dev/null +++ b/tests/ui/unsized/issue-115203.stderr @@ -0,0 +1,19 @@ +error[E0161]: cannot move a value of type `[i32]` + --> $DIR/issue-115203.rs:5:12 + | +LL | match [a[..]] { + | ^^^^^ the size of `[i32]` cannot be statically determined + +error[E0508]: cannot move out of type `[i32]`, a non-copy slice + --> $DIR/issue-115203.rs:5:12 + | +LL | match [a[..]] { + | ^^^^^ + | | + | cannot move out of here + | move occurs because value has type `[i32]`, which does not implement the `Copy` trait + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0161, E0508. +For more information about an error, try `rustc --explain E0161`. From 45abd8caf2d596a520a8b712967aa19d799d002b Mon Sep 17 00:00:00 2001 From: LuuuX Date: Tue, 22 Aug 2023 15:15:00 +0800 Subject: [PATCH 9/9] Fix Issue 112009 modify fuction clond() -> cloned() optimize the code Handle the problem that the pathset is empty and modify the judgment of the builder::tests::test_exclude_kind Delete unnecessary judegment conditions skip test for library/std duo to OOM in benches as library/alloc Add FIXME for WASM32 --- src/bootstrap/builder.rs | 6 ++++-- src/bootstrap/builder/tests.rs | 4 ++-- src/ci/docker/host-x86_64/wasm32/Dockerfile | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index b366619285338..d28ac1a05f4fb 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -302,8 +302,10 @@ impl StepDescription { } } - fn maybe_run(&self, builder: &Builder<'_>, pathsets: Vec) { - if pathsets.iter().any(|set| self.is_excluded(builder, set)) { + fn maybe_run(&self, builder: &Builder<'_>, mut pathsets: Vec) { + pathsets.retain(|set| !self.is_excluded(builder, set)); + + if pathsets.is_empty() { return; } diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index 43b4a34fe5b62..80e66622e8b92 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -136,9 +136,9 @@ fn test_exclude_kind() { let mut config = configure("test", &["A"], &["A"]); // Ensure our test is valid, and `test::Rustc` would be run without the exclude. assert!(run_build(&[], config.clone()).contains::()); - // Ensure tests for rustc are skipped. + // Ensure tests for rustc are not skipped. config.skip = vec![path.clone()]; - assert!(!run_build(&[], config.clone()).contains::()); + assert!(run_build(&[], config.clone()).contains::()); // Ensure builds for rustc are not skipped. assert!(run_build(&[], config).contains::()); } diff --git a/src/ci/docker/host-x86_64/wasm32/Dockerfile b/src/ci/docker/host-x86_64/wasm32/Dockerfile index 02b4664eb557c..0d0f1edd003cb 100644 --- a/src/ci/docker/host-x86_64/wasm32/Dockerfile +++ b/src/ci/docker/host-x86_64/wasm32/Dockerfile @@ -58,5 +58,6 @@ ENV NO_CHANGE_USER=1 RUN chown 10719 -R /emsdk-portable/ # Exclude library/alloc due to OOM in benches. +# FIXME: Fix std tests ENV SCRIPT python3 ../x.py test --stage 2 --host='' --target $TARGETS \ - --skip library/alloc + --skip library/alloc --skip library/std