From 906d2b172c936674b8fbf727c556e5b41df86ef1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 6 Jul 2023 05:39:39 +0000 Subject: [PATCH 01/12] Structurally normalize again for byte string lit pat checking --- compiler/rustc_hir_typeck/src/pat.rs | 4 ++-- tests/ui/traits/new-solver/slice-match-byte-lit.rs | 2 +- .../ui/traits/new-solver/slice-match-byte-lit.stderr | 11 ----------- 3 files changed, 3 insertions(+), 14 deletions(-) delete mode 100644 tests/ui/traits/new-solver/slice-match-byte-lit.stderr diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 96d03b471252f..275e35d4ba538 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -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"); diff --git a/tests/ui/traits/new-solver/slice-match-byte-lit.rs b/tests/ui/traits/new-solver/slice-match-byte-lit.rs index 5f9c0df645036..4f848062595da 100644 --- a/tests/ui/traits/new-solver/slice-match-byte-lit.rs +++ b/tests/ui/traits/new-solver/slice-match-byte-lit.rs @@ -1,5 +1,5 @@ // compile-flags: -Ztrait-solver=next -// known-bug: rust-lang/trait-system-refactor-initiative#38 +// check-pass fn test(s: &[u8]) { match &s[0..3] { diff --git a/tests/ui/traits/new-solver/slice-match-byte-lit.stderr b/tests/ui/traits/new-solver/slice-match-byte-lit.stderr deleted file mode 100644 index cd48a6d184339..0000000000000 --- a/tests/ui/traits/new-solver/slice-match-byte-lit.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0271]: type mismatch resolving `[u8; 3] <: <[u8] as Index>>::Output` - --> $DIR/slice-match-byte-lit.rs:6:9 - | -LL | match &s[0..3] { - | -------- this expression has type `&<[u8] as Index>>::Output` -LL | b"uwu" => {} - | ^^^^^^ types differ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0271`. From 7a83ef82da92d81be83d430602778f4f4c8fb439 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 7 Jul 2023 16:54:44 +0200 Subject: [PATCH 02/12] miri: check that assignments do not self-overlap --- .../rustc_const_eval/src/interpret/place.rs | 7 +++++- .../miri/tests/fail/overlapping_assignment.rs | 23 +++++++++++++++++++ .../tests/fail/overlapping_assignment.stderr | 20 ++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/tools/miri/tests/fail/overlapping_assignment.rs create mode 100644 src/tools/miri/tests/fail/overlapping_assignment.stderr diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 24c1fe43d0c68..ca1106384fd33 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -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, ) } diff --git a/src/tools/miri/tests/fail/overlapping_assignment.rs b/src/tools/miri/tests/fail/overlapping_assignment.rs new file mode 100644 index 0000000000000..84994c179f9ea --- /dev/null +++ b/src/tools/miri/tests/fail/overlapping_assignment.rs @@ -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); +} diff --git a/src/tools/miri/tests/fail/overlapping_assignment.stderr b/src/tools/miri/tests/fail/overlapping_assignment.stderr new file mode 100644 index 0000000000000..42a000dfcc6c7 --- /dev/null +++ b/src/tools/miri/tests/fail/overlapping_assignment.stderr @@ -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 + From d03b0f59d55324f373040d7636dffb7d9872c687 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 5 Jul 2023 18:36:10 +0200 Subject: [PATCH 03/12] If re-export is private, get the next item until a public one is found or expose the private item directly --- src/librustdoc/clean/mod.rs | 96 +++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0182d50773d77..507ac4f0c1a1d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1479,8 +1479,93 @@ 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_not_private( + cx: &mut DocContext<'_>, + hir_id: hir::HirId, + path: &hir::Path<'_>, +) -> Option { + if path.segments.is_empty() { + return None; + } + let parent_def_id = if path.segments.len() == 1 { + // Then it's available in the same scope as the owner. + hir_id.owner.def_id + } else { + // It's not available in the same scope, so we start from the parent of the item. + path.segments[path.segments.len() - 2].res.opt_def_id()?.as_local()? + }; + let target_def_id = path.res.opt_def_id()?; + let mut ident = path.segments.last().unwrap().ident; + // First we try to get the `DefId` of the item. + for child in cx + .tcx + .module_children_local(cx.tcx.local_parent(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(); + // let parent_mod = hir.local_def_id_to_hir_id(); + 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 { + match item.kind { + hir::ItemKind::Use(path, _) => { + 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 { @@ -1497,7 +1582,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_not_private(cx, hir_id, &path) { + path + } else { + clean_path(path, cx) + }; resolve_type(cx, path) } } @@ -1649,7 +1739,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 { From e3b7035e350b57baf9579c4c5c51befbe37a6df3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 5 Jul 2023 18:45:42 +0200 Subject: [PATCH 04/12] Add regression test for #81141 --- ...ue-81141-private-reexport-in-public-api.rs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/rustdoc/issue-81141-private-reexport-in-public-api.rs diff --git a/tests/rustdoc/issue-81141-private-reexport-in-public-api.rs b/tests/rustdoc/issue-81141-private-reexport-in-public-api.rs new file mode 100644 index 0000000000000..d6ef843542957 --- /dev/null +++ b/tests/rustdoc/issue-81141-private-reexport-in-public-api.rs @@ -0,0 +1,34 @@ +// This test ensures that if a private re-export is present in a public API, it'll be +// replaced by the first public item in the re-export chain or by the private item. + +#![crate_name = "foo"] + +use crate::bar::Bar as Alias; + +pub use crate::bar::Bar as Whatever; +use crate::Whatever as Whatever2; +use crate::Whatever2 as Whatever3; +pub use crate::bar::Inner as Whatever4; + +mod bar { + pub struct Bar; + pub use self::Bar as Inner; +} + +// @has 'foo/fn.bar.html' +// @has - '//*[@class="rust item-decl"]/code' 'pub fn bar() -> Bar' +pub fn bar() -> Alias { + Alias +} + +// @has 'foo/fn.bar2.html' +// @has - '//*[@class="rust item-decl"]/code' 'pub fn bar2() -> Whatever' +pub fn bar2() -> Whatever3 { + Whatever +} + +// @has 'foo/fn.bar3.html' +// @has - '//*[@class="rust item-decl"]/code' 'pub fn bar3() -> Whatever4' +pub fn bar3() -> Whatever4 { + Whatever +} From 52a7615d3bc0d77b1a2d5236fdeac1550455556b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 7 Jul 2023 13:55:31 +0200 Subject: [PATCH 05/12] Improve code readability --- src/librustdoc/clean/mod.rs | 59 +++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 507ac4f0c1a1d..410d1a5f5643d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1488,24 +1488,25 @@ fn first_not_private( hir_id: hir::HirId, path: &hir::Path<'_>, ) -> Option { - if path.segments.is_empty() { - return None; - } - let parent_def_id = if path.segments.len() == 1 { - // Then it's available in the same scope as the owner. - hir_id.owner.def_id - } else { - // It's not available in the same scope, so we start from the parent of the item. - path.segments[path.segments.len() - 2].res.opt_def_id()?.as_local()? + 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 parent.ident.name == kw::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()?; - let mut ident = path.segments.last().unwrap().ident; // First we try to get the `DefId` of the item. - for child in cx - .tcx - .module_children_local(cx.tcx.local_parent(parent_def_id)) - .iter() - .filter(move |c| c.ident == ident) + 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; @@ -1518,26 +1519,20 @@ fn first_not_private( let Some(local_use_def_id) = use_def_id.as_local() { let hir = cx.tcx.hir(); - // let parent_mod = hir.local_def_id_to_hir_id(); 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 { - match item.kind { - hir::ItemKind::Use(path, _) => { - 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 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; } } } From f37a6b0bf9ed9253e331ef3baa69fa463f1c200f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 7 Jul 2023 13:55:47 +0200 Subject: [PATCH 06/12] Extend issue-81141-private-reexport-in-public-api test to cover more cases --- ...ue-81141-private-reexport-in-public-api.rs | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/tests/rustdoc/issue-81141-private-reexport-in-public-api.rs b/tests/rustdoc/issue-81141-private-reexport-in-public-api.rs index d6ef843542957..312146e795767 100644 --- a/tests/rustdoc/issue-81141-private-reexport-in-public-api.rs +++ b/tests/rustdoc/issue-81141-private-reexport-in-public-api.rs @@ -32,3 +32,83 @@ pub fn bar2() -> Whatever3 { pub fn bar3() -> Whatever4 { Whatever } + +// @has 'foo/fn.bar4.html' +// @has - '//*[@class="rust item-decl"]/code' 'pub fn bar4() -> Bar' +pub fn bar4() -> crate::Alias { + Alias +} + +// @has 'foo/fn.bar5.html' +// @has - '//*[@class="rust item-decl"]/code' 'pub fn bar5() -> Whatever' +pub fn bar5() -> crate::Whatever3 { + Whatever +} + +// @has 'foo/fn.bar6.html' +// @has - '//*[@class="rust item-decl"]/code' 'pub fn bar6() -> Whatever4' +pub fn bar6() -> crate::Whatever4 { + Whatever +} + + +// @has 'foo/fn.bar7.html' +// @has - '//*[@class="rust item-decl"]/code' 'pub fn bar7() -> Bar' +pub fn bar7() -> self::Alias { + Alias +} + +// @has 'foo/fn.bar8.html' +// @has - '//*[@class="rust item-decl"]/code' 'pub fn bar8() -> Whatever' +pub fn bar8() -> self::Whatever3 { + Whatever +} + +// @has 'foo/fn.bar9.html' +// @has - '//*[@class="rust item-decl"]/code' 'pub fn bar9() -> Whatever4' +pub fn bar9() -> self::Whatever4 { + Whatever +} + +mod nested { + pub(crate) use crate::Alias; + pub(crate) use crate::Whatever3; + pub(crate) use crate::Whatever4; + pub(crate) use crate::nested as nested2; +} + +// @has 'foo/fn.bar10.html' +// @has - '//*[@class="rust item-decl"]/code' 'pub fn bar10() -> Bar' +pub fn bar10() -> nested::Alias { + Alias +} + +// @has 'foo/fn.bar11.html' +// @has - '//*[@class="rust item-decl"]/code' 'pub fn bar11() -> Whatever' +pub fn bar11() -> nested::Whatever3 { + Whatever +} + +// @has 'foo/fn.bar12.html' +// @has - '//*[@class="rust item-decl"]/code' 'pub fn bar12() -> Whatever4' +pub fn bar12() -> nested::Whatever4 { + Whatever +} + +// @has 'foo/fn.bar13.html' +// @has - '//*[@class="rust item-decl"]/code' 'pub fn bar13() -> Bar' +pub fn bar13() -> nested::nested2::Alias { + Alias +} + +// @has 'foo/fn.bar14.html' +// @has - '//*[@class="rust item-decl"]/code' 'pub fn bar14() -> Whatever' +pub fn bar14() -> nested::nested2::Whatever3 { + Whatever +} + +// @has 'foo/fn.bar15.html' +// @has - '//*[@class="rust item-decl"]/code' 'pub fn bar15() -> Whatever4' +pub fn bar15() -> nested::nested2::Whatever4 { + Whatever +} From 1d1951bafaf113fdb2b07aba99f51365c4a22cb5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 7 Jul 2023 16:56:21 +0200 Subject: [PATCH 07/12] Rename `first_not_private` into `first_non_private` --- src/librustdoc/clean/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 410d1a5f5643d..aa651bdb31474 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1483,7 +1483,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( /// 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_not_private( +fn first_non_private( cx: &mut DocContext<'_>, hir_id: hir::HirId, path: &hir::Path<'_>, @@ -1578,7 +1578,7 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type expanded } else { // First we check if it's a private re-export. - let path = if let Some(path) = first_not_private(cx, hir_id, &path) { + let path = if let Some(path) = first_non_private(cx, hir_id, &path) { path } else { clean_path(path, cx) From 010ee7b0e09c0b1eb6ba7bc745693bd19c9d37e4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 4 Jul 2023 17:36:26 +0000 Subject: [PATCH 08/12] Remove an AFIT test that isn't an AFIT test --- .../in-trait/async-associated-types2.rs | 30 ------------------- 1 file changed, 30 deletions(-) delete mode 100644 tests/ui/async-await/in-trait/async-associated-types2.rs diff --git a/tests/ui/async-await/in-trait/async-associated-types2.rs b/tests/ui/async-await/in-trait/async-associated-types2.rs deleted file mode 100644 index b889f616a0311..0000000000000 --- a/tests/ui/async-await/in-trait/async-associated-types2.rs +++ /dev/null @@ -1,30 +0,0 @@ -// check-pass -// edition: 2021 -// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty -// revisions: current next - -#![feature(async_fn_in_trait)] -#![feature(impl_trait_in_assoc_type)] -#![allow(incomplete_features)] - -use std::future::Future; - -trait MyTrait { - type Fut<'a>: Future - where - Self: 'a; - - fn foo<'a>(&'a self) -> Self::Fut<'a>; -} - -impl MyTrait for i32 { - type Fut<'a> = impl Future + 'a - where - Self: 'a; - - fn foo<'a>(&'a self) -> Self::Fut<'a> { - async { *self } - } -} - -fn main() {} From 713f9bb5d1d1d6cb22bc668e326d1c0f0f4f815a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 4 Jul 2023 17:54:23 +0000 Subject: [PATCH 09/12] Mark more hanging new-solver tests --- tests/ui/issues/issue-67552.rs | 1 + tests/ui/issues/issue-67552.stderr | 4 ++-- tests/ui/recursion/issue-95134.rs | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/ui/issues/issue-67552.rs b/tests/ui/issues/issue-67552.rs index ec1997ccd5d66..7336b873dd643 100644 --- a/tests/ui/issues/issue-67552.rs +++ b/tests/ui/issues/issue-67552.rs @@ -1,6 +1,7 @@ // build-fail // compile-flags: -Copt-level=0 // normalize-stderr-test: ".nll/" -> "/" +// ignore-compare-mode-next-solver (hangs) fn main() { rec(Empty); diff --git a/tests/ui/issues/issue-67552.stderr b/tests/ui/issues/issue-67552.stderr index 4746f918bf8dd..f93ed67dab244 100644 --- a/tests/ui/issues/issue-67552.stderr +++ b/tests/ui/issues/issue-67552.stderr @@ -1,11 +1,11 @@ error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut ...>` - --> $DIR/issue-67552.rs:29:9 + --> $DIR/issue-67552.rs:30:9 | LL | rec(identity(&mut it)) | ^^^^^^^^^^^^^^^^^^^^^^ | note: `rec` defined here - --> $DIR/issue-67552.rs:22:1 + --> $DIR/issue-67552.rs:23:1 | LL | / fn rec(mut it: T) LL | | where diff --git a/tests/ui/recursion/issue-95134.rs b/tests/ui/recursion/issue-95134.rs index 2f1cffa2fa907..7ee31d85c2b12 100644 --- a/tests/ui/recursion/issue-95134.rs +++ b/tests/ui/recursion/issue-95134.rs @@ -3,6 +3,7 @@ // compile-flags: -Copt-level=0 // dont-check-failure-status // dont-check-compiler-stderr +// ignore-compare-mode-next-solver (hangs) pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { if n > 15 { From f55b046931cfa1b281375ff8ec4e590d8386f0c4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 4 Jul 2023 18:49:13 +0000 Subject: [PATCH 10/12] Normalize opaques during codegen in new solver --- .../src/solve/normalize.rs | 4 +-- .../param-env-region-infer.current.stderr | 2 +- .../param-env-region-infer.next.stderr | 29 +++++++++++++++++++ tests/ui/dyn-star/param-env-region-infer.rs | 6 ++-- tests/ui/impl-trait/reveal-during-codegen.rs | 11 +++++++ 5 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 tests/ui/dyn-star/param-env-region-infer.next.stderr create mode 100644 tests/ui/impl-trait/reveal-during-codegen.rs diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index c0ee1a576e5fb..c388850d831e2 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -167,9 +167,7 @@ impl<'tcx> FallibleTypeFolder> 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), }; diff --git a/tests/ui/dyn-star/param-env-region-infer.current.stderr b/tests/ui/dyn-star/param-env-region-infer.current.stderr index c606a50c8a9cb..902053ecfef62 100644 --- a/tests/ui/dyn-star/param-env-region-infer.current.stderr +++ b/tests/ui/dyn-star/param-env-region-infer.current.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/param-env-region-infer.rs:16:10 + --> $DIR/param-env-region-infer.rs:18:10 | LL | t as _ | ^ cannot infer type diff --git a/tests/ui/dyn-star/param-env-region-infer.next.stderr b/tests/ui/dyn-star/param-env-region-infer.next.stderr new file mode 100644 index 0000000000000..dd724a6590829 --- /dev/null +++ b/tests/ui/dyn-star/param-env-region-infer.next.stderr @@ -0,0 +1,29 @@ +error[E0391]: cycle detected when computing type of `make_dyn_star::{opaque#0}` + --> $DIR/param-env-region-infer.rs:16:60 + | +LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `make_dyn_star`... + --> $DIR/param-env-region-infer.rs:16:1 + | +LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires computing layout of `make_dyn_star::{opaque#0}`... + = note: ...which requires normalizing `make_dyn_star::{opaque#0}`... + = note: ...which again requires computing type of `make_dyn_star::{opaque#0}`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/param-env-region-infer.rs:10:1 + | +LL | / #![feature(dyn_star, pointer_like_trait)] +LL | | #![allow(incomplete_features)] +LL | | +LL | | use std::fmt::Debug; +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/dyn-star/param-env-region-infer.rs b/tests/ui/dyn-star/param-env-region-infer.rs index 9c337e4a89bd3..537473abc3a5b 100644 --- a/tests/ui/dyn-star/param-env-region-infer.rs +++ b/tests/ui/dyn-star/param-env-region-infer.rs @@ -1,6 +1,7 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next -//[next] check-pass +// Need `-Zdeduplicate-diagnostics=yes` because the number of cycle errors +// emitted is for some horrible reason platform-specific. +//[next] compile-flags: -Ztrait-solver=next -Zdeduplicate-diagnostics=yes // incremental // checks that we don't ICE if there are region inference variables in the environment @@ -13,6 +14,7 @@ use std::fmt::Debug; use std::marker::PointerLike; fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a { + //[next]~^ ERROR cycle detected when computing t as _ //[current]~^ ERROR type annotations needed } diff --git a/tests/ui/impl-trait/reveal-during-codegen.rs b/tests/ui/impl-trait/reveal-during-codegen.rs new file mode 100644 index 0000000000000..11463772eb38c --- /dev/null +++ b/tests/ui/impl-trait/reveal-during-codegen.rs @@ -0,0 +1,11 @@ +// build-pass +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next + +fn test() -> Option { + Some("") +} + +fn main() { + test(); +} From 4a1e06b453d14b61d4fc19532918694f485bf51e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 7 Jul 2023 17:55:33 +0200 Subject: [PATCH 11/12] Correctly handle `super` and `::` --- src/librustdoc/clean/mod.rs | 11 ++++++++++- .../issue-81141-private-reexport-in-public-api-2.rs | 13 +++++++++++++ .../issue-81141-private-reexport-in-public-api.rs | 10 ++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 tests/rustdoc/issue-81141-private-reexport-in-public-api-2.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index aa651bdb31474..f663b58c7380e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1497,9 +1497,18 @@ fn first_non_private( (cx.tcx.local_parent(hir_id.owner.def_id), leaf.ident) } // Crate paths are not. We start from the crate root. - [parent, leaf] if parent.ident.name == kw::Crate => { + [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), }; diff --git a/tests/rustdoc/issue-81141-private-reexport-in-public-api-2.rs b/tests/rustdoc/issue-81141-private-reexport-in-public-api-2.rs new file mode 100644 index 0000000000000..4e9d188bbf8d1 --- /dev/null +++ b/tests/rustdoc/issue-81141-private-reexport-in-public-api-2.rs @@ -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 } +} diff --git a/tests/rustdoc/issue-81141-private-reexport-in-public-api.rs b/tests/rustdoc/issue-81141-private-reexport-in-public-api.rs index 312146e795767..bd54d02c6ec8f 100644 --- a/tests/rustdoc/issue-81141-private-reexport-in-public-api.rs +++ b/tests/rustdoc/issue-81141-private-reexport-in-public-api.rs @@ -112,3 +112,13 @@ pub fn bar14() -> nested::nested2::Whatever3 { pub fn bar15() -> nested::nested2::Whatever4 { Whatever } + +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() -> super::Private { super::Private } +} From cedcd39cfd31946112f0a1f5c77ec58451893f6d Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Fri, 7 Jul 2023 18:18:25 +0000 Subject: [PATCH 12/12] Fix failing clippy tests Comments out the C string literals due to https://github.com/rust-lang/rust/pull/113334 Fixes https://github.com/rust-lang/rust-clippy/issues/11121 --- .../clippy_lints/src/incorrect_impls.rs | 2 +- .../clippy/tests/ui/needless_raw_string.fixed | 7 ++++--- .../clippy/tests/ui/needless_raw_string.rs | 7 ++++--- .../tests/ui/needless_raw_string.stderr | 8 +------- .../tests/ui/needless_raw_string_hashes.fixed | 9 +++++---- .../tests/ui/needless_raw_string_hashes.rs | 9 +++++---- .../ui/needless_raw_string_hashes.stderr | 20 +------------------ 7 files changed, 21 insertions(+), 41 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/incorrect_impls.rs b/src/tools/clippy/clippy_lints/src/incorrect_impls.rs index 13cc0b23ba33d..7b95116ee4e36 100644 --- a/src/tools/clippy/clippy_lints/src/incorrect_impls.rs +++ b/src/tools/clippy/clippy_lints/src/incorrect_impls.rs @@ -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 { diff --git a/src/tools/clippy/tests/ui/needless_raw_string.fixed b/src/tools/clippy/tests/ui/needless_raw_string.fixed index 6438e46977bbd..b36912efbb2d4 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string.fixed +++ b/src/tools/clippy/tests/ui/needless_raw_string.fixed @@ -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"#; } diff --git a/src/tools/clippy/tests/ui/needless_raw_string.rs b/src/tools/clippy/tests/ui/needless_raw_string.rs index f7ddc68265edf..8f48e7dab2a6e 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string.rs +++ b/src/tools/clippy/tests/ui/needless_raw_string.rs @@ -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"#; } diff --git a/src/tools/clippy/tests/ui/needless_raw_string.stderr b/src/tools/clippy/tests/ui/needless_raw_string.stderr index 0179978b7b08c..cfb07b647d7c6 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string.stderr +++ b/src/tools/clippy/tests/ui/needless_raw_string.stderr @@ -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 diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed b/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed index e4d7d8fb017a9..c8507c7271513 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed +++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed @@ -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" "# "## "######; } diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs b/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs index e2d85c52e78cc..912fbde1679db 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs +++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs @@ -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" "# "## "######; } diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr index dff47a2d04212..30e6783a38e8b 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr +++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr @@ -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