Skip to content

Commit 309af34

Browse files
committed
Auto merge of #115672 - GuillaumeGomez:rollup-mjiy56f, r=GuillaumeGomez
Rollup of 6 pull requests Successful merges: - #104299 (Clarify stability guarantee for lifetimes in enum discriminants) - #115088 (Fix Step Skipping Caused by Using the `--exclude` Option) - #115201 (rustdoc: list matching impls on type aliases) - #115633 (Lint node for `PRIVATE_BOUNDS`/`PRIVATE_INTERFACES` is the item which names the private type) - #115638 (`-Cllvm-args` usability improvement) - #115643 (fix: return early when has tainted in mir-lint) r? `@ghost` `@rustbot` modify labels: rollup
2 parents cd71a37 + 60327bb commit 309af34

File tree

13 files changed

+173
-22
lines changed

13 files changed

+173
-22
lines changed

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "llvm/Analysis/AliasAnalysis.h"
1010
#include "llvm/Analysis/TargetLibraryInfo.h"
1111
#include "llvm/Analysis/TargetTransformInfo.h"
12+
#include "llvm/CodeGen/CommandFlags.h"
1213
#include "llvm/CodeGen/TargetSubtargetInfo.h"
1314
#include "llvm/IR/AutoUpgrade.h"
1415
#include "llvm/IR/AssemblyAnnotationWriter.h"
@@ -50,6 +51,8 @@
5051

5152
using namespace llvm;
5253

54+
static codegen::RegisterCodeGenFlags CGF;
55+
5356
typedef struct LLVMOpaquePass *LLVMPassRef;
5457
typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
5558

@@ -422,7 +425,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
422425
return nullptr;
423426
}
424427

425-
TargetOptions Options;
428+
TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Trip);
426429

427430
Options.FloatABIType = FloatABI::Default;
428431
if (UseSoftFloat) {

compiler/rustc_mir_transform/src/const_prop_lint.rs

+4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ pub struct ConstProp;
3939

4040
impl<'tcx> MirLint<'tcx> for ConstProp {
4141
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
42+
if body.tainted_by_errors.is_some() {
43+
return;
44+
}
45+
4246
// will be evaluated by miri and produce its errors there
4347
if body.source.promoted.is_some() {
4448
return;

compiler/rustc_privacy/src/lib.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1463,14 +1463,15 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
14631463
};
14641464

14651465
let vis = self.tcx.local_visibility(local_def_id);
1466-
let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id);
14671466
let span = self.tcx.def_span(self.item_def_id.to_def_id());
14681467
let vis_span = self.tcx.def_span(def_id);
14691468
if self.in_assoc_ty && !vis.is_at_least(self.required_visibility, self.tcx) {
14701469
let vis_descr = match vis {
14711470
ty::Visibility::Public => "public",
14721471
ty::Visibility::Restricted(vis_def_id) => {
1473-
if vis_def_id == self.tcx.parent_module(hir_id).to_local_def_id() {
1472+
if vis_def_id
1473+
== self.tcx.parent_module_from_def_id(local_def_id).to_local_def_id()
1474+
{
14741475
"private"
14751476
} else if vis_def_id.is_top_level_module() {
14761477
"crate-private"
@@ -1504,7 +1505,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
15041505
};
15051506
self.tcx.emit_spanned_lint(
15061507
lint,
1507-
hir_id,
1508+
self.tcx.hir().local_def_id_to_hir_id(self.item_def_id),
15081509
span,
15091510
PrivateInterfacesOrBoundsLint {
15101511
item_span: span,

library/core/src/mem/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,11 @@ impl<T> fmt::Debug for Discriminant<T> {
11261126
///
11271127
/// [Reference]: ../../reference/items/enumerations.html#custom-discriminant-values-for-fieldless-enumerations
11281128
///
1129+
/// The value of a [`Discriminant<T>`] is independent of any *lifetimes* in `T`. As such, reading
1130+
/// or writing a `Discriminant<Foo<'a>>` as a `Discriminant<Foo<'b>>` (whether via [`transmute`] or
1131+
/// otherwise) is always sound. Note that this is **not** true for other kinds of generic
1132+
/// parameters; `Discriminant<Foo<A>>` and `Discriminant<Foo<B>>` might be incompatible.
1133+
///
11291134
/// # Examples
11301135
///
11311136
/// This can be used to compare enums that carry data, while disregarding

library/core/src/ptr/mut_ptr.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ impl<T: ?Sized> *mut T {
109109
/// with [`cast_mut`] on `*const T` and may have documentation value if used instead of implicit
110110
/// coercion.
111111
///
112-
/// [`cast_mut`]: #method.cast_mut
112+
/// [`cast_mut`]: pointer::cast_mut
113113
#[stable(feature = "ptr_const_cast", since = "1.65.0")]
114114
#[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")]
115115
#[rustc_diagnostic_item = "ptr_cast_const"]
@@ -121,7 +121,7 @@ impl<T: ?Sized> *mut T {
121121
/// Casts a pointer to its raw bits.
122122
///
123123
/// This is equivalent to `as usize`, but is more specific to enhance readability.
124-
/// The inverse method is [`from_bits`](#method.from_bits-1).
124+
/// The inverse method is [`from_bits`](pointer#method.from_bits-1).
125125
///
126126
/// In particular, `*p as usize` and `p as usize` will both compile for
127127
/// pointers to numeric types but do very different things, so using this
@@ -157,7 +157,7 @@ impl<T: ?Sized> *mut T {
157157
/// Creates a pointer from its raw bits.
158158
///
159159
/// This is equivalent to `as *mut T`, but is more specific to enhance readability.
160-
/// The inverse method is [`to_bits`](#method.to_bits-1).
160+
/// The inverse method is [`to_bits`](pointer#method.to_bits-1).
161161
///
162162
/// # Examples
163163
///
@@ -307,7 +307,7 @@ impl<T: ?Sized> *mut T {
307307
///
308308
/// For the mutable counterpart see [`as_mut`].
309309
///
310-
/// [`as_uninit_ref`]: #method.as_uninit_ref-1
310+
/// [`as_uninit_ref`]: pointer#method.as_uninit_ref-1
311311
/// [`as_mut`]: #method.as_mut
312312
///
313313
/// # Safety
@@ -373,7 +373,7 @@ impl<T: ?Sized> *mut T {
373373
///
374374
/// For the mutable counterpart see [`as_uninit_mut`].
375375
///
376-
/// [`as_ref`]: #method.as_ref-1
376+
/// [`as_ref`]: pointer#method.as_ref-1
377377
/// [`as_uninit_mut`]: #method.as_uninit_mut
378378
///
379379
/// # Safety
@@ -628,7 +628,7 @@ impl<T: ?Sized> *mut T {
628628
/// For the shared counterpart see [`as_ref`].
629629
///
630630
/// [`as_uninit_mut`]: #method.as_uninit_mut
631-
/// [`as_ref`]: #method.as_ref-1
631+
/// [`as_ref`]: pointer#method.as_ref-1
632632
///
633633
/// # Safety
634634
///
@@ -693,7 +693,7 @@ impl<T: ?Sized> *mut T {
693693
/// For the shared counterpart see [`as_uninit_ref`].
694694
///
695695
/// [`as_mut`]: #method.as_mut
696-
/// [`as_uninit_ref`]: #method.as_uninit_ref-1
696+
/// [`as_uninit_ref`]: pointer#method.as_uninit_ref-1
697697
///
698698
/// # Safety
699699
///
@@ -783,7 +783,7 @@ impl<T: ?Sized> *mut T {
783783
///
784784
/// This function is the inverse of [`offset`].
785785
///
786-
/// [`offset`]: #method.offset-1
786+
/// [`offset`]: pointer#method.offset-1
787787
///
788788
/// # Safety
789789
///
@@ -2064,7 +2064,7 @@ impl<T> *mut [T] {
20642064
///
20652065
/// For the mutable counterpart see [`as_uninit_slice_mut`].
20662066
///
2067-
/// [`as_ref`]: #method.as_ref-1
2067+
/// [`as_ref`]: pointer#method.as_ref-1
20682068
/// [`as_uninit_slice_mut`]: #method.as_uninit_slice_mut
20692069
///
20702070
/// # Safety

src/bootstrap/builder.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,10 @@ impl StepDescription {
302302
}
303303
}
304304

305-
fn maybe_run(&self, builder: &Builder<'_>, pathsets: Vec<PathSet>) {
306-
if pathsets.iter().any(|set| self.is_excluded(builder, set)) {
305+
fn maybe_run(&self, builder: &Builder<'_>, mut pathsets: Vec<PathSet>) {
306+
pathsets.retain(|set| !self.is_excluded(builder, set));
307+
308+
if pathsets.is_empty() {
307309
return;
308310
}
309311

src/bootstrap/builder/tests.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,9 @@ fn test_exclude_kind() {
136136
let mut config = configure("test", &["A"], &["A"]);
137137
// Ensure our test is valid, and `test::Rustc` would be run without the exclude.
138138
assert!(run_build(&[], config.clone()).contains::<test::CrateLibrustc>());
139-
// Ensure tests for rustc are skipped.
139+
// Ensure tests for rustc are not skipped.
140140
config.skip = vec![path.clone()];
141-
assert!(!run_build(&[], config.clone()).contains::<test::CrateLibrustc>());
141+
assert!(run_build(&[], config.clone()).contains::<test::CrateLibrustc>());
142142
// Ensure builds for rustc are not skipped.
143143
assert!(run_build(&[], config).contains::<compile::Rustc>());
144144
}

src/ci/docker/host-x86_64/wasm32/Dockerfile

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,6 @@ ENV NO_CHANGE_USER=1
5858
RUN chown 10719 -R /emsdk-portable/
5959

6060
# Exclude library/alloc due to OOM in benches.
61+
# FIXME: Fix std tests
6162
ENV SCRIPT python3 ../x.py test --stage 2 --host='' --target $TARGETS \
62-
--skip library/alloc
63+
--skip library/alloc --skip library/std

src/librustdoc/html/render/mod.rs

+43-4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
5454
use rustc_hir::def_id::{DefId, DefIdSet};
5555
use rustc_hir::Mutability;
5656
use rustc_middle::middle::stability;
57+
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
5758
use rustc_middle::ty::TyCtxt;
5859
use rustc_span::{
5960
symbol::{sym, Symbol},
@@ -62,6 +63,7 @@ use rustc_span::{
6263
use serde::ser::{SerializeMap, SerializeSeq};
6364
use serde::{Serialize, Serializer};
6465

66+
use crate::clean::types::TypeAliasItem;
6567
use crate::clean::{self, ItemId, RenderedLink, SelfTy};
6668
use crate::error::Error;
6769
use crate::formats::cache::Cache;
@@ -1139,8 +1141,40 @@ fn render_assoc_items_inner(
11391141
info!("Documenting associated items of {:?}", containing_item.name);
11401142
let shared = Rc::clone(&cx.shared);
11411143
let cache = &shared.cache;
1142-
let Some(v) = cache.impls.get(&it) else { return };
1143-
let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none());
1144+
let tcx = cx.tcx();
1145+
let av = if let TypeAliasItem(ait) = &*containing_item.kind &&
1146+
let aliased_clean_type = ait.item_type.as_ref().unwrap_or(&ait.type_) &&
1147+
let Some(aliased_type_defid) = aliased_clean_type.def_id(cache) &&
1148+
let Some(mut av) = cache.impls.get(&aliased_type_defid).cloned() &&
1149+
let Some(alias_def_id) = containing_item.item_id.as_def_id()
1150+
{
1151+
// This branch of the compiler compares types structually, but does
1152+
// not check trait bounds. That's probably fine, since type aliases
1153+
// don't normally constrain on them anyway.
1154+
// https://github.com/rust-lang/rust/issues/21903
1155+
//
1156+
// FIXME(lazy_type_alias): Once the feature is complete or stable, rewrite this to use type unification.
1157+
// Be aware of `tests/rustdoc/issue-112515-impl-ty-alias.rs` which might regress.
1158+
let aliased_ty = tcx.type_of(alias_def_id).skip_binder();
1159+
let reject_cx = DeepRejectCtxt {
1160+
treat_obligation_params: TreatParams::AsCandidateKey,
1161+
};
1162+
av.retain(|impl_| {
1163+
if let Some(impl_def_id) = impl_.impl_item.item_id.as_def_id() {
1164+
reject_cx.types_may_unify(aliased_ty, tcx.type_of(impl_def_id).skip_binder())
1165+
} else {
1166+
false
1167+
}
1168+
});
1169+
av
1170+
} else {
1171+
Vec::new()
1172+
};
1173+
let blank = Vec::new();
1174+
let v = cache.impls.get(&it).unwrap_or(&blank);
1175+
let (non_trait, traits): (Vec<_>, _) =
1176+
v.iter().chain(&av[..]).partition(|i| i.inner_impl().trait_.is_none());
1177+
let mut saw_impls = FxHashSet::default();
11441178
if !non_trait.is_empty() {
11451179
let mut tmp_buf = Buffer::html();
11461180
let (render_mode, id, class_html) = match what {
@@ -1169,6 +1203,9 @@ fn render_assoc_items_inner(
11691203
};
11701204
let mut impls_buf = Buffer::html();
11711205
for i in &non_trait {
1206+
if !saw_impls.insert(i.def_id()) {
1207+
continue;
1208+
}
11721209
render_impl(
11731210
&mut impls_buf,
11741211
cx,
@@ -1214,8 +1251,10 @@ fn render_assoc_items_inner(
12141251

12151252
let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) =
12161253
traits.into_iter().partition(|t| t.inner_impl().kind.is_auto());
1217-
let (blanket_impl, concrete): (Vec<&Impl>, _) =
1218-
concrete.into_iter().partition(|t| t.inner_impl().kind.is_blanket());
1254+
let (blanket_impl, concrete): (Vec<&Impl>, _) = concrete
1255+
.into_iter()
1256+
.filter(|t| saw_impls.insert(t.def_id()))
1257+
.partition(|t| t.inner_impl().kind.is_blanket());
12191258

12201259
render_all_impls(w, cx, containing_item, &concrete, &synthetic, &blanket_impl);
12211260
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Regression test for <https://github.com/rust-lang/rust/issues/32077>.
2+
3+
#![crate_name = "foo"]
4+
5+
pub struct GenericStruct<T>(T);
6+
7+
impl<T> GenericStruct<T> {
8+
pub fn on_gen(arg: T) {}
9+
}
10+
11+
impl GenericStruct<u32> {
12+
pub fn on_u32(arg: u32) {}
13+
}
14+
15+
pub trait Foo {}
16+
pub trait Bar {}
17+
18+
impl<T> Foo for GenericStruct<T> {}
19+
impl Bar for GenericStruct<u32> {}
20+
21+
// @has 'foo/type.TypedefStruct.html'
22+
// We check that we have the implementation of the type alias itself.
23+
// @has - '//*[@id="impl-TypedefStruct"]/h3' 'impl TypedefStruct'
24+
// @has - '//*[@id="method.on_alias"]/h4' 'pub fn on_alias()'
25+
// @has - '//*[@id="impl-GenericStruct%3CT%3E"]/h3' 'impl<T> GenericStruct<T>'
26+
// @has - '//*[@id="method.on_gen"]/h4' 'pub fn on_gen(arg: T)'
27+
// @has - '//*[@id="impl-Foo-for-GenericStruct%3CT%3E"]/h3' 'impl<T> Foo for GenericStruct<T>'
28+
// This trait implementation doesn't match the type alias parameters so shouldn't appear in docs.
29+
// @!has - '//h3' 'impl Bar for GenericStruct<u32> {}'
30+
// Same goes for the `Deref` impl.
31+
// @!has - '//h2' 'Methods from Deref<Target = u32>'
32+
pub type TypedefStruct = GenericStruct<u8>;
33+
34+
impl TypedefStruct {
35+
pub fn on_alias() {}
36+
}
37+
38+
impl std::ops::Deref for GenericStruct<u32> {
39+
type Target = u32;
40+
41+
fn deref(&self) -> &Self::Target {
42+
&self.0
43+
}
44+
}
45+
46+
pub struct Wrap<T>(GenericStruct<T>);
47+
48+
// @has 'foo/type.Alias.html'
49+
// @has - '//h2' 'Methods from Deref<Target = u32>'
50+
// @has - '//*[@id="impl-Deref-for-Wrap%3CT%3E"]/h3' 'impl<T> Deref for Wrap<T>'
51+
pub type Alias = Wrap<u32>;
52+
53+
impl<T> std::ops::Deref for Wrap<T> {
54+
type Target = GenericStruct<T>;
55+
56+
fn deref(&self) -> &Self::Target {
57+
&self.0
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// check-pass
2+
// compile-flags: --crate-type=lib
3+
4+
#[allow(private_bounds)]
5+
pub trait Foo: FooImpl {}
6+
7+
trait FooImpl {}

tests/ui/unsized/issue-115203.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// compile-flags: --emit link
2+
3+
fn main() {
4+
let a: [i32; 0] = [];
5+
match [a[..]] {
6+
//~^ ERROR cannot move a value of type `[i32]
7+
//~| ERROR cannot move out of type `[i32]`, a non-copy slice
8+
[[]] => (),
9+
_ => (),
10+
}
11+
}

tests/ui/unsized/issue-115203.stderr

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0161]: cannot move a value of type `[i32]`
2+
--> $DIR/issue-115203.rs:5:12
3+
|
4+
LL | match [a[..]] {
5+
| ^^^^^ the size of `[i32]` cannot be statically determined
6+
7+
error[E0508]: cannot move out of type `[i32]`, a non-copy slice
8+
--> $DIR/issue-115203.rs:5:12
9+
|
10+
LL | match [a[..]] {
11+
| ^^^^^
12+
| |
13+
| cannot move out of here
14+
| move occurs because value has type `[i32]`, which does not implement the `Copy` trait
15+
16+
error: aborting due to 2 previous errors
17+
18+
Some errors have detailed explanations: E0161, E0508.
19+
For more information about an error, try `rustc --explain E0161`.

0 commit comments

Comments
 (0)