Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #113458

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion compiler/rustc_const_eval/src/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -700,8 +700,13 @@ where
assert_eq!(src.layout.size, dest.layout.size);
}

// Setting `nonoverlapping` here only has an effect when we don't hit the fast-path above,
// but that should at least match what LLVM does where `memcpy` is also only used when the
// type does not have Scalar/ScalarPair layout.
// (Or as the `Assign` docs put it, assignments "not producing primitives" must be
// non-overlapping.)
self.mem_copy(
src.ptr, src.align, dest.ptr, dest.align, dest_size, /*nonoverlapping*/ false,
src.ptr, src.align, dest.ptr, dest.align, dest_size, /*nonoverlapping*/ true,
)
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut pat_ty = ty;
if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::ByteStr(..), .. }) = lt.kind {
let expected = self.structurally_resolve_type(span, expected);
if let ty::Ref(_, inner_ty, _) = expected.kind()
&& matches!(inner_ty.kind(), ty::Slice(_))
if let ty::Ref(_, inner_ty, _) = *expected.kind()
&& self.try_structurally_resolve_type(span, inner_ty).is_slice()
{
let tcx = self.tcx;
trace!(?lt.hir_id.local_id, "polymorphic byte string lit");
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_trait_selection/src/solve/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
// We don't normalize opaque types unless we have
// `Reveal::All`, even if we're in the defining scope.
let data = match *ty.kind() {
ty::Alias(kind, alias_ty) if kind != ty::Opaque || reveal == Reveal::UserFacing => {
alias_ty
}
ty::Alias(kind, alias_ty) if kind != ty::Opaque || reveal == Reveal::All => alias_ty,
_ => return ty.try_super_fold_with(self),
};

Expand Down
100 changes: 97 additions & 3 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1479,8 +1479,97 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name), kind, cx)
}

/// The goal of this function is to return the first `Path` which is not private (ie not private
/// or `doc(hidden)`). If it's not possible, it'll return the "end type".
///
/// If the path is not a re-export or is public, it'll return `None`.
fn first_non_private(
cx: &mut DocContext<'_>,
hir_id: hir::HirId,
path: &hir::Path<'_>,
) -> Option<Path> {
let (parent_def_id, mut ident) = match &path.segments[..] {
[] => return None,
// Relative paths are available in the same scope as the owner.
[leaf] => (cx.tcx.local_parent(hir_id.owner.def_id), leaf.ident),
// So are self paths.
[parent, leaf] if parent.ident.name == kw::SelfLower => {
(cx.tcx.local_parent(hir_id.owner.def_id), leaf.ident)
}
// Crate paths are not. We start from the crate root.
[parent, leaf] if matches!(parent.ident.name, kw::Crate | kw::PathRoot) => {
(LOCAL_CRATE.as_def_id().as_local()?, leaf.ident)
}
[parent, leaf] if parent.ident.name == kw::Super => {
let parent_mod = cx.tcx.parent_module(hir_id);
if let Some(super_parent) = cx.tcx.opt_local_parent(parent_mod) {
(super_parent, leaf.ident)
} else {
// If we can't find the parent of the parent, then the parent is already the crate.
(LOCAL_CRATE.as_def_id().as_local()?, leaf.ident)
}
}
// Absolute paths are not. We start from the parent of the item.
[.., parent, leaf] => (parent.res.opt_def_id()?.as_local()?, leaf.ident),
};
let target_def_id = path.res.opt_def_id()?;
// First we try to get the `DefId` of the item.
for child in
cx.tcx.module_children_local(parent_def_id).iter().filter(move |c| c.ident == ident)
{
if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = child.res {
continue;
}

if let Some(def_id) = child.res.opt_def_id() && target_def_id == def_id {
let mut last_path_res = None;
'reexps: for reexp in child.reexport_chain.iter() {
if let Some(use_def_id) = reexp.id() &&
let Some(local_use_def_id) = use_def_id.as_local()
{
let hir = cx.tcx.hir();
for item_id in hir.module_items(cx.tcx.local_parent(local_use_def_id)) {
let item = hir.item(item_id);
if item.ident == ident && let hir::ItemKind::Use(path, _) = item.kind {
for res in &path.res {
if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res {
continue;
}
if !cx.tcx.is_doc_hidden(use_def_id) &&
cx.tcx.local_visibility(local_use_def_id).is_public() {
break 'reexps;
}
ident = path.segments.last().unwrap().ident;
last_path_res = Some((path, res));
continue 'reexps;
}
}
}
}
}
if !child.reexport_chain.is_empty() {
// So in here, we use the data we gathered from iterating the reexports. If
// `last_path_res` is set, it can mean two things:
//
// 1. We found a public reexport.
// 2. We didn't find a public reexport so it's the "end type" path.
if let Some((path, res)) = last_path_res {
let path = hir::Path { segments: path.segments, res: *res, span: path.span };
return Some(clean_path(&path, cx));
}
// If `last_path_res` is `None`, it can mean two things:
//
// 1. The re-export is public, no need to change anything, just use the path as is.
// 2. Nothing was found, so let's just return the original path.
return None;
}
}
}
None
}

fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type {
let hir::Ty { hir_id: _, span, ref kind } = *hir_ty;
let hir::Ty { hir_id, span, ref kind } = *hir_ty;
let hir::TyKind::Path(qpath) = kind else { unreachable!() };

match qpath {
Expand All @@ -1497,7 +1586,12 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
if let Some(expanded) = maybe_expand_private_type_alias(cx, path) {
expanded
} else {
let path = clean_path(path, cx);
// First we check if it's a private re-export.
let path = if let Some(path) = first_non_private(cx, hir_id, &path) {
path
} else {
clean_path(path, cx)
};
resolve_type(cx, path)
}
}
Expand Down Expand Up @@ -1649,7 +1743,7 @@ fn maybe_expand_private_type_alias<'tcx>(
}
}

Some(cx.enter_alias(substs, def_id.to_def_id(), |cx| clean_ty(ty, cx)))
Some(cx.enter_alias(substs, def_id.to_def_id(), |cx| clean_ty(&ty, cx)))
}

pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_lints/src/incorrect_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl LateLintPass<'_> for IncorrectImpls {
cx,
hir_ty_to_ty(cx.tcx, imp.self_ty),
copy_def_id,
trait_impl.substs,
&[],
)
{
if impl_item.ident.name == sym::clone {
Expand Down
7 changes: 4 additions & 3 deletions src/tools/clippy/tests/ui/needless_raw_string.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ fn main() {
b"aaa";
br#""aaa""#;
br#"\s"#;
c"aaa";
cr#""aaa""#;
cr#"\s"#;
// currently disabled: https://github.com/rust-lang/rust/issues/113333
// cr#"aaa"#;
// cr#""aaa""#;
// cr#"\s"#;
}
7 changes: 4 additions & 3 deletions src/tools/clippy/tests/ui/needless_raw_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ fn main() {
br#"aaa"#;
br#""aaa""#;
br#"\s"#;
cr#"aaa"#;
cr#""aaa""#;
cr#"\s"#;
// currently disabled: https://github.com/rust-lang/rust/issues/113333
// cr#"aaa"#;
// cr#""aaa""#;
// cr#"\s"#;
}
8 changes: 1 addition & 7 deletions src/tools/clippy/tests/ui/needless_raw_string.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,5 @@ error: unnecessary raw string literal
LL | br#"aaa"#;
| ^^^^^^^^^ help: try: `b"aaa"`

error: unnecessary raw string literal
--> $DIR/needless_raw_string.rs:13:5
|
LL | cr#"aaa"#;
| ^^^^^^^^^ help: try: `c"aaa"`

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

9 changes: 5 additions & 4 deletions src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ fn main() {
br#"Hello "world"!"#;
br####" "### "## "# "####;
br###" "aa" "# "## "###;
cr#"aaa"#;
cr#"Hello "world"!"#;
cr####" "### "## "# "####;
cr###" "aa" "# "## "###;
// currently disabled: https://github.com/rust-lang/rust/issues/113333
// cr#"aaa"#;
// cr##"Hello "world"!"##;
// cr######" "### "## "# "######;
// cr######" "aa" "# "## "######;
}
9 changes: 5 additions & 4 deletions src/tools/clippy/tests/ui/needless_raw_string_hashes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ fn main() {
br##"Hello "world"!"##;
br######" "### "## "# "######;
br######" "aa" "# "## "######;
cr#"aaa"#;
cr##"Hello "world"!"##;
cr######" "### "## "# "######;
cr######" "aa" "# "## "######;
// currently disabled: https://github.com/rust-lang/rust/issues/113333
// cr#"aaa"#;
// cr##"Hello "world"!"##;
// cr######" "### "## "# "######;
// cr######" "aa" "# "## "######;
}
20 changes: 1 addition & 19 deletions src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,5 @@ error: unnecessary hashes around raw string literal
LL | br######" "aa" "# "## "######;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `br###" "aa" "# "## "###`

error: unnecessary hashes around raw string literal
--> $DIR/needless_raw_string_hashes.rs:16:5
|
LL | cr##"Hello "world"!"##;
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `cr#"Hello "world"!"#`

error: unnecessary hashes around raw string literal
--> $DIR/needless_raw_string_hashes.rs:17:5
|
LL | cr######" "### "## "# "######;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cr####" "### "## "# "####`

error: unnecessary hashes around raw string literal
--> $DIR/needless_raw_string_hashes.rs:18:5
|
LL | cr######" "aa" "# "## "######;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cr###" "aa" "# "## "###`

error: aborting due to 9 previous errors
error: aborting due to 6 previous errors

23 changes: 23 additions & 0 deletions src/tools/miri/tests/fail/overlapping_assignment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#![feature(core_intrinsics)]
#![feature(custom_mir)]

use std::intrinsics::mir::*;

// It's not that easy to fool the MIR validity check
// which wants to prevent overlapping assignments...
// So we use two separate pointer arguments, and then arrange for them to alias.
#[custom_mir(dialect = "runtime", phase = "optimized")]
pub fn self_copy(ptr1: *mut [i32; 4], ptr2: *mut [i32; 4]) {
mir! {
{
*ptr1 = *ptr2; //~ERROR: overlapping ranges
Return()
}
}
}

pub fn main() {
let mut x = [0; 4];
let ptr = std::ptr::addr_of_mut!(x);
self_copy(ptr, ptr);
}
20 changes: 20 additions & 0 deletions src/tools/miri/tests/fail/overlapping_assignment.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error: Undefined Behavior: `copy_nonoverlapping` called on overlapping ranges
--> $DIR/overlapping_assignment.rs:LL:CC
|
LL | *ptr1 = *ptr2;
| ^^^^^^^^^^^^^ `copy_nonoverlapping` called on overlapping ranges
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `self_copy` at $DIR/overlapping_assignment.rs:LL:CC
note: inside `main`
--> $DIR/overlapping_assignment.rs:LL:CC
|
LL | self_copy(ptr, ptr);
| ^^^^^^^^^^^^^^^^^^^

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to previous error

13 changes: 13 additions & 0 deletions tests/rustdoc/issue-81141-private-reexport-in-public-api-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// edition:2015

#![crate_name = "foo"]

use external::Public as Private;

pub mod external {
pub struct Public;

// @has 'foo/external/fn.make.html'
// @has - '//*[@class="rust item-decl"]/code' 'pub fn make() -> Public'
pub fn make() -> ::Private { super::Private }
}
Loading