Skip to content

Commit 43874a2

Browse files
committed
Auto merge of rust-lang#97742 - matthiaskrgr:rollup-fr3j0t8, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#97609 (Iterate over `maybe_unused_trait_imports` when checking dead trait imports) - rust-lang#97688 (test const_copy to make sure bytewise pointer copies are working) - rust-lang#97707 (Improve soundness of rustc_data_structures) - rust-lang#97731 (Add regresion test for rust-lang#87142) - rust-lang#97735 (Don't generate "Impls on Foreign Types" for std) - rust-lang#97737 (Fix pretty printing named bound regions under -Zverbose) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 4e725ba + 1794309 commit 43874a2

File tree

17 files changed

+162
-77
lines changed

17 files changed

+162
-77
lines changed

compiler/rustc_data_structures/src/base_n/tests.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ fn test_encode() {
1515
test(u64::MAX as u128, base);
1616
test(u128::MAX, base);
1717

18-
for i in 0..1_000 {
18+
const N: u128 = if cfg!(miri) { 10 } else { 1000 };
19+
20+
for i in 0..N {
1921
test(i * 983, base);
2022
}
2123
}

compiler/rustc_data_structures/src/graph/scc/tests.rs

+3
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,10 @@ fn test_deep_linear() {
156156
v
157157
158158
*/
159+
#[cfg(not(miri))]
159160
const NR_NODES: usize = 1 << 14;
161+
#[cfg(miri)]
162+
const NR_NODES: usize = 1 << 3;
160163
let mut nodes = vec![];
161164
for i in 1..NR_NODES {
162165
nodes.push((i - 1, i));

compiler/rustc_data_structures/src/owning_ref/tests.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// FIXME: owning_ref is not sound under stacked borrows. Preferably, get rid of it.
2+
#[cfg(not(miri))]
13
mod owning_ref {
24
use super::super::OwningRef;
35
use super::super::{BoxRef, Erased, ErasedBoxRef, RcRef};
@@ -361,6 +363,8 @@ mod owning_handle {
361363
}
362364
}
363365

366+
// FIXME: owning_ref is not sound under stacked borrows. Preferably, get rid of it.
367+
#[cfg(not(miri))]
364368
mod owning_ref_mut {
365369
use super::super::BoxRef;
366370
use super::super::{BoxRefMut, Erased, ErasedBoxRefMut, OwningRefMut};

compiler/rustc_data_structures/src/sip128.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,9 @@ impl SipHasher128 {
255255
// elements from spill (at most LEN - 1 bytes could have overflowed
256256
// into the spill). The memcpy call is optimized away because the size
257257
// is known. And the whole copy is optimized away for LEN == 1.
258+
let dst = self.buf.as_mut_ptr() as *mut u8;
258259
let src = self.buf.get_unchecked(BUFFER_SPILL_INDEX) as *const _ as *const u8;
259-
ptr::copy_nonoverlapping(src, self.buf.as_mut_ptr() as *mut u8, LEN - 1);
260+
ptr::copy_nonoverlapping(src, dst, LEN - 1);
260261

261262
// This function should only be called when the write fills the buffer.
262263
// Therefore, when LEN == 1, the new `self.nbuf` must be zero.

compiler/rustc_middle/src/query/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1728,8 +1728,8 @@ rustc_queries! {
17281728
query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>> {
17291729
desc { |tcx| "collecting upvars mentioned in `{}`", tcx.def_path_str(def_id) }
17301730
}
1731-
query maybe_unused_trait_import(def_id: LocalDefId) -> bool {
1732-
desc { |tcx| "maybe_unused_trait_import for `{}`", tcx.def_path_str(def_id.to_def_id()) }
1731+
query maybe_unused_trait_imports(_: ()) -> &'tcx FxIndexSet<LocalDefId> {
1732+
desc { "fetching potentially unused trait imports" }
17331733
}
17341734
query maybe_unused_extern_crates(_: ()) -> &'tcx [(LocalDefId, Span)] {
17351735
desc { "looking up all possibly unused extern crates" }

compiler/rustc_middle/src/ty/context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2893,8 +2893,8 @@ pub fn provide(providers: &mut ty::query::Providers) {
28932893
assert_eq!(id, LOCAL_CRATE);
28942894
tcx.crate_name
28952895
};
2896-
providers.maybe_unused_trait_import =
2897-
|tcx, id| tcx.resolutions(()).maybe_unused_trait_imports.contains(&id);
2896+
providers.maybe_unused_trait_imports =
2897+
|tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
28982898
providers.maybe_unused_extern_crates =
28992899
|tcx, ()| &tcx.resolutions(()).maybe_unused_extern_crates[..];
29002900
providers.names_imported_by_glob_use = |tcx, id| {

compiler/rustc_middle/src/ty/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub use generics::*;
2828
use rustc_ast as ast;
2929
use rustc_attr as attr;
3030
use rustc_data_structures::fingerprint::Fingerprint;
31-
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
31+
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
3232
use rustc_data_structures::intern::{Interned, WithStableHash};
3333
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
3434
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
@@ -138,7 +138,7 @@ pub struct ResolverOutputs {
138138
pub has_pub_restricted: bool,
139139
pub access_levels: AccessLevels,
140140
pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
141-
pub maybe_unused_trait_imports: FxHashSet<LocalDefId>,
141+
pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
142142
pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
143143
pub reexport_map: FxHashMap<LocalDefId, Vec<ModChild>>,
144144
pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,

compiler/rustc_middle/src/ty/print/pretty.rs

+30-24
Original file line numberDiff line numberDiff line change
@@ -2190,34 +2190,40 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21902190
// this is not *quite* right and changes the ordering of some output
21912191
// anyways.
21922192
let (new_value, map) = if self.tcx().sess.verbose() {
2193-
// anon index + 1 (BrEnv takes 0) -> name
2194-
let mut region_map: FxHashMap<_, _> = Default::default();
2195-
let bound_vars = value.bound_vars();
2196-
for var in bound_vars {
2197-
let ty::BoundVariableKind::Region(var) = var else { continue };
2198-
match var {
2199-
ty::BrAnon(_) | ty::BrEnv => {
2200-
start_or_continue(&mut self, "for<", ", ");
2201-
let name = next_name(&self);
2202-
do_continue(&mut self, name);
2203-
region_map.insert(var, ty::BrNamed(CRATE_DEF_ID.to_def_id(), name));
2204-
}
2205-
ty::BrNamed(def_id, kw::UnderscoreLifetime) => {
2206-
start_or_continue(&mut self, "for<", ", ");
2207-
let name = next_name(&self);
2208-
do_continue(&mut self, name);
2209-
region_map.insert(var, ty::BrNamed(def_id, name));
2210-
}
2211-
ty::BrNamed(_, name) => {
2212-
start_or_continue(&mut self, "for<", ", ");
2213-
do_continue(&mut self, name);
2193+
let regions: Vec<_> = value
2194+
.bound_vars()
2195+
.into_iter()
2196+
.map(|var| {
2197+
let ty::BoundVariableKind::Region(var) = var else {
2198+
// This doesn't really matter because it doesn't get used,
2199+
// it's just an empty value
2200+
return ty::BrAnon(0);
2201+
};
2202+
match var {
2203+
ty::BrAnon(_) | ty::BrEnv => {
2204+
start_or_continue(&mut self, "for<", ", ");
2205+
let name = next_name(&self);
2206+
do_continue(&mut self, name);
2207+
ty::BrNamed(CRATE_DEF_ID.to_def_id(), name)
2208+
}
2209+
ty::BrNamed(def_id, kw::UnderscoreLifetime) => {
2210+
start_or_continue(&mut self, "for<", ", ");
2211+
let name = next_name(&self);
2212+
do_continue(&mut self, name);
2213+
ty::BrNamed(def_id, name)
2214+
}
2215+
ty::BrNamed(def_id, name) => {
2216+
start_or_continue(&mut self, "for<", ", ");
2217+
do_continue(&mut self, name);
2218+
ty::BrNamed(def_id, name)
2219+
}
22142220
}
2215-
}
2216-
}
2221+
})
2222+
.collect();
22172223
start_or_continue(&mut self, "", "> ");
22182224

22192225
self.tcx.replace_late_bound_regions(value.clone(), |br| {
2220-
let kind = region_map[&br.kind];
2226+
let kind = regions[br.var.as_usize()];
22212227
self.tcx.mk_region(ty::ReLateBound(
22222228
ty::INNERMOST,
22232229
ty::BoundRegion { var: br.var, kind },

compiler/rustc_middle/src/ty/query.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, T
3737
use rustc_ast as ast;
3838
use rustc_ast::expand::allocator::AllocatorKind;
3939
use rustc_attr as attr;
40-
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
40+
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
4141
use rustc_data_structures::steal::Steal;
4242
use rustc_data_structures::svh::Svh;
4343
use rustc_data_structures::sync::Lrc;

compiler/rustc_resolve/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use rustc_ast::node_id::NodeMap;
2828
use rustc_ast::{self as ast, NodeId, CRATE_NODE_ID};
2929
use rustc_ast::{AngleBracketedArg, Crate, Expr, ExprKind, GenericArg, GenericArgs, LitKind, Path};
3030
use rustc_ast_lowering::{LifetimeRes, ResolverAstLowering};
31-
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
31+
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
3232
use rustc_data_structures::intern::Interned;
3333
use rustc_data_structures::sync::Lrc;
3434
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed};
@@ -941,7 +941,7 @@ pub struct Resolver<'a> {
941941
visibilities: FxHashMap<LocalDefId, ty::Visibility>,
942942
has_pub_restricted: bool,
943943
used_imports: FxHashSet<NodeId>,
944-
maybe_unused_trait_imports: FxHashSet<LocalDefId>,
944+
maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
945945
maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
946946

947947
/// Privacy errors are delayed until the end in order to deduplicate them.

compiler/rustc_typeck/src/check_unused.rs

+20-36
Original file line numberDiff line numberDiff line change
@@ -16,48 +16,32 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
1616
used_trait_imports.extend(imports.iter());
1717
}
1818

19-
for id in tcx.hir().items() {
20-
if matches!(tcx.def_kind(id.def_id), DefKind::Use) {
21-
if tcx.visibility(id.def_id).is_public() {
22-
continue;
23-
}
24-
let item = tcx.hir().item(id);
25-
if item.span.is_dummy() {
26-
continue;
27-
}
28-
if let hir::ItemKind::Use(path, _) = item.kind {
29-
check_import(tcx, &mut used_trait_imports, item.item_id(), path.span);
30-
}
19+
for &id in tcx.maybe_unused_trait_imports(()) {
20+
debug_assert_eq!(tcx.def_kind(id), DefKind::Use);
21+
if tcx.visibility(id).is_public() {
22+
continue;
23+
}
24+
if used_trait_imports.contains(&id) {
25+
continue;
3126
}
27+
let item = tcx.hir().expect_item(id);
28+
if item.span.is_dummy() {
29+
continue;
30+
}
31+
let hir::ItemKind::Use(path, _) = item.kind else { unreachable!() };
32+
tcx.struct_span_lint_hir(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, |lint| {
33+
let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) {
34+
format!("unused import: `{}`", snippet)
35+
} else {
36+
"unused import".to_owned()
37+
};
38+
lint.build(&msg).emit();
39+
});
3240
}
3341

3442
unused_crates_lint(tcx);
3543
}
3644

37-
fn check_import<'tcx>(
38-
tcx: TyCtxt<'tcx>,
39-
used_trait_imports: &mut FxHashSet<LocalDefId>,
40-
item_id: hir::ItemId,
41-
span: Span,
42-
) {
43-
if !tcx.maybe_unused_trait_import(item_id.def_id) {
44-
return;
45-
}
46-
47-
if used_trait_imports.contains(&item_id.def_id) {
48-
return;
49-
}
50-
51-
tcx.struct_span_lint_hir(lint::builtin::UNUSED_IMPORTS, item_id.hir_id(), span, |lint| {
52-
let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) {
53-
format!("unused import: `{}`", snippet)
54-
} else {
55-
"unused import".to_owned()
56-
};
57-
lint.build(&msg).emit();
58-
});
59-
}
60-
6145
fn unused_crates_lint(tcx: TyCtxt<'_>) {
6246
let lint = lint::builtin::UNUSED_EXTERN_CRATES;
6347

library/core/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
#![feature(const_option)]
8585
#![feature(const_option_ext)]
8686
#![feature(const_result)]
87+
#![feature(const_intrinsic_copy)]
8788
#![feature(integer_atomics)]
8889
#![feature(int_roundings)]
8990
#![feature(slice_group_by)]

library/core/tests/ptr.rs

+40
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use core::cell::RefCell;
2+
use core::mem::{self, MaybeUninit};
23
use core::num::NonZeroUsize;
34
use core::ptr;
45
use core::ptr::*;
@@ -781,3 +782,42 @@ fn nonnull_tagged_pointer_with_provenance() {
781782
}
782783
}
783784
}
785+
786+
#[test]
787+
fn test_const_copy() {
788+
const {
789+
let ptr1 = &1;
790+
let mut ptr2 = &666;
791+
792+
// Copy ptr1 to ptr2, bytewise.
793+
unsafe {
794+
ptr::copy(
795+
&ptr1 as *const _ as *const MaybeUninit<u8>,
796+
&mut ptr2 as *mut _ as *mut MaybeUninit<u8>,
797+
mem::size_of::<&i32>(),
798+
);
799+
}
800+
801+
// Make sure they still work.
802+
assert!(*ptr1 == 1);
803+
assert!(*ptr2 == 1);
804+
};
805+
806+
const {
807+
let ptr1 = &1;
808+
let mut ptr2 = &666;
809+
810+
// Copy ptr1 to ptr2, bytewise.
811+
unsafe {
812+
ptr::copy_nonoverlapping(
813+
&ptr1 as *const _ as *const MaybeUninit<u8>,
814+
&mut ptr2 as *mut _ as *mut MaybeUninit<u8>,
815+
mem::size_of::<&i32>(),
816+
);
817+
}
818+
819+
// Make sure they still work.
820+
assert!(*ptr1 == 1);
821+
assert!(*ptr2 == 1);
822+
};
823+
}

src/librustdoc/formats/mod.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
77
pub(crate) use renderer::{run_format, FormatRenderer};
88

99
use crate::clean::{self, ItemId};
10-
use cache::Cache;
10+
use crate::html::render::Context;
1111

1212
/// Specifies whether rendering directly implemented trait items or ones from a certain Deref
1313
/// impl.
@@ -65,7 +65,8 @@ impl Impl {
6565
// Returns true if this is an implementation on a "local" type, meaning:
6666
// the type is in the current crate, or the type and the trait are both
6767
// re-exported by the current crate.
68-
pub(crate) fn is_on_local_type(&self, cache: &Cache) -> bool {
68+
pub(crate) fn is_on_local_type(&self, cx: &Context<'_>) -> bool {
69+
let cache = cx.cache();
6970
let for_type = &self.inner_impl().for_;
7071
if let Some(for_type_did) = for_type.def_id(cache) {
7172
// The "for" type is local if it's in the paths for the current crate.
@@ -80,6 +81,18 @@ impl Impl {
8081
if for_type_did.krate == trait_did.krate {
8182
return true;
8283
}
84+
// Hack: many traits and types in std are re-exported from
85+
// core or alloc. In general, rustdoc is capable of recognizing
86+
// these implementations as being on local types. However, in at
87+
// least one case (https://github.com/rust-lang/rust/issues/97610),
88+
// rustdoc gets confused and labels an implementation as being on
89+
// a foreign type. To make sure that confusion doesn't pass on to
90+
// the reader, consider all implementations in std, core, and alloc
91+
// to be on local types.
92+
let crate_name = cx.tcx().crate_name(trait_did.krate);
93+
if matches!(crate_name.as_str(), "std" | "core" | "alloc") {
94+
return true;
95+
}
8396
}
8497
return false;
8598
};

src/librustdoc/html/render/mod.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -2281,11 +2281,10 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
22812281
|sym| format!("<a href=\"#{1}.{0}\">{0}</a>", sym, ItemType::Method),
22822282
);
22832283

2284-
let cache = cx.cache();
2285-
if let Some(implementors) = cache.implementors.get(&it.item_id.expect_def_id()) {
2284+
if let Some(implementors) = cx.cache().implementors.get(&it.item_id.expect_def_id()) {
22862285
let mut res = implementors
22872286
.iter()
2288-
.filter(|i| !i.is_on_local_type(cache))
2287+
.filter(|i| !i.is_on_local_type(cx))
22892288
.filter_map(|i| extract_for_impl_name(&i.impl_item, cx))
22902289
.collect::<Vec<_>>();
22912290

src/librustdoc/html/render/print_item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
823823
}
824824

825825
let (local, foreign) =
826-
implementors.iter().partition::<Vec<_>, _>(|i| i.is_on_local_type(cache));
826+
implementors.iter().partition::<Vec<_>, _>(|i| i.is_on_local_type(cx));
827827

828828
let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) =
829829
local.iter().partition(|i| i.inner_impl().kind.is_auto());

src/test/ui/generator/issue-87142.rs

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// compile-flags: -Cdebuginfo=2
2+
// build-pass
3+
4+
// Regression test for #87142
5+
// This test needs the above flags and the "lib" crate type.
6+
7+
#![feature(type_alias_impl_trait, generator_trait, generators)]
8+
#![crate_type = "lib"]
9+
10+
use std::ops::Generator;
11+
12+
pub trait GeneratorProviderAlt: Sized {
13+
type Gen: Generator<(), Return = (), Yield = ()>;
14+
15+
fn start(ctx: Context<Self>) -> Self::Gen;
16+
}
17+
18+
pub struct Context<G: 'static + GeneratorProviderAlt> {
19+
pub link: Box<G::Gen>,
20+
}
21+
22+
impl GeneratorProviderAlt for () {
23+
type Gen = impl Generator<(), Return = (), Yield = ()>;
24+
fn start(ctx: Context<Self>) -> Self::Gen {
25+
move || {
26+
match ctx {
27+
_ => (),
28+
}
29+
yield ();
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)