From 959616ef44fe919f297bba1c3ddc65bd8f2432fc Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 31 Dec 2022 03:03:28 +0000 Subject: [PATCH 1/8] Handle inference variables in CollectAllMismatches correctly --- .../traits/error_reporting/method_chain.rs | 13 ++++++---- .../ct-var-in-collect_all_mismatches.rs | 20 ++++++++++++++++ .../ct-var-in-collect_all_mismatches.stderr | 22 +++++++++++++++++ .../invalid-iterator-chain-with-int-infer.rs | 4 ++++ ...valid-iterator-chain-with-int-infer.stderr | 24 +++++++++++++++++++ 5 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 tests/ui/consts/ct-var-in-collect_all_mismatches.rs create mode 100644 tests/ui/consts/ct-var-in-collect_all_mismatches.stderr create mode 100644 tests/ui/iterators/invalid-iterator-chain-with-int-infer.rs create mode 100644 tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs index 27c207528c7..ba9ee57d409 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs @@ -55,7 +55,7 @@ impl<'a, 'tcx> TypeRelation<'tcx> for CollectAllMismatches<'a, 'tcx> { fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { self.infcx.probe(|_| { - if a.is_ty_infer() || b.is_ty_infer() { + if a.is_ty_var() || b.is_ty_var() { Ok(a) } else { self.infcx.super_combine_tys(self, a, b).or_else(|e| { @@ -71,10 +71,13 @@ impl<'a, 'tcx> TypeRelation<'tcx> for CollectAllMismatches<'a, 'tcx> { a: ty::Const<'tcx>, b: ty::Const<'tcx>, ) -> RelateResult<'tcx, ty::Const<'tcx>> { - if a == b { - return Ok(a); - } - relate::super_relate_consts(self, a, b) // could do something similar here for constants! + self.infcx.probe(|_| { + if a.is_ct_infer() || b.is_ct_infer() { + Ok(a) + } else { + relate::super_relate_consts(self, a, b) // could do something similar here for constants! + } + }) } fn binders>( diff --git a/tests/ui/consts/ct-var-in-collect_all_mismatches.rs b/tests/ui/consts/ct-var-in-collect_all_mismatches.rs new file mode 100644 index 00000000000..5fb633de983 --- /dev/null +++ b/tests/ui/consts/ct-var-in-collect_all_mismatches.rs @@ -0,0 +1,20 @@ +struct Foo { + array: [T; N], +} + +trait Bar {} + +impl Foo { + fn trigger(self) { + self.unsatisfied() + //~^ ERROR the trait bound `T: Bar` is not satisfied + } + + fn unsatisfied(self) + where + T: Bar, + { + } +} + +fn main() {} diff --git a/tests/ui/consts/ct-var-in-collect_all_mismatches.stderr b/tests/ui/consts/ct-var-in-collect_all_mismatches.stderr new file mode 100644 index 00000000000..43fba2573ff --- /dev/null +++ b/tests/ui/consts/ct-var-in-collect_all_mismatches.stderr @@ -0,0 +1,22 @@ +error[E0277]: the trait bound `T: Bar` is not satisfied + --> $DIR/ct-var-in-collect_all_mismatches.rs:9:14 + | +LL | self.unsatisfied() + | ^^^^^^^^^^^ the trait `Bar` is not implemented for `T` + | +note: required by a bound in `Foo::::unsatisfied` + --> $DIR/ct-var-in-collect_all_mismatches.rs:15:12 + | +LL | fn unsatisfied(self) + | ----------- required by a bound in this +LL | where +LL | T: Bar, + | ^^^^^^ required by this bound in `Foo::::unsatisfied` +help: consider restricting type parameter `T` + | +LL | impl, const N: usize> Foo { + | ++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.rs b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.rs new file mode 100644 index 00000000000..882a1d13954 --- /dev/null +++ b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.rs @@ -0,0 +1,4 @@ +fn main() { + let x = Some(()).iter().map(|()| 1).sum::(); + //~^ ERROR a value of type `f32` cannot be made by summing an iterator over elements of type `{integer}` +} diff --git a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr new file mode 100644 index 00000000000..3cb5e44c711 --- /dev/null +++ b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr @@ -0,0 +1,24 @@ +error[E0277]: a value of type `f32` cannot be made by summing an iterator over elements of type `{integer}` + --> $DIR/invalid-iterator-chain-with-int-infer.rs:2:41 + | +LL | let x = Some(()).iter().map(|()| 1).sum::(); + | ^^^ value of type `f32` cannot be made by summing a `std::iter::Iterator` + | + = help: the trait `Sum<{integer}>` is not implemented for `f32` + = help: the following other types implement trait `Sum`: + > + +note: the method call chain might not have had the expected associated types + --> $DIR/invalid-iterator-chain-with-int-infer.rs:2:29 + | +LL | let x = Some(()).iter().map(|()| 1).sum::(); + | -------- ------ ^^^^^^^^^^^ `Iterator::Item` changed to `{integer}` here + | | | + | | `Iterator::Item` is `&()` here + | this expression has type `Option<()>` +note: required by a bound in `std::iter::Iterator::sum` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From ad13d9fbbe7d7a3bc5e59ad1f829e132d6cb1b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 8 Jan 2023 01:15:28 +0000 Subject: [PATCH 2/8] Suggest making private tuple struct field public Fix #52144. --- .../rustc_resolve/src/build_reduced_graph.rs | 2 ++ .../rustc_resolve/src/late/diagnostics.rs | 20 +++++++++++++++++++ compiler/rustc_resolve/src/lib.rs | 5 +++++ tests/ui/privacy/issue-75906.stderr | 4 ++++ tests/ui/privacy/issue-75907.rs | 2 +- tests/ui/privacy/issue-75907.stderr | 8 ++++++++ tests/ui/resolve/issue-42944.rs | 2 +- tests/ui/resolve/issue-42944.stderr | 12 +++++++---- 8 files changed, 49 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 58f6fd2b006..928f372d948 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -331,7 +331,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { .iter() .map(|field| respan(field.span, field.ident.map_or(kw::Empty, |ident| ident.name))) .collect(); + let field_vis = vdata.fields().iter().map(|field| field.vis.span).collect(); self.r.field_names.insert(def_id, field_names); + self.r.field_visibility_spans.insert(def_id, field_vis); } fn insert_field_names_extern(&mut self, def_id: DefId) { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 74522f18542..a675a1fb78b 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1451,6 +1451,26 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { .collect(); if non_visible_spans.len() > 0 { + if let Some(visibility_spans) = self.r.field_visibility_spans.get(&def_id) { + err.multipart_suggestion_verbose( + &format!( + "consider making the field{} publicly accessible", + pluralize!(visibility_spans.len()) + ), + visibility_spans + .iter() + .map(|span| { + ( + *span, + if span.lo() == span.hi() { "pub " } else { "pub" } + .to_string(), + ) + }) + .collect(), + Applicability::MaybeIncorrect, + ); + } + let mut m: MultiSpan = non_visible_spans.clone().into(); non_visible_spans .into_iter() diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 2182b736937..84d9794ccf2 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -881,6 +881,10 @@ pub struct Resolver<'a> { /// Used for hints during error reporting. field_names: FxHashMap>>, + /// Span of the privacy modifier in fields of an item `DefId` accessible with dot syntax. + /// Used for hints during error reporting. + field_visibility_spans: FxHashMap>, + /// All imports known to succeed or fail. determined_imports: Vec<&'a Import<'a>>, @@ -1268,6 +1272,7 @@ impl<'a> Resolver<'a> { has_self: FxHashSet::default(), field_names: FxHashMap::default(), + field_visibility_spans: FxHashMap::default(), determined_imports: Vec::new(), indeterminate_imports: Vec::new(), diff --git a/tests/ui/privacy/issue-75906.stderr b/tests/ui/privacy/issue-75906.stderr index 4c6a68646ad..600dc7c876f 100644 --- a/tests/ui/privacy/issue-75906.stderr +++ b/tests/ui/privacy/issue-75906.stderr @@ -9,6 +9,10 @@ note: constructor is not visible here due to private fields | LL | pub struct Bar(u8); | ^^ private field +help: consider making the field publicly accessible + | +LL | pub struct Bar(pub u8); + | +++ error: aborting due to previous error diff --git a/tests/ui/privacy/issue-75907.rs b/tests/ui/privacy/issue-75907.rs index 6da99cf6435..3bed841d13e 100644 --- a/tests/ui/privacy/issue-75907.rs +++ b/tests/ui/privacy/issue-75907.rs @@ -2,7 +2,7 @@ mod foo { pub(crate) struct Foo(u8); - pub(crate) struct Bar(pub u8, u8, Foo); + pub(crate) struct Bar(pub u8, pub(in crate::foo) u8, Foo); pub(crate) fn make_bar() -> Bar { Bar(1, 12, Foo(10)) diff --git a/tests/ui/privacy/issue-75907.stderr b/tests/ui/privacy/issue-75907.stderr index 2f89e31a31a..f7cb874c2cc 100644 --- a/tests/ui/privacy/issue-75907.stderr +++ b/tests/ui/privacy/issue-75907.stderr @@ -11,6 +11,10 @@ LL | let Bar(x, y, Foo(z)) = make_bar(); | ^ ^^^^^^ private field | | | private field +help: consider making the fields publicly accessible + | +LL | pub(crate) struct Bar(pub u8, pub u8, pub Foo); + | ~~~ ~~~ +++ error[E0532]: cannot match against a tuple struct which contains private fields --> $DIR/issue-75907.rs:15:19 @@ -23,6 +27,10 @@ note: constructor is not visible here due to private fields | LL | let Bar(x, y, Foo(z)) = make_bar(); | ^ private field +help: consider making the field publicly accessible + | +LL | pub(crate) struct Foo(pub u8); + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/issue-42944.rs b/tests/ui/resolve/issue-42944.rs index a4404857a56..7e439c10b7b 100644 --- a/tests/ui/resolve/issue-42944.rs +++ b/tests/ui/resolve/issue-42944.rs @@ -1,5 +1,5 @@ mod foo { - pub struct Bx(()); + pub struct Bx(pub(in crate::foo) ()); } mod bar { diff --git a/tests/ui/resolve/issue-42944.stderr b/tests/ui/resolve/issue-42944.stderr index 0ee9fd391fe..4ffa9402c66 100644 --- a/tests/ui/resolve/issue-42944.stderr +++ b/tests/ui/resolve/issue-42944.stderr @@ -7,8 +7,8 @@ LL | Bx(()); note: tuple struct `foo::Bx` exists but is inaccessible --> $DIR/issue-42944.rs:2:5 | -LL | pub struct Bx(()); - | ^^^^^^^^^^^^^^^^^^ not accessible +LL | pub struct Bx(pub(in crate::foo) ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not accessible error[E0423]: cannot initialize a tuple struct which contains private fields --> $DIR/issue-42944.rs:9:9 @@ -19,8 +19,12 @@ LL | Bx(()); note: constructor is not visible here due to private fields --> $DIR/issue-42944.rs:2:19 | -LL | pub struct Bx(()); - | ^^ private field +LL | pub struct Bx(pub(in crate::foo) ()); + | ^^^^^^^^^^^^^^^^^^^^^ private field +help: consider making the field publicly accessible + | +LL | pub struct Bx(pub ()); + | ~~~ error: aborting due to 2 previous errors From eb835093a3bc4dc571c1a612cc2efde85906e63e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 8 Jan 2023 07:18:07 +0000 Subject: [PATCH 3/8] review comment --- compiler/rustc_resolve/src/late/diagnostics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a675a1fb78b..6923ca7ef1b 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1462,7 +1462,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { .map(|span| { ( *span, - if span.lo() == span.hi() { "pub " } else { "pub" } + if span.is_empty() { "pub " } else { "pub" } .to_string(), ) }) From 41e66d902589964cda32a5a89c34023a9f78398b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 10 Jan 2023 20:57:02 +0000 Subject: [PATCH 4/8] review comments: Tweak output * Account for `struct S(pub(super)Ty);` in suggestion * Suggest changing field visibility in E0603 too --- .../rustc_resolve/src/build_reduced_graph.rs | 14 ++- compiler/rustc_resolve/src/diagnostics.rs | 14 ++- .../rustc_resolve/src/late/diagnostics.rs | 15 +-- tests/ui/privacy/privacy5.stderr | 96 +++++++++++++++++++ .../privacy/suggest-making-field-public.fixed | 15 +++ .../ui/privacy/suggest-making-field-public.rs | 15 +++ .../suggest-making-field-public.stderr | 39 ++++++++ tests/ui/resolve/privacy-struct-ctor.stderr | 16 ++++ 8 files changed, 210 insertions(+), 14 deletions(-) create mode 100644 tests/ui/privacy/suggest-making-field-public.fixed create mode 100644 tests/ui/privacy/suggest-making-field-public.rs create mode 100644 tests/ui/privacy/suggest-making-field-public.stderr diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 928f372d948..b1b04c92a75 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -331,8 +331,15 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { .iter() .map(|field| respan(field.span, field.ident.map_or(kw::Empty, |ident| ident.name))) .collect(); - let field_vis = vdata.fields().iter().map(|field| field.vis.span).collect(); self.r.field_names.insert(def_id, field_names); + } + + fn insert_field_visibilities_local(&mut self, def_id: DefId, vdata: &ast::VariantData) { + let field_vis = vdata + .fields() + .iter() + .map(|field| field.vis.span.until(field.ident.map_or(field.ty.span, |i| i.span))) + .collect(); self.r.field_visibility_spans.insert(def_id, field_vis); } @@ -739,6 +746,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { // Record field names for error reporting. self.insert_field_names_local(def_id, vdata); + self.insert_field_visibilities_local(def_id, vdata); // If this is a tuple or unit struct, define a name // in the value namespace as well. @@ -772,6 +780,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id.to_def_id()); self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion)); self.r.visibilities.insert(ctor_def_id, ctor_vis); + // We need the field visibility spans also for the constructor for E0603. + self.insert_field_visibilities_local(ctor_def_id.to_def_id(), vdata); self.r .struct_constructors @@ -785,6 +795,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { // Record field names for error reporting. self.insert_field_names_local(def_id, vdata); + self.insert_field_visibilities_local(def_id, vdata); } ItemKind::Trait(..) => { @@ -1512,6 +1523,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { // Record field names for error reporting. self.insert_field_names_local(def_id.to_def_id(), &variant.data); + self.insert_field_visibilities_local(def_id.to_def_id(), &variant.data); visit::walk_variant(self, variant); } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 7d62d67d64f..1a852de8eed 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -6,7 +6,9 @@ use rustc_ast::{self as ast, Crate, ItemKind, ModKind, NodeId, Path, CRATE_NODE_ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{ + pluralize, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, +}; use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind, PerNS}; @@ -1604,6 +1606,16 @@ impl<'a> Resolver<'a> { err.span_label(ident.span, &format!("private {}", descr)); if let Some(span) = ctor_fields_span { err.span_label(span, "a constructor is private if any of the fields is private"); + if let Res::Def(_, d) = res && let Some(fields) = self.field_visibility_spans.get(&d) { + err.multipart_suggestion_verbose( + &format!( + "consider making the field{} publicly accessible", + pluralize!(fields.len()) + ), + fields.iter().map(|span| (*span, "pub ".to_string())).collect(), + Applicability::MaybeIncorrect, + ); + } } // Print the whole import chain to make it easier to see what happens. diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 6923ca7ef1b..d92f5a7c05e 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1451,22 +1451,13 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { .collect(); if non_visible_spans.len() > 0 { - if let Some(visibility_spans) = self.r.field_visibility_spans.get(&def_id) { + if let Some(fields) = self.r.field_visibility_spans.get(&def_id) { err.multipart_suggestion_verbose( &format!( "consider making the field{} publicly accessible", - pluralize!(visibility_spans.len()) + pluralize!(fields.len()) ), - visibility_spans - .iter() - .map(|span| { - ( - *span, - if span.is_empty() { "pub " } else { "pub" } - .to_string(), - ) - }) - .collect(), + fields.iter().map(|span| (*span, "pub ".to_string())).collect(), Applicability::MaybeIncorrect, ); } diff --git a/tests/ui/privacy/privacy5.stderr b/tests/ui/privacy/privacy5.stderr index 680161272ce..615b0af2762 100644 --- a/tests/ui/privacy/privacy5.stderr +++ b/tests/ui/privacy/privacy5.stderr @@ -12,6 +12,10 @@ note: the tuple struct constructor `A` is defined here | LL | pub struct A(()); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct A(pub ()); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:52:16 @@ -27,6 +31,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:53:16 @@ -42,6 +50,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:56:12 @@ -57,6 +69,10 @@ note: the tuple struct constructor `A` is defined here | LL | pub struct A(()); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct A(pub ()); + | +++ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:57:12 @@ -72,6 +88,10 @@ note: the tuple struct constructor `A` is defined here | LL | pub struct A(()); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct A(pub ()); + | +++ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:58:18 @@ -87,6 +107,10 @@ note: the tuple struct constructor `A` is defined here | LL | pub struct A(()); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct A(pub ()); + | +++ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:59:18 @@ -102,6 +126,10 @@ note: the tuple struct constructor `A` is defined here | LL | pub struct A(()); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct A(pub ()); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:61:12 @@ -117,6 +145,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:62:12 @@ -132,6 +164,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:63:18 @@ -147,6 +183,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:64:18 @@ -162,6 +202,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:65:18 @@ -177,6 +221,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:65:32 @@ -192,6 +240,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:68:12 @@ -207,6 +259,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:69:12 @@ -222,6 +278,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:70:12 @@ -237,6 +297,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:71:12 @@ -252,6 +316,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:72:18 @@ -267,6 +335,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:73:18 @@ -282,6 +354,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:74:18 @@ -297,6 +373,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:75:18 @@ -312,6 +392,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:83:17 @@ -327,6 +411,10 @@ note: the tuple struct constructor `A` is defined here | LL | pub struct A(()); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct A(pub ()); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:84:17 @@ -342,6 +430,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:85:17 @@ -357,6 +449,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:90:20 diff --git a/tests/ui/privacy/suggest-making-field-public.fixed b/tests/ui/privacy/suggest-making-field-public.fixed new file mode 100644 index 00000000000..78e335b3db1 --- /dev/null +++ b/tests/ui/privacy/suggest-making-field-public.fixed @@ -0,0 +1,15 @@ +// run-rustfix +mod a { + pub struct A(pub String); +} + +mod b { + use crate::a::A; + pub fn x() { + A("".into()); //~ ERROR cannot initialize a tuple struct which contains private fields + } +} +fn main() { + a::A("a".into()); //~ ERROR tuple struct constructor `A` is private + b::x(); +} diff --git a/tests/ui/privacy/suggest-making-field-public.rs b/tests/ui/privacy/suggest-making-field-public.rs new file mode 100644 index 00000000000..b65c801d10e --- /dev/null +++ b/tests/ui/privacy/suggest-making-field-public.rs @@ -0,0 +1,15 @@ +// run-rustfix +mod a { + pub struct A(pub(self)String); +} + +mod b { + use crate::a::A; + pub fn x() { + A("".into()); //~ ERROR cannot initialize a tuple struct which contains private fields + } +} +fn main() { + a::A("a".into()); //~ ERROR tuple struct constructor `A` is private + b::x(); +} diff --git a/tests/ui/privacy/suggest-making-field-public.stderr b/tests/ui/privacy/suggest-making-field-public.stderr new file mode 100644 index 00000000000..e92e9aae310 --- /dev/null +++ b/tests/ui/privacy/suggest-making-field-public.stderr @@ -0,0 +1,39 @@ +error[E0603]: tuple struct constructor `A` is private + --> $DIR/suggest-making-field-public.rs:13:8 + | +LL | pub struct A(pub(self)String); + | --------------- a constructor is private if any of the fields is private +... +LL | a::A("a".into()); + | ^ private tuple struct constructor + | +note: the tuple struct constructor `A` is defined here + --> $DIR/suggest-making-field-public.rs:3:5 + | +LL | pub struct A(pub(self)String); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct A(pub String); + | ~~~ + +error[E0423]: cannot initialize a tuple struct which contains private fields + --> $DIR/suggest-making-field-public.rs:9:9 + | +LL | A("".into()); + | ^ + | +note: constructor is not visible here due to private fields + --> $DIR/suggest-making-field-public.rs:3:18 + | +LL | pub struct A(pub(self)String); + | ^^^^^^^^^^^^^^^ private field +help: consider making the field publicly accessible + | +LL | pub struct A(pub String); + | ~~~ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0423, E0603. +For more information about an error, try `rustc --explain E0423`. diff --git a/tests/ui/resolve/privacy-struct-ctor.stderr b/tests/ui/resolve/privacy-struct-ctor.stderr index 17a666a401c..c1fcaaf0573 100644 --- a/tests/ui/resolve/privacy-struct-ctor.stderr +++ b/tests/ui/resolve/privacy-struct-ctor.stderr @@ -53,6 +53,10 @@ note: the tuple struct constructor `Z` is defined here | LL | pub(in m) struct Z(pub(in m::n) u8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub(in m) struct Z(pub u8); + | ~~~ error[E0603]: tuple struct constructor `S` is private --> $DIR/privacy-struct-ctor.rs:29:8 @@ -68,6 +72,10 @@ note: the tuple struct constructor `S` is defined here | LL | pub struct S(u8); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct S(pub u8); + | +++ error[E0603]: tuple struct constructor `S` is private --> $DIR/privacy-struct-ctor.rs:31:19 @@ -83,6 +91,10 @@ note: the tuple struct constructor `S` is defined here | LL | pub struct S(u8); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct S(pub u8); + | +++ error[E0603]: tuple struct constructor `Z` is private --> $DIR/privacy-struct-ctor.rs:35:11 @@ -98,6 +110,10 @@ note: the tuple struct constructor `Z` is defined here | LL | pub(in m) struct Z(pub(in m::n) u8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub(in m) struct Z(pub u8); + | ~~~ error[E0603]: tuple struct constructor `S` is private --> $DIR/privacy-struct-ctor.rs:41:16 From 7aff210ead0eba3b4c6e6b2cbae5157e1ffe0562 Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Mon, 9 Jan 2023 00:00:41 +0100 Subject: [PATCH 5/8] Support eager subdiagnostics again --- .../src/diagnostics/diagnostic_builder.rs | 24 +++++++++++--- compiler/rustc_macros/src/lib.rs | 1 + .../session-diagnostic/diagnostic-derive.rs | 2 -- .../diagnostic-derive.stderr | 32 +++++-------------- 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index 82f6812026a..e405462bbb8 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -382,10 +382,26 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> { return Ok(quote! { #diag.subdiagnostic(#binding); }); } } - (Meta::List(_), "subdiagnostic") => { - throw_invalid_attr!(attr, &meta, |diag| { - diag.help("`subdiagnostic` does not support nested attributes") - }) + (Meta::List(MetaList { ref nested, .. }), "subdiagnostic") => { + if nested.len() == 1 + && let Some(NestedMeta::Meta(Meta::Path(path))) = nested.first() + && path.is_ident("eager") { + let handler = match &self.parent.kind { + DiagnosticDeriveKind::Diagnostic { handler } => handler, + DiagnosticDeriveKind::LintDiagnostic => { + throw_invalid_attr!(attr, &meta, |diag| { + diag.help("eager subdiagnostics are not supported on lints") + }) + } + }; + return Ok(quote! { #diag.eager_subdiagnostic(#handler, #binding); }); + } else { + throw_invalid_attr!(attr, &meta, |diag| { + diag.help( + "`eager` is the only supported nested attribute for `subdiagnostic`", + ) + }) + } } _ => (), } diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index ac916bb6068..bb3722fe156 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -1,5 +1,6 @@ #![feature(allow_internal_unstable)] #![feature(if_let_guard)] +#![feature(let_chains)] #![feature(never_type)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_span)] diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index c19b639a8d5..65d9601e78a 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -723,7 +723,6 @@ struct SubdiagnosticEagerLint { #[diag(compiletest_example)] struct SubdiagnosticEagerCorrect { #[subdiagnostic(eager)] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute note: Note, } @@ -744,7 +743,6 @@ pub(crate) struct SubdiagnosticWithSuggestion { #[diag(compiletest_example)] struct SubdiagnosticEagerSuggestion { #[subdiagnostic(eager)] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute sub: SubdiagnosticWithSuggestion, } diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index f39d32a221c..13e806a434f 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -539,7 +539,7 @@ error: `#[subdiagnostic(...)]` is not a valid attribute LL | #[subdiagnostic(bad)] | ^^^^^^^^^^^^^^^^^^^^^ | - = help: `subdiagnostic` does not support nested attributes + = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic = ...]` is not a valid attribute --> $DIR/diagnostic-derive.rs:693:5 @@ -553,7 +553,7 @@ error: `#[subdiagnostic(...)]` is not a valid attribute LL | #[subdiagnostic(bad, bad)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: `subdiagnostic` does not support nested attributes + = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:709:5 @@ -561,7 +561,7 @@ error: `#[subdiagnostic(...)]` is not a valid attribute LL | #[subdiagnostic("bad")] | ^^^^^^^^^^^^^^^^^^^^^^^ | - = help: `subdiagnostic` does not support nested attributes + = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:717:5 @@ -569,38 +569,22 @@ error: `#[subdiagnostic(...)]` is not a valid attribute LL | #[subdiagnostic(eager)] | ^^^^^^^^^^^^^^^^^^^^^^^ | - = help: `subdiagnostic` does not support nested attributes - -error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:725:5 - | -LL | #[subdiagnostic(eager)] - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: `subdiagnostic` does not support nested attributes - -error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:746:5 - | -LL | #[subdiagnostic(eager)] - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: `subdiagnostic` does not support nested attributes + = help: eager subdiagnostics are not supported on lints error: expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive.rs:777:18 + --> $DIR/diagnostic-derive.rs:775:18 | LL | #[suggestion(code())] | ^^^^^^ error: `code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:785:23 + --> $DIR/diagnostic-derive.rs:783:23 | LL | #[suggestion(code(foo))] | ^^^ error: `code = "..."`/`code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:793:18 + --> $DIR/diagnostic-derive.rs:791:18 | LL | #[suggestion(code = 3)] | ^^^^^^^^ @@ -676,7 +660,7 @@ note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg` --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:LL:CC = note: this error originates in the derive macro `Diagnostic` which comes from the expansion of the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 85 previous errors +error: aborting due to 83 previous errors Some errors have detailed explanations: E0277, E0425. For more information about an error, try `rustc --explain E0277`. From 02005e9f22bf06e74c3ed6ce56be112d7366bd15 Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Wed, 11 Jan 2023 22:46:14 +1300 Subject: [PATCH 6/8] remove unreachable error code `E0490` --- compiler/rustc_error_codes/src/error_codes.rs | 2 +- .../locales/en-US/infer.ftl | 1 - .../src/infer/error_reporting/note.rs | 35 ------------------- .../src/infer/lexical_region_resolve/mod.rs | 23 ++---------- compiler/rustc_infer/src/infer/mod.rs | 4 --- src/tools/tidy/src/error_codes.rs | 6 ++-- 6 files changed, 5 insertions(+), 66 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 686c22bc386..d09463aad76 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -618,7 +618,7 @@ E0791: include_str!("./error_codes/E0791.md"), // E0487, // unsafe use of destructor: destructor might be called while... // E0488, // lifetime of variable does not enclose its declaration // E0489, // type/lifetime parameter not in scope here - E0490, // a value of type `..` is borrowed for too long +// E0490, // removed: unreachable E0523, // two dependencies have same (crate-name, disambiguator) but different SVH // E0526, // shuffle indices are not constant // E0540, // multiple rustc_deprecated attributes diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index c1cb07cf0df..ae0091b0373 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -101,7 +101,6 @@ infer_subtype_2 = ...so that {$requirement -> infer_reborrow = ...so that reference does not outlive borrowed content infer_reborrow_upvar = ...so that closure can access `{$name}` infer_relate_object_bound = ...so that it can be closed over into an object -infer_data_borrowed = ...so that the type `{$name}` is not borrowed for too long infer_reference_outlives_referent = ...so that the reference type `{$name}` does not outlive the data it points at infer_relate_param_bound = ...so that the type `{$name}` will meet its required lifetime bounds{$continues -> [true] ... diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 7bb79d7bda8..7504ed094a3 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -29,15 +29,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { RegionOriginNote::Plain { span, msg: fluent::infer_relate_object_bound } .add_to_diagnostic(err); } - infer::DataBorrowed(ty, span) => { - RegionOriginNote::WithName { - span, - msg: fluent::infer_data_borrowed, - name: &self.ty_to_string(ty), - continues: false, - } - .add_to_diagnostic(err); - } infer::ReferenceOutlivesReferent(ty, span) => { RegionOriginNote::WithName { span, @@ -227,32 +218,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); err } - infer::DataBorrowed(ty, span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0490, - "a value of type `{}` is borrowed for too long", - self.ty_to_string(ty) - ); - note_and_explain_region( - self.tcx, - &mut err, - "the type is valid for ", - sub, - "", - None, - ); - note_and_explain_region( - self.tcx, - &mut err, - "but the borrow lasts for ", - sup, - "", - None, - ); - err - } infer::ReferenceOutlivesReferent(ty, span) => { let mut err = struct_span_err!( self.tcx.sess, diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index da2c6fbc05f..897545046c3 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -702,26 +702,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // Obtain the spans for all the places that can // influence the constraints on this value for // richer diagnostics in `static_impl_trait`. - let influences: Vec = self - .data - .constraints - .iter() - .filter_map(|(constraint, origin)| match (constraint, origin) { - ( - Constraint::VarSubVar(_, sup), - SubregionOrigin::DataBorrowed(_, sp), - ) if sup == &node_vid => Some(*sp), - _ => None, - }) - .collect(); - self.collect_error_for_expanding_node( - graph, - &mut dup_vec, - node_vid, - errors, - influences, - ); + self.collect_error_for_expanding_node(graph, &mut dup_vec, node_vid, errors); } } } @@ -775,7 +757,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { dup_vec: &mut IndexVec>, node_idx: RegionVid, errors: &mut Vec>, - influences: Vec, ) { // Errors in expanding nodes result from a lower-bound that is // not contained by an upper-bound. @@ -830,7 +811,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { lower_bound.region, upper_bound.origin.clone(), upper_bound.region, - influences, + vec![], )); return; } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 6bef3f000a5..0e355b6d1ee 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -410,9 +410,6 @@ pub enum SubregionOrigin<'tcx> { /// Creating a pointer `b` to contents of another reference Reborrow(Span), - /// Data with type `Ty<'tcx>` was borrowed - DataBorrowed(Ty<'tcx>, Span), - /// (&'a &'b T) where a >= b ReferenceOutlivesReferent(Ty<'tcx>, Span), @@ -1974,7 +1971,6 @@ impl<'tcx> SubregionOrigin<'tcx> { RelateParamBound(a, ..) => a, RelateRegionParamBound(a) => a, Reborrow(a) => a, - DataBorrowed(_, a) => a, ReferenceOutlivesReferent(_, a) => a, CompareImplItemObligation { span, .. } => span, AscribeUserTypeProvePredicate(span) => span, diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index 9aacc07e0ab..8b44a09fdf0 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -31,10 +31,8 @@ const IGNORE_DOCTEST_CHECK: &[&str] = &["E0208", "E0464", "E0570", "E0601", "E0602", "E0640", "E0717"]; // Error codes that don't yet have a UI test. This list will eventually be removed. -const IGNORE_UI_TEST_CHECK: &[&str] = &[ - "E0461", "E0465", "E0476", "E0490", "E0514", "E0523", "E0554", "E0640", "E0717", "E0729", - "E0789", -]; +const IGNORE_UI_TEST_CHECK: &[&str] = + &["E0461", "E0465", "E0476", "E0514", "E0523", "E0554", "E0640", "E0717", "E0729", "E0789"]; macro_rules! verbose_print { ($verbose:expr, $($fmt:tt)*) => { From 740f6aaf95e12ad265eb54f78bd56fe3891827bd Mon Sep 17 00:00:00 2001 From: clubby789 Date: Thu, 12 Jan 2023 03:19:08 +0000 Subject: [PATCH 7/8] Fix rendering 'const' for intrinsics --- src/librustdoc/clean/types.rs | 12 ++++++++++-- tests/rustdoc/const-intrinsic.rs | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 tests/rustdoc/const-intrinsic.rs diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 5c63efef717..87de41fde63 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -676,7 +676,8 @@ impl Item { } let header = match *self.kind { ItemKind::ForeignFunctionItem(_) => { - let abi = tcx.fn_sig(self.item_id.as_def_id().unwrap()).abi(); + let def_id = self.item_id.as_def_id().unwrap(); + let abi = tcx.fn_sig(def_id).abi(); hir::FnHeader { unsafety: if abi == Abi::RustIntrinsic { intrinsic_operation_unsafety(tcx, self.item_id.as_def_id().unwrap()) @@ -684,7 +685,14 @@ impl Item { hir::Unsafety::Unsafe }, abi, - constness: hir::Constness::NotConst, + constness: if abi == Abi::RustIntrinsic + && tcx.is_const_fn(def_id) + && is_unstable_const_fn(tcx, def_id).is_none() + { + hir::Constness::Const + } else { + hir::Constness::NotConst + }, asyncness: hir::IsAsync::NotAsync, } } diff --git a/tests/rustdoc/const-intrinsic.rs b/tests/rustdoc/const-intrinsic.rs new file mode 100644 index 00000000000..2fc486d01da --- /dev/null +++ b/tests/rustdoc/const-intrinsic.rs @@ -0,0 +1,25 @@ +#![feature(intrinsics)] +#![feature(staged_api)] + +#![crate_name = "foo"] +#![stable(since="1.0.0", feature="rust1")] + +extern "rust-intrinsic" { + // @has 'foo/fn.transmute.html' + // @has - '//pre[@class="rust fn"]' 'pub const unsafe extern "rust-intrinsic" fn transmute(_: T) -> U' + #[stable(since="1.0.0", feature="rust1")] + #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")] + pub fn transmute(_: T) -> U; + + // @has 'foo/fn.unreachable.html' + // @has - '//pre[@class="rust fn"]' 'pub unsafe extern "rust-intrinsic" fn unreachable() -> !' + #[stable(since="1.0.0", feature="rust1")] + pub fn unreachable() -> !; +} + +extern "C" { + // @has 'foo/fn.needs_drop.html' + // @has - '//pre[@class="rust fn"]' 'pub unsafe extern "C" fn needs_drop() -> !' + #[stable(since="1.0.0", feature="rust1")] + pub fn needs_drop() -> !; +} From fb0ecc028840ae97cc38258f7e2cbbfcd70a8f29 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 12 Jan 2023 06:53:06 +0000 Subject: [PATCH 8/8] Add `WaffleLapkin` to compiler reviewers --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 1f1b1f1110d..a7b4925bc17 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -478,6 +478,7 @@ compiler-team-contributors = [ "@jackh726", "@TaKO8Ki", "@Nilstrieb", + "@WaffleLapkin", ] compiler = [ "compiler-team",