Skip to content

Commit

Permalink
Auto merge of rust-lang#97742 - matthiaskrgr:rollup-fr3j0t8, r=matthi…
Browse files Browse the repository at this point in the history
…askrgr

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
  • Loading branch information
bors committed Jun 4, 2022
2 parents 4e725ba + 1794309 commit 43874a2
Show file tree
Hide file tree
Showing 17 changed files with 162 additions and 77 deletions.
4 changes: 3 additions & 1 deletion compiler/rustc_data_structures/src/base_n/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ fn test_encode() {
test(u64::MAX as u128, base);
test(u128::MAX, base);

for i in 0..1_000 {
const N: u128 = if cfg!(miri) { 10 } else { 1000 };

for i in 0..N {
test(i * 983, base);
}
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_data_structures/src/graph/scc/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,10 @@ fn test_deep_linear() {
v
*/
#[cfg(not(miri))]
const NR_NODES: usize = 1 << 14;
#[cfg(miri)]
const NR_NODES: usize = 1 << 3;
let mut nodes = vec![];
for i in 1..NR_NODES {
nodes.push((i - 1, i));
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_data_structures/src/owning_ref/tests.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// FIXME: owning_ref is not sound under stacked borrows. Preferably, get rid of it.
#[cfg(not(miri))]
mod owning_ref {
use super::super::OwningRef;
use super::super::{BoxRef, Erased, ErasedBoxRef, RcRef};
Expand Down Expand Up @@ -361,6 +363,8 @@ mod owning_handle {
}
}

// FIXME: owning_ref is not sound under stacked borrows. Preferably, get rid of it.
#[cfg(not(miri))]
mod owning_ref_mut {
use super::super::BoxRef;
use super::super::{BoxRefMut, Erased, ErasedBoxRefMut, OwningRefMut};
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_data_structures/src/sip128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,9 @@ impl SipHasher128 {
// elements from spill (at most LEN - 1 bytes could have overflowed
// into the spill). The memcpy call is optimized away because the size
// is known. And the whole copy is optimized away for LEN == 1.
let dst = self.buf.as_mut_ptr() as *mut u8;
let src = self.buf.get_unchecked(BUFFER_SPILL_INDEX) as *const _ as *const u8;
ptr::copy_nonoverlapping(src, self.buf.as_mut_ptr() as *mut u8, LEN - 1);
ptr::copy_nonoverlapping(src, dst, LEN - 1);

// This function should only be called when the write fills the buffer.
// Therefore, when LEN == 1, the new `self.nbuf` must be zero.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1728,8 +1728,8 @@ rustc_queries! {
query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>> {
desc { |tcx| "collecting upvars mentioned in `{}`", tcx.def_path_str(def_id) }
}
query maybe_unused_trait_import(def_id: LocalDefId) -> bool {
desc { |tcx| "maybe_unused_trait_import for `{}`", tcx.def_path_str(def_id.to_def_id()) }
query maybe_unused_trait_imports(_: ()) -> &'tcx FxIndexSet<LocalDefId> {
desc { "fetching potentially unused trait imports" }
}
query maybe_unused_extern_crates(_: ()) -> &'tcx [(LocalDefId, Span)] {
desc { "looking up all possibly unused extern crates" }
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2893,8 +2893,8 @@ pub fn provide(providers: &mut ty::query::Providers) {
assert_eq!(id, LOCAL_CRATE);
tcx.crate_name
};
providers.maybe_unused_trait_import =
|tcx, id| tcx.resolutions(()).maybe_unused_trait_imports.contains(&id);
providers.maybe_unused_trait_imports =
|tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
providers.maybe_unused_extern_crates =
|tcx, ()| &tcx.resolutions(()).maybe_unused_extern_crates[..];
providers.names_imported_by_glob_use = |tcx, id| {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub use generics::*;
use rustc_ast as ast;
use rustc_attr as attr;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::intern::{Interned, WithStableHash};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
Expand Down Expand Up @@ -138,7 +138,7 @@ pub struct ResolverOutputs {
pub has_pub_restricted: bool,
pub access_levels: AccessLevels,
pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
pub maybe_unused_trait_imports: FxHashSet<LocalDefId>,
pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
pub reexport_map: FxHashMap<LocalDefId, Vec<ModChild>>,
pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
Expand Down
54 changes: 30 additions & 24 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2190,34 +2190,40 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
// this is not *quite* right and changes the ordering of some output
// anyways.
let (new_value, map) = if self.tcx().sess.verbose() {
// anon index + 1 (BrEnv takes 0) -> name
let mut region_map: FxHashMap<_, _> = Default::default();
let bound_vars = value.bound_vars();
for var in bound_vars {
let ty::BoundVariableKind::Region(var) = var else { continue };
match var {
ty::BrAnon(_) | ty::BrEnv => {
start_or_continue(&mut self, "for<", ", ");
let name = next_name(&self);
do_continue(&mut self, name);
region_map.insert(var, ty::BrNamed(CRATE_DEF_ID.to_def_id(), name));
}
ty::BrNamed(def_id, kw::UnderscoreLifetime) => {
start_or_continue(&mut self, "for<", ", ");
let name = next_name(&self);
do_continue(&mut self, name);
region_map.insert(var, ty::BrNamed(def_id, name));
}
ty::BrNamed(_, name) => {
start_or_continue(&mut self, "for<", ", ");
do_continue(&mut self, name);
let regions: Vec<_> = value
.bound_vars()
.into_iter()
.map(|var| {
let ty::BoundVariableKind::Region(var) = var else {
// This doesn't really matter because it doesn't get used,
// it's just an empty value
return ty::BrAnon(0);
};
match var {
ty::BrAnon(_) | ty::BrEnv => {
start_or_continue(&mut self, "for<", ", ");
let name = next_name(&self);
do_continue(&mut self, name);
ty::BrNamed(CRATE_DEF_ID.to_def_id(), name)
}
ty::BrNamed(def_id, kw::UnderscoreLifetime) => {
start_or_continue(&mut self, "for<", ", ");
let name = next_name(&self);
do_continue(&mut self, name);
ty::BrNamed(def_id, name)
}
ty::BrNamed(def_id, name) => {
start_or_continue(&mut self, "for<", ", ");
do_continue(&mut self, name);
ty::BrNamed(def_id, name)
}
}
}
}
})
.collect();
start_or_continue(&mut self, "", "> ");

self.tcx.replace_late_bound_regions(value.clone(), |br| {
let kind = region_map[&br.kind];
let kind = regions[br.var.as_usize()];
self.tcx.mk_region(ty::ReLateBound(
ty::INNERMOST,
ty::BoundRegion { var: br.var, kind },
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, T
use rustc_ast as ast;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::steal::Steal;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::Lrc;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use rustc_ast::node_id::NodeMap;
use rustc_ast::{self as ast, NodeId, CRATE_NODE_ID};
use rustc_ast::{AngleBracketedArg, Crate, Expr, ExprKind, GenericArg, GenericArgs, LitKind, Path};
use rustc_ast_lowering::{LifetimeRes, ResolverAstLowering};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::intern::Interned;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed};
Expand Down Expand Up @@ -941,7 +941,7 @@ pub struct Resolver<'a> {
visibilities: FxHashMap<LocalDefId, ty::Visibility>,
has_pub_restricted: bool,
used_imports: FxHashSet<NodeId>,
maybe_unused_trait_imports: FxHashSet<LocalDefId>,
maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,

/// Privacy errors are delayed until the end in order to deduplicate them.
Expand Down
56 changes: 20 additions & 36 deletions compiler/rustc_typeck/src/check_unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,48 +16,32 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
used_trait_imports.extend(imports.iter());
}

for id in tcx.hir().items() {
if matches!(tcx.def_kind(id.def_id), DefKind::Use) {
if tcx.visibility(id.def_id).is_public() {
continue;
}
let item = tcx.hir().item(id);
if item.span.is_dummy() {
continue;
}
if let hir::ItemKind::Use(path, _) = item.kind {
check_import(tcx, &mut used_trait_imports, item.item_id(), path.span);
}
for &id in tcx.maybe_unused_trait_imports(()) {
debug_assert_eq!(tcx.def_kind(id), DefKind::Use);
if tcx.visibility(id).is_public() {
continue;
}
if used_trait_imports.contains(&id) {
continue;
}
let item = tcx.hir().expect_item(id);
if item.span.is_dummy() {
continue;
}
let hir::ItemKind::Use(path, _) = item.kind else { unreachable!() };
tcx.struct_span_lint_hir(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, |lint| {
let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) {
format!("unused import: `{}`", snippet)
} else {
"unused import".to_owned()
};
lint.build(&msg).emit();
});
}

unused_crates_lint(tcx);
}

fn check_import<'tcx>(
tcx: TyCtxt<'tcx>,
used_trait_imports: &mut FxHashSet<LocalDefId>,
item_id: hir::ItemId,
span: Span,
) {
if !tcx.maybe_unused_trait_import(item_id.def_id) {
return;
}

if used_trait_imports.contains(&item_id.def_id) {
return;
}

tcx.struct_span_lint_hir(lint::builtin::UNUSED_IMPORTS, item_id.hir_id(), span, |lint| {
let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) {
format!("unused import: `{}`", snippet)
} else {
"unused import".to_owned()
};
lint.build(&msg).emit();
});
}

fn unused_crates_lint(tcx: TyCtxt<'_>) {
let lint = lint::builtin::UNUSED_EXTERN_CRATES;

Expand Down
1 change: 1 addition & 0 deletions library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
#![feature(const_option)]
#![feature(const_option_ext)]
#![feature(const_result)]
#![feature(const_intrinsic_copy)]
#![feature(integer_atomics)]
#![feature(int_roundings)]
#![feature(slice_group_by)]
Expand Down
40 changes: 40 additions & 0 deletions library/core/tests/ptr.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use core::cell::RefCell;
use core::mem::{self, MaybeUninit};
use core::num::NonZeroUsize;
use core::ptr;
use core::ptr::*;
Expand Down Expand Up @@ -781,3 +782,42 @@ fn nonnull_tagged_pointer_with_provenance() {
}
}
}

#[test]
fn test_const_copy() {
const {
let ptr1 = &1;
let mut ptr2 = &666;

// Copy ptr1 to ptr2, bytewise.
unsafe {
ptr::copy(
&ptr1 as *const _ as *const MaybeUninit<u8>,
&mut ptr2 as *mut _ as *mut MaybeUninit<u8>,
mem::size_of::<&i32>(),
);
}

// Make sure they still work.
assert!(*ptr1 == 1);
assert!(*ptr2 == 1);
};

const {
let ptr1 = &1;
let mut ptr2 = &666;

// Copy ptr1 to ptr2, bytewise.
unsafe {
ptr::copy_nonoverlapping(
&ptr1 as *const _ as *const MaybeUninit<u8>,
&mut ptr2 as *mut _ as *mut MaybeUninit<u8>,
mem::size_of::<&i32>(),
);
}

// Make sure they still work.
assert!(*ptr1 == 1);
assert!(*ptr2 == 1);
};
}
17 changes: 15 additions & 2 deletions src/librustdoc/formats/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
pub(crate) use renderer::{run_format, FormatRenderer};

use crate::clean::{self, ItemId};
use cache::Cache;
use crate::html::render::Context;

/// Specifies whether rendering directly implemented trait items or ones from a certain Deref
/// impl.
Expand Down Expand Up @@ -65,7 +65,8 @@ impl Impl {
// Returns true if this is an implementation on a "local" type, meaning:
// the type is in the current crate, or the type and the trait are both
// re-exported by the current crate.
pub(crate) fn is_on_local_type(&self, cache: &Cache) -> bool {
pub(crate) fn is_on_local_type(&self, cx: &Context<'_>) -> bool {
let cache = cx.cache();
let for_type = &self.inner_impl().for_;
if let Some(for_type_did) = for_type.def_id(cache) {
// The "for" type is local if it's in the paths for the current crate.
Expand All @@ -80,6 +81,18 @@ impl Impl {
if for_type_did.krate == trait_did.krate {
return true;
}
// Hack: many traits and types in std are re-exported from
// core or alloc. In general, rustdoc is capable of recognizing
// these implementations as being on local types. However, in at
// least one case (https://github.com/rust-lang/rust/issues/97610),
// rustdoc gets confused and labels an implementation as being on
// a foreign type. To make sure that confusion doesn't pass on to
// the reader, consider all implementations in std, core, and alloc
// to be on local types.
let crate_name = cx.tcx().crate_name(trait_did.krate);
if matches!(crate_name.as_str(), "std" | "core" | "alloc") {
return true;
}
}
return false;
};
Expand Down
5 changes: 2 additions & 3 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2281,11 +2281,10 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
|sym| format!("<a href=\"#{1}.{0}\">{0}</a>", sym, ItemType::Method),
);

let cache = cx.cache();
if let Some(implementors) = cache.implementors.get(&it.item_id.expect_def_id()) {
if let Some(implementors) = cx.cache().implementors.get(&it.item_id.expect_def_id()) {
let mut res = implementors
.iter()
.filter(|i| !i.is_on_local_type(cache))
.filter(|i| !i.is_on_local_type(cx))
.filter_map(|i| extract_for_impl_name(&i.impl_item, cx))
.collect::<Vec<_>>();

Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
}

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

let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) =
local.iter().partition(|i| i.inner_impl().kind.is_auto());
Expand Down
32 changes: 32 additions & 0 deletions src/test/ui/generator/issue-87142.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// compile-flags: -Cdebuginfo=2
// build-pass

// Regression test for #87142
// This test needs the above flags and the "lib" crate type.

#![feature(type_alias_impl_trait, generator_trait, generators)]
#![crate_type = "lib"]

use std::ops::Generator;

pub trait GeneratorProviderAlt: Sized {
type Gen: Generator<(), Return = (), Yield = ()>;

fn start(ctx: Context<Self>) -> Self::Gen;
}

pub struct Context<G: 'static + GeneratorProviderAlt> {
pub link: Box<G::Gen>,
}

impl GeneratorProviderAlt for () {
type Gen = impl Generator<(), Return = (), Yield = ()>;
fn start(ctx: Context<Self>) -> Self::Gen {
move || {
match ctx {
_ => (),
}
yield ();
}
}
}

0 comments on commit 43874a2

Please sign in to comment.