From 656213cc83537c311d8bcfd0b8f2c68fe1594233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 27 Jul 2023 12:32:22 +0000 Subject: [PATCH 1/9] When flushing delayed span bugs, write to the ICE dump file even if it doesn't exist Fix #113881. --- compiler/rustc_errors/src/lib.rs | 4 ++-- library/std/src/panicking.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 1da02e1bb012f..9772c5b8c1572 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1673,11 +1673,11 @@ impl HandlerInner { let backtrace = std::env::var_os("RUST_BACKTRACE").map_or(true, |x| &x != "0"); for bug in bugs { if let Some(file) = self.ice_file.as_ref() - && let Ok(mut out) = std::fs::File::options().append(true).open(file) + && let Ok(mut out) = std::fs::File::options().create(true).append(true).open(file) { let _ = write!( &mut out, - "\n\ndelayed span bug: {}\n{}", + "delayed span bug: {}\n{}\n", bug.inner.styled_message().iter().filter_map(|(msg, _)| msg.as_str()).collect::(), &bug.note ); diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 0e90d618ad434..15285465c713a 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -300,7 +300,7 @@ pub fn panic_hook_with_disk_dump(info: &PanicInfo<'_>, path: Option<&crate::path }; if let Some(path) = path - && let Ok(mut out) = crate::fs::File::options().create(true).write(true).open(&path) + && let Ok(mut out) = crate::fs::File::options().create(true).append(true).open(&path) { write(&mut out, BacktraceStyle::full()); } From b09091c69bb086e7ed4ecf7f6509654f1c776dde Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jul 2023 16:50:28 +0000 Subject: [PATCH 2/9] Adjust spans correctly for fn -> method suggestion --- compiler/rustc_hir_typeck/src/callee.rs | 8 ++++++-- .../suggest-method-on-call-with-macro-rcvr.rs | 6 ++++++ .../suggest-method-on-call-with-macro-rcvr.stderr | 15 +++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 tests/ui/methods/suggest-method-on-call-with-macro-rcvr.rs create mode 100644 tests/ui/methods/suggest-method-on-call-with-macro-rcvr.stderr diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index a475972219966..c68f2d94f3521 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -531,8 +531,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - let up_to_rcvr_span = segment.ident.span.until(callee_expr.span); - let rest_span = callee_expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi()); + let Some(callee_expr_span) = callee_expr.span.find_ancestor_inside(call_expr.span) + else { + return; + }; + let up_to_rcvr_span = segment.ident.span.until(callee_expr_span); + let rest_span = callee_expr_span.shrink_to_hi().to(call_expr.span.shrink_to_hi()); let rest_snippet = if let Some(first) = rest.first() { self.tcx .sess diff --git a/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.rs b/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.rs new file mode 100644 index 0000000000000..93b7ddf5e9e09 --- /dev/null +++ b/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.rs @@ -0,0 +1,6 @@ +// issue: 114131 + +fn main() { + let hello = len(vec![]); + //~^ ERROR cannot find function `len` in this scope +} diff --git a/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.stderr b/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.stderr new file mode 100644 index 0000000000000..9694f80ab6d0f --- /dev/null +++ b/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.stderr @@ -0,0 +1,15 @@ +error[E0425]: cannot find function `len` in this scope + --> $DIR/suggest-method-on-call-with-macro-rcvr.rs:4:17 + | +LL | let hello = len(vec![]); + | ^^^ not found in this scope + | +help: use the `.` operator to call the method `len` on `&Vec<_>` + | +LL - let hello = len(vec![]); +LL + let hello = vec![].len(); + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. From 0ae0643a5353da7b79e53a11beca93ceeea067d5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jul 2023 22:04:19 +0000 Subject: [PATCH 3/9] Skip reporting item name when checking RPITIT GAT's associated type bounds hold --- .../src/infer/error_reporting/note.rs | 18 +++++++---- .../in-trait/bad-item-bound-within-rpitit.rs | 25 ++++++++++++++++ .../bad-item-bound-within-rpitit.stderr | 30 +++++++++++++++++++ 3 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs create mode 100644 tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 7144084c78ebe..8cd1b82130b01 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -243,12 +243,18 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => { let mut err = self.report_concrete_failure(*parent, sub, sup); - let trait_item_span = self.tcx.def_span(trait_item_def_id); - let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); - err.span_label( - trait_item_span, - format!("definition of `{}` from trait", item_name), - ); + + // Don't mention the item name if it's an RPITIT, since that'll just confuse + // folks. + if !self.tcx.is_impl_trait_in_trait(impl_item_def_id.to_def_id()) { + let trait_item_span = self.tcx.def_span(trait_item_def_id); + let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); + err.span_label( + trait_item_span, + format!("definition of `{}` from trait", item_name), + ); + } + self.suggest_copy_trait_method_bounds( trait_item_def_id, impl_item_def_id, diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs new file mode 100644 index 0000000000000..8b97336fe0c67 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs @@ -0,0 +1,25 @@ +// issue: 114145 + +#![feature(return_position_impl_trait_in_trait)] + +trait Iterable { + type Item<'a> + where + Self: 'a; + + fn iter(&self) -> impl '_ + Iterator>; +} + +impl<'a, I: 'a + Iterable> Iterable for &'a I { + type Item<'b> = I::Item<'a> + where + 'b: 'a; + //~^ ERROR impl has stricter requirements than trait + + fn iter(&self) -> impl 'a + Iterator> { + //~^ ERROR the type `&'a I` does not fulfill the required lifetime + (*self).iter() + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr new file mode 100644 index 0000000000000..1e3363268f06d --- /dev/null +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr @@ -0,0 +1,30 @@ +error[E0276]: impl has stricter requirements than trait + --> $DIR/bad-item-bound-within-rpitit.rs:16:13 + | +LL | type Item<'a> + | ------------- definition of `Item` from trait +... +LL | 'b: 'a; + | ^^ impl has extra requirement `'b: 'a` + | +help: copy the `where` clause predicates from the trait + | +LL | where Self: 'b; + | ~~~~~~~~~~~~~~ + +error[E0477]: the type `&'a I` does not fulfill the required lifetime + --> $DIR/bad-item-bound-within-rpitit.rs:19:5 + | +LL | fn iter(&self) -> impl 'a + Iterator> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: type must outlive the anonymous lifetime as defined here + --> $DIR/bad-item-bound-within-rpitit.rs:10:28 + | +LL | fn iter(&self) -> impl '_ + Iterator>; + | ^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0276, E0477. +For more information about an error, try `rustc --explain E0276`. From bf38111ac1ad499d592b9f9ef9ae28e947c1c587 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jul 2023 22:20:32 +0000 Subject: [PATCH 4/9] tighten span slightly for synthetic item --- compiler/rustc_ty_utils/src/assoc.rs | 12 ++++++++++-- .../in-trait/bad-item-bound-within-rpitit.stderr | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 4a54423217422..780f7ea426f7b 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -346,8 +346,16 @@ fn associated_type_for_impl_trait_in_impl( ) -> LocalDefId { let impl_local_def_id = tcx.local_parent(impl_fn_def_id); - // FIXME fix the span, we probably want the def_id of the return type of the function - let span = tcx.def_span(impl_fn_def_id); + let decl = tcx + .hir() + .find_by_def_id(impl_fn_def_id) + .expect("expected item") + .fn_decl() + .expect("expected decl"); + let span = match decl.output { + hir::FnRetTy::DefaultReturn(_) => tcx.def_span(impl_fn_def_id), + hir::FnRetTy::Return(ty) => ty.span, + }; let impl_assoc_ty = tcx.at(span).create_def(impl_local_def_id, DefPathData::ImplTraitAssocTy); let local_def_id = impl_assoc_ty.def_id(); diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr index 1e3363268f06d..54a08c5b516c4 100644 --- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr @@ -13,10 +13,10 @@ LL | where Self: 'b; | ~~~~~~~~~~~~~~ error[E0477]: the type `&'a I` does not fulfill the required lifetime - --> $DIR/bad-item-bound-within-rpitit.rs:19:5 + --> $DIR/bad-item-bound-within-rpitit.rs:19:23 | LL | fn iter(&self) -> impl 'a + Iterator> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: type must outlive the anonymous lifetime as defined here --> $DIR/bad-item-bound-within-rpitit.rs:10:28 From a4ac773f62aa0992c4c525b9291302a93b352cc3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jul 2023 22:32:53 +0000 Subject: [PATCH 5/9] Insert RPITITs that were shadowed by missing ADTs that resolve to type error --- .../src/check/compare_impl_item.rs | 26 ++++++++++++++++--- .../rpitit-shadowed-by-missing-adt.rs | 18 +++++++++++++ .../rpitit-shadowed-by-missing-adt.stderr | 9 +++++++ 3 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs create mode 100644 tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.stderr diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 0a6e2e644eb22..3adbdcedbfb74 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -760,7 +760,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( ); ocx.resolve_regions_and_report_errors(impl_m_def_id, &outlives_env)?; - let mut collected_tys = FxHashMap::default(); + let mut remapped_types = FxHashMap::default(); for (def_id, (ty, args)) in collected_types { match infcx.fully_resolve((ty, args)) { Ok((ty, args)) => { @@ -810,19 +810,37 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( Ok(ty) => ty, Err(guar) => Ty::new_error(tcx, guar), }; - collected_tys.insert(def_id, ty::EarlyBinder::bind(ty)); + remapped_types.insert(def_id, ty::EarlyBinder::bind(ty)); } Err(err) => { let reported = tcx.sess.delay_span_bug( return_span, format!("could not fully resolve: {ty} => {err:?}"), ); - collected_tys.insert(def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, reported))); + remapped_types.insert(def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, reported))); } } } - Ok(&*tcx.arena.alloc(collected_tys)) + // We may not collect all RPITITs that we see in the HIR for a trait signature + // because an RPITIT was located within a missing item. Like if we have a sig + // returning `-> Missing`, that gets converted to `-> [type error]`, + // and when walking through the signature we end up never collecting the def id + // of the `impl Sized`. Insert that here, so we don't ICE later. + for assoc_item in tcx.associated_types_for_impl_traits_in_associated_fn(trait_m.def_id) { + if !remapped_types.contains_key(assoc_item) { + remapped_types.insert( + *assoc_item, + ty::EarlyBinder::bind(Ty::new_error_with_message( + tcx, + return_span, + "missing synthetic item for RPITIT", + )), + ); + } + } + + Ok(&*tcx.arena.alloc(remapped_types)) } struct ImplTraitInTraitCollector<'a, 'tcx> { diff --git a/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs new file mode 100644 index 0000000000000..7682884f87931 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs @@ -0,0 +1,18 @@ +// issue: 113903 + +#![feature(return_position_impl_trait_in_trait)] + +use std::ops::Deref; + +pub trait Tr { + fn w() -> impl Deref>; + //~^ ERROR cannot find type `Missing` in this scope +} + +impl Tr for () { + fn w() -> &'static () { + &() + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.stderr b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.stderr new file mode 100644 index 0000000000000..6e4a5bb5df36a --- /dev/null +++ b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Missing` in this scope + --> $DIR/rpitit-shadowed-by-missing-adt.rs:8:35 + | +LL | fn w() -> impl Deref>; + | ^^^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. From ea2f8b346b09c474d620ada38e4a0cb9f75e0b5f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jul 2023 22:50:40 +0000 Subject: [PATCH 6/9] Add additional test --- .../bad-item-bound-within-rpitit-2.rs | 11 +++++++ .../bad-item-bound-within-rpitit-2.stderr | 33 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs create mode 100644 tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs new file mode 100644 index 0000000000000..3a93dfee57f33 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs @@ -0,0 +1,11 @@ +// issue: 114146 + +#![feature(return_position_impl_trait_in_trait)] + +trait Foo { + fn bar<'other: 'a>() -> impl Sized + 'a {} + //~^ ERROR use of undeclared lifetime name `'a` + //~| ERROR use of undeclared lifetime name `'a` +} + +fn main() {} diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr new file mode 100644 index 0000000000000..3a1f8f9083747 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr @@ -0,0 +1,33 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/bad-item-bound-within-rpitit-2.rs:6:20 + | +LL | fn bar<'other: 'a>() -> impl Sized + 'a {} + | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | fn bar<'a, 'other: 'a>() -> impl Sized + 'a {} + | +++ +help: consider introducing lifetime `'a` here + | +LL | trait Foo<'a> { + | ++++ + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/bad-item-bound-within-rpitit-2.rs:6:42 + | +LL | fn bar<'other: 'a>() -> impl Sized + 'a {} + | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | fn bar<'a, 'other: 'a>() -> impl Sized + 'a {} + | +++ +help: consider introducing lifetime `'a` here + | +LL | trait Foo<'a> { + | ++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0261`. From 8745fdc4487d6200ec652abc05b7a1ac9bb16765 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 28 Jul 2023 12:55:13 +1000 Subject: [PATCH 7/9] Replace a lazy `RefCell>` with `OnceCell` --- compiler/rustc_mir_transform/src/coverage/spans.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 35cf9ea5f91cd..deebf5345bac9 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::TyCtxt; use rustc_span::source_map::original_sp; use rustc_span::{BytePos, ExpnKind, MacroKind, Span, Symbol}; -use std::cell::RefCell; +use std::cell::OnceCell; use std::cmp::Ordering; #[derive(Debug, Copy, Clone)] @@ -67,7 +67,7 @@ impl CoverageStatement { pub(super) struct CoverageSpan { pub span: Span, pub expn_span: Span, - pub current_macro_or_none: RefCell>>, + pub current_macro_or_none: OnceCell>, pub bcb: BasicCoverageBlock, pub coverage_statements: Vec, pub is_closure: bool, @@ -175,8 +175,7 @@ impl CoverageSpan { /// If the span is part of a macro, returns the macro name symbol. pub fn current_macro(&self) -> Option { self.current_macro_or_none - .borrow_mut() - .get_or_insert_with(|| { + .get_or_init(|| { if let ExpnKind::Macro(MacroKind::Bang, current_macro) = self.expn_span.ctxt().outer_expn_data().kind { From 38e0d58d7d67a4347b85ac26aa35df573df86621 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Fri, 28 Jul 2023 11:01:53 +0200 Subject: [PATCH 8/9] Add regression test for `--cap-lints allow` and trait bounds warning I have verified that the test fails if stderr begins to contain output by making sure the test fails when I add eprintln!("some output on stderr"); to the compiler (I added it to `fn build_session()`). --- tests/ui/lint/lint-cap-trait-bounds.rs | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/ui/lint/lint-cap-trait-bounds.rs diff --git a/tests/ui/lint/lint-cap-trait-bounds.rs b/tests/ui/lint/lint-cap-trait-bounds.rs new file mode 100644 index 0000000000000..d9c28dd0aa6eb --- /dev/null +++ b/tests/ui/lint/lint-cap-trait-bounds.rs @@ -0,0 +1,8 @@ +// Regression test for https://github.com/rust-lang/rust/issues/43134 + +// check-pass +// compile-flags: --cap-lints allow + +type Foo = Option; + +fn main() {} From e051a323110d438c337f3f893d171fade7d2d1a6 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 26 Jul 2023 16:51:40 +0100 Subject: [PATCH 9/9] privacy: no nominal visibility for assoc fns When `staged_api` is enabled, effective visibilities are computed earlier and this can trigger an ICE in some cases. In particular, if a impl of a trait method has a visibility then an error will be reported for that, but when privacy invariants are being checked, the effective visibility will still be greater than the nominal visbility and that will trigger a `span_bug!`. However, this invariant - that effective visibilites are limited to nominal visibility - doesn't make sense for associated functions. Signed-off-by: David Wood --- compiler/rustc_middle/src/middle/privacy.rs | 9 +++- tests/ui/privacy/issue-113860-1.rs | 16 +++++++ tests/ui/privacy/issue-113860-1.stderr | 49 +++++++++++++++++++++ tests/ui/privacy/issue-113860-2.rs | 16 +++++++ tests/ui/privacy/issue-113860-2.stderr | 49 +++++++++++++++++++++ tests/ui/privacy/issue-113860.rs | 16 +++++++ tests/ui/privacy/issue-113860.stderr | 49 +++++++++++++++++++++ 7 files changed, 202 insertions(+), 2 deletions(-) create mode 100644 tests/ui/privacy/issue-113860-1.rs create mode 100644 tests/ui/privacy/issue-113860-1.stderr create mode 100644 tests/ui/privacy/issue-113860-2.rs create mode 100644 tests/ui/privacy/issue-113860-2.stderr create mode 100644 tests/ui/privacy/issue-113860.rs create mode 100644 tests/ui/privacy/issue-113860.stderr diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index 5baeb1ee0cf7b..1913421f54c93 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -178,7 +178,12 @@ impl EffectiveVisibilities { // All effective visibilities except `reachable_through_impl_trait` are limited to // nominal visibility. For some items nominal visibility doesn't make sense so we // don't check this condition for them. - if !matches!(tcx.def_kind(def_id), DefKind::Impl { .. }) { + let is_impl = matches!(tcx.def_kind(def_id), DefKind::Impl { .. }); + let is_associated_item_in_trait_impl = tcx + .impl_of_method(def_id.to_def_id()) + .and_then(|impl_id| tcx.trait_id_of_impl(impl_id)) + .is_some(); + if !is_impl && !is_associated_item_in_trait_impl { let nominal_vis = tcx.visibility(def_id); if !nominal_vis.is_at_least(ev.reachable, tcx) { span_bug!( @@ -186,7 +191,7 @@ impl EffectiveVisibilities { "{:?}: reachable {:?} > nominal {:?}", def_id, ev.reachable, - nominal_vis + nominal_vis, ); } } diff --git a/tests/ui/privacy/issue-113860-1.rs b/tests/ui/privacy/issue-113860-1.rs new file mode 100644 index 0000000000000..86ccca41f3795 --- /dev/null +++ b/tests/ui/privacy/issue-113860-1.rs @@ -0,0 +1,16 @@ +#![feature(staged_api)] +//~^ ERROR module has missing stability attribute + +pub trait Trait { + //~^ ERROR trait has missing stability attribute + fn fun() {} + //~^ ERROR associated function has missing stability attribute +} + +impl Trait for u8 { + //~^ ERROR implementation has missing stability attribute + pub(self) fn fun() {} + //~^ ERROR visibility qualifiers are not permitted here [E0449] +} + +fn main() {} diff --git a/tests/ui/privacy/issue-113860-1.stderr b/tests/ui/privacy/issue-113860-1.stderr new file mode 100644 index 0000000000000..c33ce26f0f6e8 --- /dev/null +++ b/tests/ui/privacy/issue-113860-1.stderr @@ -0,0 +1,49 @@ +error[E0449]: visibility qualifiers are not permitted here + --> $DIR/issue-113860-1.rs:12:5 + | +LL | pub(self) fn fun() {} + | ^^^^^^^^^ + | + = note: trait items always share the visibility of their trait + +error: module has missing stability attribute + --> $DIR/issue-113860-1.rs:1:1 + | +LL | / #![feature(staged_api)] +LL | | +LL | | +LL | | pub trait Trait { +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: trait has missing stability attribute + --> $DIR/issue-113860-1.rs:4:1 + | +LL | / pub trait Trait { +LL | | +LL | | fn fun() {} +LL | | +LL | | } + | |_^ + +error: implementation has missing stability attribute + --> $DIR/issue-113860-1.rs:10:1 + | +LL | / impl Trait for u8 { +LL | | +LL | | pub(self) fn fun() {} +LL | | +LL | | } + | |_^ + +error: associated function has missing stability attribute + --> $DIR/issue-113860-1.rs:6:5 + | +LL | fn fun() {} + | ^^^^^^^^^^^ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0449`. diff --git a/tests/ui/privacy/issue-113860-2.rs b/tests/ui/privacy/issue-113860-2.rs new file mode 100644 index 0000000000000..59be19d88a018 --- /dev/null +++ b/tests/ui/privacy/issue-113860-2.rs @@ -0,0 +1,16 @@ +#![feature(staged_api)] +//~^ ERROR module has missing stability attribute + +pub trait Trait { + //~^ ERROR trait has missing stability attribute + type X; + //~^ ERROR associated type has missing stability attribute +} + +impl Trait for u8 { + //~^ ERROR implementation has missing stability attribute + pub(self) type X = Self; + //~^ ERROR visibility qualifiers are not permitted here [E0449] +} + +fn main() {} diff --git a/tests/ui/privacy/issue-113860-2.stderr b/tests/ui/privacy/issue-113860-2.stderr new file mode 100644 index 0000000000000..6748bc276684a --- /dev/null +++ b/tests/ui/privacy/issue-113860-2.stderr @@ -0,0 +1,49 @@ +error[E0449]: visibility qualifiers are not permitted here + --> $DIR/issue-113860-2.rs:12:5 + | +LL | pub(self) type X = Self; + | ^^^^^^^^^ + | + = note: trait items always share the visibility of their trait + +error: module has missing stability attribute + --> $DIR/issue-113860-2.rs:1:1 + | +LL | / #![feature(staged_api)] +LL | | +LL | | +LL | | pub trait Trait { +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: trait has missing stability attribute + --> $DIR/issue-113860-2.rs:4:1 + | +LL | / pub trait Trait { +LL | | +LL | | type X; +LL | | +LL | | } + | |_^ + +error: implementation has missing stability attribute + --> $DIR/issue-113860-2.rs:10:1 + | +LL | / impl Trait for u8 { +LL | | +LL | | pub(self) type X = Self; +LL | | +LL | | } + | |_^ + +error: associated type has missing stability attribute + --> $DIR/issue-113860-2.rs:6:5 + | +LL | type X; + | ^^^^^^^ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0449`. diff --git a/tests/ui/privacy/issue-113860.rs b/tests/ui/privacy/issue-113860.rs new file mode 100644 index 0000000000000..b94c14fac4e1c --- /dev/null +++ b/tests/ui/privacy/issue-113860.rs @@ -0,0 +1,16 @@ +#![feature(staged_api)] +//~^ ERROR module has missing stability attribute + +pub trait Trait { + //~^ ERROR trait has missing stability attribute + const X: u32; + //~^ ERROR associated constant has missing stability attribute +} + +impl Trait for u8 { + //~^ ERROR implementation has missing stability attribute + pub(self) const X: u32 = 3; + //~^ ERROR visibility qualifiers are not permitted here [E0449] +} + +fn main() {} diff --git a/tests/ui/privacy/issue-113860.stderr b/tests/ui/privacy/issue-113860.stderr new file mode 100644 index 0000000000000..3204f4ff9162f --- /dev/null +++ b/tests/ui/privacy/issue-113860.stderr @@ -0,0 +1,49 @@ +error[E0449]: visibility qualifiers are not permitted here + --> $DIR/issue-113860.rs:12:5 + | +LL | pub(self) const X: u32 = 3; + | ^^^^^^^^^ + | + = note: trait items always share the visibility of their trait + +error: module has missing stability attribute + --> $DIR/issue-113860.rs:1:1 + | +LL | / #![feature(staged_api)] +LL | | +LL | | +LL | | pub trait Trait { +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: trait has missing stability attribute + --> $DIR/issue-113860.rs:4:1 + | +LL | / pub trait Trait { +LL | | +LL | | const X: u32; +LL | | +LL | | } + | |_^ + +error: implementation has missing stability attribute + --> $DIR/issue-113860.rs:10:1 + | +LL | / impl Trait for u8 { +LL | | +LL | | pub(self) const X: u32 = 3; +LL | | +LL | | } + | |_^ + +error: associated constant has missing stability attribute + --> $DIR/issue-113860.rs:6:5 + | +LL | const X: u32; + | ^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0449`.