Skip to content
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