From 3b985b4dd6c51e2939b23a0782579944fdf7a08c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Mon, 5 Sep 2022 00:17:46 +0200 Subject: [PATCH 01/13] Hermit: Add File::set_time stub This is not supported on hermit yet. This change is required for compiling std. --- library/std/src/sys/hermit/fs.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/std/src/sys/hermit/fs.rs b/library/std/src/sys/hermit/fs.rs index 1c5efa94bd36a..f921839cf529f 100644 --- a/library/std/src/sys/hermit/fs.rs +++ b/library/std/src/sys/hermit/fs.rs @@ -41,6 +41,9 @@ pub struct OpenOptions { mode: i32, } +#[derive(Copy, Clone, Debug, Default)] +pub struct FileTimes {} + pub struct FilePermissions(!); pub struct FileType(!); @@ -110,6 +113,11 @@ impl fmt::Debug for FilePermissions { } } +impl FileTimes { + pub fn set_accessed(&mut self, _t: SystemTime) {} + pub fn set_modified(&mut self, _t: SystemTime) {} +} + impl FileType { pub fn is_dir(&self) -> bool { self.0 @@ -344,6 +352,10 @@ impl File { pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> { Err(Error::from_raw_os_error(22)) } + + pub fn set_times(&self, _times: FileTimes) -> io::Result<()> { + Err(Error::from_raw_os_error(22)) + } } impl DirBuilder { From 850090d99c81dde7615e2a7e2111c09650868a48 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Mon, 5 Sep 2022 08:37:20 -0700 Subject: [PATCH 02/13] Avoid UB in the Windows filesystem code in... bootstrap? --- src/bootstrap/Cargo.toml | 1 + src/bootstrap/util.rs | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 2dad41bb18fce..95e711737738a 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -67,6 +67,7 @@ features = [ "psapi", "impl-default", "timezoneapi", + "winbase", ] [dev-dependencies] diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 3a00e258e00e5..0ebabbd5ca5c0 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -197,9 +197,11 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { ptr::null_mut(), ); - let mut data = [0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]; - let db = data.as_mut_ptr() as *mut REPARSE_MOUNTPOINT_DATA_BUFFER; - let buf = &mut (*db).ReparseTarget as *mut u16; + #[repr(C, align(8))] + struct Align8(T); + let mut data = Align8([0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]); + let db = data.0.as_mut_ptr() as *mut REPARSE_MOUNTPOINT_DATA_BUFFER; + let buf = core::ptr::addr_of_mut!((*db).ReparseTarget) as *mut u16; let mut i = 0; // FIXME: this conversion is very hacky let v = br"\??\"; @@ -219,7 +221,7 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { let res = DeviceIoControl( h as *mut _, FSCTL_SET_REPARSE_POINT, - data.as_ptr() as *mut _, + db.cast(), (*db).ReparseDataLength + 8, ptr::null_mut(), 0, From af3343ae299c81a019d9d62d15c10cb99d7ceb89 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Sun, 28 Aug 2022 19:45:19 +0300 Subject: [PATCH 03/13] Migrate E0623 --- .../locales/en-US/infer.ftl | 31 +++- compiler/rustc_infer/src/errors.rs | 173 +++++++++++++++++- .../nice_region_error/different_lifetimes.rs | 147 ++++----------- compiler/rustc_infer/src/lib.rs | 4 + 4 files changed, 234 insertions(+), 121 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 60086cd6e477f..478a4bdf8a966 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -104,9 +104,36 @@ 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] ... -*[false] {""} + [true] ... + *[false] {""} } infer_relate_param_bound_2 = ...that is required by this bound infer_relate_region_param_bound = ...so that the declared lifetime parameter bounds are satisfied infer_compare_impl_item_obligation = ...so that the definition in impl matches the definition from the trait + +infer_nothing = {""} + +infer_lifetime_mismatch = lifetime mismatch + +infer_declared_different = this parameter and the return type are declared with different lifetimes... +infer_data_returned = ...but data{$label_var1_exists -> + [true] {" "}from `{$label_var1}` + *[false] {""} +} is returned here + +infer_data_lifetime_flow = ...but data with one lifetime flows into the other here +infer_declared_multiple = this type is declared with multiple lifetimes... +infer_types_declared_different = these two types are declared with different lifetimes... +infer_data_flows = ...but data{$label_var1_exists -> + [true] -> {" "}from `{$label_var1}` + *[false] -> {""} +} flows{$label_var2_exists -> + [true] -> {" "}into `{$label_var2}` + *[false] -> {""} +} here + +infer_lifetime_param_suggestion = consider introducing a named lifetime parameter{$is_impl -> + [true] {" "}and update trait if needed + *[false] {""} +} +infer_lifetime_param_suggestion_elided = each elided lifetime in input position becomes a distinct lifetime diff --git a/compiler/rustc_infer/src/errors.rs b/compiler/rustc_infer/src/errors.rs index 938f8aa77a5b4..932ba1f35afcf 100644 --- a/compiler/rustc_infer/src/errors.rs +++ b/compiler/rustc_infer/src/errors.rs @@ -1,7 +1,13 @@ -use rustc_errors::{fluent, AddSubdiagnostic, DiagnosticMessage, DiagnosticStyledString}; -use rustc_hir::FnRetTy; +use hir::GenericParamKind; +use rustc_errors::{ + fluent, AddSubdiagnostic, Applicability, DiagnosticMessage, DiagnosticStyledString, +}; +use rustc_hir as hir; +use rustc_hir::{FnRetTy, Ty}; use rustc_macros::SessionDiagnostic; -use rustc_span::{BytePos, Span}; +use rustc_middle::ty::{Region, TyCtxt}; +use rustc_span::symbol::kw; +use rustc_span::{symbol::Ident, BytePos, Span}; use crate::infer::error_reporting::{ need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind}, @@ -252,3 +258,164 @@ impl AddSubdiagnostic for RegionOriginNote<'_> { }; } } + +pub enum LifetimeMismatchLabels { + InRet { + param_span: Span, + ret_span: Span, + span: Span, + label_var1: Option, + }, + Normal { + hir_equal: bool, + ty_sup: Span, + ty_sub: Span, + span: Span, + label_var1: Option, + label_var2: Option, + }, +} + +impl AddSubdiagnostic for LifetimeMismatchLabels { + fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + match self { + LifetimeMismatchLabels::InRet { param_span, ret_span, span, label_var1 } => { + diag.span_label(param_span, fluent::infer::declared_different); + diag.span_label(ret_span, fluent::infer::nothing); + diag.span_label(span, fluent::infer::data_returned); + diag.set_arg("label_var1_exists", label_var1.is_some()); + diag.set_arg("label_var1", label_var1.map(|x| x.to_string()).unwrap_or_default()); + } + LifetimeMismatchLabels::Normal { + hir_equal, + ty_sup, + ty_sub, + span, + label_var1, + label_var2, + } => { + if hir_equal { + diag.span_label(ty_sup, fluent::infer::declared_multiple); + diag.span_label(ty_sub, fluent::infer::nothing); + diag.span_label(span, fluent::infer::data_lifetime_flow); + } else { + diag.span_label(ty_sup, fluent::infer::types_declared_different); + diag.span_label(ty_sub, fluent::infer::nothing); + diag.span_label(span, fluent::infer::data_flows); + diag.set_arg("label_var1_exists", label_var1.is_some()); + diag.set_arg( + "label_var1", + label_var1.map(|x| x.to_string()).unwrap_or_default(), + ); + diag.set_arg("label_var2_exists", label_var2.is_some()); + diag.set_arg( + "label_var2", + label_var2.map(|x| x.to_string()).unwrap_or_default(), + ); + } + } + } + } +} + +pub struct AddLifetimeParamsSuggestion<'a> { + pub tcx: TyCtxt<'a>, + pub sub: Region<'a>, + pub ty_sup: &'a Ty<'a>, + pub ty_sub: &'a Ty<'a>, + pub add_note: bool, +} + +impl AddSubdiagnostic for AddLifetimeParamsSuggestion<'_> { + fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + let mut mk_suggestion = || { + let ( + hir::Ty { kind: hir::TyKind::Rptr(lifetime_sub, _), .. }, + hir::Ty { kind: hir::TyKind::Rptr(lifetime_sup, _), .. }, + ) = (self.ty_sub, self.ty_sup) else { + return false; + }; + + if !lifetime_sub.name.is_anonymous() || !lifetime_sup.name.is_anonymous() { + return false; + }; + + let Some(anon_reg) = self.tcx.is_suitable_region(self.sub) else { + return false; + }; + + let hir_id = self.tcx.hir().local_def_id_to_hir_id(anon_reg.def_id); + + let node = self.tcx.hir().get(hir_id); + let is_impl = matches!(&node, hir::Node::ImplItem(_)); + let generics = match node { + hir::Node::Item(&hir::Item { + kind: hir::ItemKind::Fn(_, ref generics, ..), + .. + }) + | hir::Node::TraitItem(&hir::TraitItem { ref generics, .. }) + | hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => generics, + _ => return false, + }; + + let suggestion_param_name = generics + .params + .iter() + .filter(|p| matches!(p.kind, GenericParamKind::Lifetime { .. })) + .map(|p| p.name.ident().name) + .find(|i| *i != kw::UnderscoreLifetime); + let introduce_new = suggestion_param_name.is_none(); + let suggestion_param_name = + suggestion_param_name.map(|n| n.to_string()).unwrap_or_else(|| "'a".to_owned()); + + debug!(?lifetime_sup.span); + debug!(?lifetime_sub.span); + let make_suggestion = |span: rustc_span::Span| { + if span.is_empty() { + (span, format!("{}, ", suggestion_param_name)) + } else if let Ok("&") = self.tcx.sess.source_map().span_to_snippet(span).as_deref() + { + (span.shrink_to_hi(), format!("{} ", suggestion_param_name)) + } else { + (span, suggestion_param_name.clone()) + } + }; + let mut suggestions = + vec![make_suggestion(lifetime_sub.span), make_suggestion(lifetime_sup.span)]; + + if introduce_new { + let new_param_suggestion = if let Some(first) = + generics.params.iter().find(|p| !p.name.ident().span.is_empty()) + { + (first.span.shrink_to_lo(), format!("{}, ", suggestion_param_name)) + } else { + (generics.span, format!("<{}>", suggestion_param_name)) + }; + + suggestions.push(new_param_suggestion); + } + + diag.multipart_suggestion( + fluent::infer::lifetime_param_suggestion, + suggestions, + Applicability::MaybeIncorrect, + ); + diag.set_arg("is_impl", is_impl); + true + }; + if mk_suggestion() && self.add_note { + diag.note(fluent::infer::lifetime_param_suggestion_elided); + } + } +} + +#[derive(SessionDiagnostic)] +#[diag(infer::lifetime_mismatch, code = "E0623")] +pub struct LifetimeMismatch<'a> { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub labels: LifetimeMismatchLabels, + #[subdiagnostic] + pub suggestion: AddLifetimeParamsSuggestion<'a>, +} diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs index 9a2ab3e32248b..ebd59a3fef795 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -1,6 +1,9 @@ //! Error Reporting for Anonymous Region Lifetime Errors //! where both the regions are anonymous. +use crate::errors::AddLifetimeParamsSuggestion; +use crate::errors::LifetimeMismatch; +use crate::errors::LifetimeMismatchLabels; use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type; use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo; use crate::infer::error_reporting::nice_region_error::NiceRegionError; @@ -8,11 +11,10 @@ use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::SubregionOrigin; use crate::infer::TyCtxt; -use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed}; -use rustc_hir as hir; -use rustc_hir::{GenericParamKind, Ty}; +use rustc_errors::AddSubdiagnostic; +use rustc_errors::{Diagnostic, ErrorGuaranteed}; +use rustc_hir::Ty; use rustc_middle::ty::Region; -use rustc_span::symbol::kw; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// Print the error message for lifetime errors when both the concerned regions are anonymous. @@ -98,137 +100,50 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let sub_is_ret_type = self.is_return_type_anon(scope_def_id_sub, bregion_sub, ty_fndecl_sub); - let span_label_var1 = match anon_param_sup.pat.simple_ident() { - Some(simple_ident) => format!(" from `{}`", simple_ident), - None => String::new(), - }; - - let span_label_var2 = match anon_param_sub.pat.simple_ident() { - Some(simple_ident) => format!(" into `{}`", simple_ident), - None => String::new(), - }; - debug!( "try_report_anon_anon_conflict: sub_is_ret_type={:?} sup_is_ret_type={:?}", sub_is_ret_type, sup_is_ret_type ); - let mut err = struct_span_err!(self.tcx().sess, span, E0623, "lifetime mismatch"); - - match (sup_is_ret_type, sub_is_ret_type) { + let labels = match (sup_is_ret_type, sub_is_ret_type) { (ret_capture @ Some(ret_span), _) | (_, ret_capture @ Some(ret_span)) => { let param_span = if sup_is_ret_type == ret_capture { ty_sub.span } else { ty_sup.span }; - - err.span_label( + LifetimeMismatchLabels::InRet { param_span, - "this parameter and the return type are declared with different lifetimes...", - ); - err.span_label(ret_span, ""); - err.span_label(span, format!("...but data{} is returned here", span_label_var1)); - } - - (None, None) => { - if ty_sup.hir_id == ty_sub.hir_id { - err.span_label(ty_sup.span, "this type is declared with multiple lifetimes..."); - err.span_label(ty_sub.span, ""); - err.span_label(span, "...but data with one lifetime flows into the other here"); - } else { - err.span_label( - ty_sup.span, - "these two types are declared with different lifetimes...", - ); - err.span_label(ty_sub.span, ""); - err.span_label( - span, - format!("...but data{} flows{} here", span_label_var1, span_label_var2), - ); + ret_span, + span, + label_var1: anon_param_sup.pat.simple_ident(), } } - } - if suggest_adding_lifetime_params(self.tcx(), sub, ty_sup, ty_sub, &mut err) { - err.note("each elided lifetime in input position becomes a distinct lifetime"); - } + (None, None) => LifetimeMismatchLabels::Normal { + hir_equal: ty_sup.hir_id == ty_sub.hir_id, + ty_sup: ty_sup.span, + ty_sub: ty_sub.span, + span, + label_var1: anon_param_sup.pat.simple_ident(), + label_var2: anon_param_sub.pat.simple_ident(), + }, + }; - let reported = err.emit(); + let suggestion = + AddLifetimeParamsSuggestion { tcx: self.tcx(), sub, ty_sup, ty_sub, add_note: true }; + let err = LifetimeMismatch { span, labels, suggestion }; + let reported = self.tcx().sess.emit_err(err); Some(reported) } } +/// Currently only used in rustc_borrowck, probably should be +/// removed in favour of public_errors::AddLifetimeParamsSuggestion pub fn suggest_adding_lifetime_params<'tcx>( tcx: TyCtxt<'tcx>, sub: Region<'tcx>, - ty_sup: &Ty<'_>, - ty_sub: &Ty<'_>, + ty_sup: &'tcx Ty<'_>, + ty_sub: &'tcx Ty<'_>, err: &mut Diagnostic, -) -> bool { - let ( - hir::Ty { kind: hir::TyKind::Rptr(lifetime_sub, _), .. }, - hir::Ty { kind: hir::TyKind::Rptr(lifetime_sup, _), .. }, - ) = (ty_sub, ty_sup) else { - return false; - }; - - if !lifetime_sub.name.is_anonymous() || !lifetime_sup.name.is_anonymous() { - return false; - }; - - let Some(anon_reg) = tcx.is_suitable_region(sub) else { - return false; - }; - - let hir_id = tcx.hir().local_def_id_to_hir_id(anon_reg.def_id); - - let node = tcx.hir().get(hir_id); - let is_impl = matches!(&node, hir::Node::ImplItem(_)); - let generics = match node { - hir::Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, ref generics, ..), .. }) - | hir::Node::TraitItem(&hir::TraitItem { ref generics, .. }) - | hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => generics, - _ => return false, - }; - - let suggestion_param_name = generics - .params - .iter() - .filter(|p| matches!(p.kind, GenericParamKind::Lifetime { .. })) - .map(|p| p.name.ident().name) - .find(|i| *i != kw::UnderscoreLifetime); - let introduce_new = suggestion_param_name.is_none(); - let suggestion_param_name = - suggestion_param_name.map(|n| n.to_string()).unwrap_or_else(|| "'a".to_owned()); - - debug!(?lifetime_sup.span); - debug!(?lifetime_sub.span); - let make_suggestion = |span: rustc_span::Span| { - if span.is_empty() { - (span, format!("{}, ", suggestion_param_name)) - } else if let Ok("&") = tcx.sess.source_map().span_to_snippet(span).as_deref() { - (span.shrink_to_hi(), format!("{} ", suggestion_param_name)) - } else { - (span, suggestion_param_name.clone()) - } - }; - let mut suggestions = - vec![make_suggestion(lifetime_sub.span), make_suggestion(lifetime_sup.span)]; - - if introduce_new { - let new_param_suggestion = - if let Some(first) = generics.params.iter().find(|p| !p.name.ident().span.is_empty()) { - (first.span.shrink_to_lo(), format!("{}, ", suggestion_param_name)) - } else { - (generics.span, format!("<{}>", suggestion_param_name)) - }; - - suggestions.push(new_param_suggestion); - } - - let mut sugg = String::from("consider introducing a named lifetime parameter"); - if is_impl { - sugg.push_str(" and update trait if needed"); - } - err.multipart_suggestion(sugg, suggestions, Applicability::MaybeIncorrect); - - true +) { + let suggestion = AddLifetimeParamsSuggestion { tcx, sub, ty_sup, ty_sub, add_note: false }; + suggestion.add_to_diagnostic(err); } diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 931ebca7d0145..5810616fcdbf1 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -36,5 +36,9 @@ extern crate tracing; extern crate rustc_middle; mod errors; +pub mod public_errors { + // Probably would be useful in rustc_borrowck + pub use super::errors::AddLifetimeParamsSuggestion; +} pub mod infer; pub mod traits; From e0e9b21c78e4e6a7a5515944ace4cb0c1f2f9253 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Tue, 30 Aug 2022 18:28:50 +0300 Subject: [PATCH 04/13] Mugrate mismatched_static_lifetime.rs --- .../locales/en-US/infer.ftl | 31 +++ .../src/{errors.rs => errors/mod.rs} | 68 +++++++ .../src/errors/note_and_explain.rs | 176 ++++++++++++++++++ .../mismatched_static_lifetime.rs | 48 +++-- 4 files changed, 303 insertions(+), 20 deletions(-) rename compiler/rustc_infer/src/{errors.rs => errors/mod.rs} (88%) create mode 100644 compiler/rustc_infer/src/errors/note_and_explain.rs diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 478a4bdf8a966..2899b8304bc14 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -137,3 +137,34 @@ infer_lifetime_param_suggestion = consider introducing a named lifetime paramete *[false] {""} } infer_lifetime_param_suggestion_elided = each elided lifetime in input position becomes a distinct lifetime + +infer_region_explanation = {$pref_kind -> + *[should_not_happen] [{$pref_kind}] + [empty] {""} +}{$pref_kind -> + [empty] {""} + *[other] {" "} +}{$desc_kind -> + *[should_not_happen] [{$desc_kind}] + [restatic] the static lifetime + [reempty] the empty lifetime + [reemptyuni] the empty lifetime in universe {$desc_arg} + [revar] lifetime {$desc_arg} + + [as_defined] the lifetime `{$desc_arg}` as defined here + [as_defined_anon] the anonymous lifetime as defined here + [defined_here] the anonymous lifetime defined here + [anon_num_here] the anonymous lifetime #{$desc_num_arg} defined here + [defined_here_reg] the lifetime `{$desc_arg}` as defined here +}{$suff_kind -> + *[should_not_happen] [{$suff_kind}] + [empty]{""} + [continues] ... +} + +infer_mismatched_static_lifetime = incompatible lifetime on type +infer_msl_impl_note = ...does not necessarily outlive the static lifetime introduced by the compatible `impl` +infer_msl_introduces_static = introduces a `'static` lifetime requirement +infer_msl_unmet_req = because this has an unmet lifetime requirement +infer_msl_trait_note = this has an implicit `'static` lifetime requirement +infer_msl_trait_sugg = consider relaxing the implicit `'static` requirement diff --git a/compiler/rustc_infer/src/errors.rs b/compiler/rustc_infer/src/errors/mod.rs similarity index 88% rename from compiler/rustc_infer/src/errors.rs rename to compiler/rustc_infer/src/errors/mod.rs index 932ba1f35afcf..ad8eb2945fa99 100644 --- a/compiler/rustc_infer/src/errors.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -14,6 +14,8 @@ use crate::infer::error_reporting::{ ObligationCauseAsDiagArg, }; +pub mod note_and_explain; + #[derive(SessionDiagnostic)] #[diag(infer::opaque_hidden_type)] pub struct OpaqueHiddenTypeDiag { @@ -419,3 +421,69 @@ pub struct LifetimeMismatch<'a> { #[subdiagnostic] pub suggestion: AddLifetimeParamsSuggestion<'a>, } + +pub mod mismatched_static_lifetime { + use rustc_errors::{self, fluent, AddSubdiagnostic, MultiSpan}; + use rustc_span::Span; + + use super::note_and_explain; + + pub struct LabeledMultiSpan { + pub multi_span: MultiSpan, + pub binding_span: Span, + } + + impl AddSubdiagnostic for LabeledMultiSpan { + fn add_to_diagnostic(mut self, diag: &mut rustc_errors::Diagnostic) { + self.multi_span + .push_span_label(self.binding_span, fluent::infer::msl_introduces_static); + diag.span_note(self.multi_span, fluent::infer::msl_unmet_req); + } + } + + pub struct ImplNote { + pub impl_span: Option, + } + + impl AddSubdiagnostic for ImplNote { + fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + match self.impl_span { + Some(span) => diag.span_note(span, fluent::infer::msl_impl_note), + None => diag.note(fluent::infer::msl_impl_note), + }; + } + } + + #[derive(SessionSubdiagnostic)] + pub enum TraitSubdiag { + #[note(infer::msl_trait_note)] + Note { + #[primary_span] + span: Span, + }, + #[suggestion_verbose( + infer::msl_trait_sugg, + code = " + '_", + applicability = "maybe-incorrect" + )] + Sugg { + #[primary_span] + span: Span, + }, + } + + #[derive(SessionDiagnostic)] + #[diag(infer::mismatched_static_lifetime)] + pub struct MismatchedStaticLifetime<'a> { + #[primary_span] + pub cause_span: Span, + #[subdiagnostic] + pub multispan_subdiag: LabeledMultiSpan, + #[subdiagnostic] + pub expl: Option>, + #[subdiagnostic] + pub impl_note: ImplNote, + #[subdiagnostic] + pub trait_subdiags: Vec, + } +} diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs new file mode 100644 index 0000000000000..92bf3ecd131da --- /dev/null +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -0,0 +1,176 @@ +use crate::infer::error_reporting::nice_region_error::find_anon_type; +use rustc_errors::{self, fluent, AddSubdiagnostic}; +use rustc_middle::ty::{self, TyCtxt}; +use rustc_span::{symbol::kw, Span}; + +#[derive(Default)] +struct DescriptionCtx<'a> { + span: Option, + kind: &'a str, + arg: String, + num_arg: u32, +} + +impl<'a> DescriptionCtx<'a> { + fn new<'tcx>( + tcx: TyCtxt<'tcx>, + region: ty::Region<'tcx>, + alt_span: Option, + ) -> Option { + let mut me = DescriptionCtx::default(); + me.span = alt_span; + match *region { + ty::ReEarlyBound(_) | ty::ReFree(_) => { + return Self::from_early_bound_and_free_regions(tcx, region); + } + ty::ReStatic => { + me.kind = "restatic"; + } + + ty::ReEmpty(ty::UniverseIndex::ROOT) => me.kind = "reempty", + + // uh oh, hope no user ever sees THIS + ty::ReEmpty(ui) => { + me.kind = "reemptyuni"; + me.arg = format!("{:?}", ui); + } + + ty::RePlaceholder(_) => return None, + + // FIXME(#13998) RePlaceholder should probably print like + // ReFree rather than dumping Debug output on the user. + // + // We shouldn't really be having unification failures with ReVar + // and ReLateBound though. + ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => { + me.kind = "revar"; + me.arg = format!("{:?}", region); + } + }; + Some(me) + } + + fn from_early_bound_and_free_regions<'tcx>( + tcx: TyCtxt<'tcx>, + region: ty::Region<'tcx>, + ) -> Option { + let mut me = DescriptionCtx::default(); + let scope = region.free_region_binding_scope(tcx).expect_local(); + match *region { + ty::ReEarlyBound(ref br) => { + let mut sp = tcx.def_span(scope); + if let Some(param) = + tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name)) + { + sp = param.span; + } + if br.has_name() { + me.kind = "as_defined"; + me.arg = br.name.to_string(); + } else { + me.kind = "as_defined_anon"; + }; + me.span = Some(sp) + } + ty::ReFree(ref fr) => { + if !fr.bound_region.is_named() + && let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) + { + me.kind = "defined_here"; + me.span = Some(ty.span); + } else { + match fr.bound_region { + ty::BoundRegionKind::BrNamed(_, name) => { + let mut sp = tcx.def_span(scope); + if let Some(param) = + tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name)) + { + sp = param.span; + } + if name == kw::UnderscoreLifetime { + me.kind = "as_defined_anon"; + } else { + me.kind = "as_defined"; + me.arg = name.to_string(); + }; + me.span = Some(sp); + } + ty::BrAnon(idx) => { + me.kind = "anon_num_here"; + me.num_arg = idx+1; + me.span = Some(tcx.def_span(scope)); + }, + _ => { + me.kind = "defined_here_reg"; + me.arg = region.to_string(); + me.span = Some(tcx.def_span(scope)); + }, + } + } + } + _ => bug!(), + } + Some(me) + } + + fn add_to(self, diag: &mut rustc_errors::Diagnostic) { + diag.set_arg("desc_kind", self.kind); + diag.set_arg("desc_arg", self.arg); + diag.set_arg("desc_num_arg", self.num_arg); + } +} + +pub enum PrefixKind { + Empty, +} + +pub enum SuffixKind { + Continues, +} + +impl PrefixKind { + fn add_to(self, diag: &mut rustc_errors::Diagnostic) { + match self { + Self::Empty => diag.set_arg("pref_kind", "empty"), + }; + } +} + +impl SuffixKind { + fn add_to(self, diag: &mut rustc_errors::Diagnostic) { + match self { + Self::Continues => diag.set_arg("suff_kind", "continues"), + }; + } +} + +pub struct RegionExplanation<'a> { + desc: DescriptionCtx<'a>, + prefix: PrefixKind, + suffix: SuffixKind, +} + +impl RegionExplanation<'_> { + pub fn new<'tcx>( + tcx: TyCtxt<'tcx>, + region: ty::Region<'tcx>, + alt_span: Option, + prefix: PrefixKind, + suffix: SuffixKind, + ) -> Option { + Some(Self { desc: DescriptionCtx::new(tcx, region, alt_span)?, prefix, suffix }) + } +} + +impl AddSubdiagnostic for RegionExplanation<'_> { + fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + if let Some(span) = self.desc.span { + diag.span_note(span, fluent::infer::region_explanation); + } else { + diag.note(fluent::infer::region_explanation); + } + self.desc.add_to(diag); + self.prefix.add_to(diag); + self.suffix.add_to(diag); + } +} diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index c20b96cae2e4f..832a0eaba3b8e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -1,13 +1,14 @@ //! Error Reporting for when the lifetime for a type doesn't match the `impl` selected for a predicate //! to hold. +use crate::errors::mismatched_static_lifetime::{ImplNote, MismatchedStaticLifetime, TraitSubdiag}; +use crate::errors::{mismatched_static_lifetime::LabeledMultiSpan, note_and_explain}; use crate::infer::error_reporting::nice_region_error::NiceRegionError; -use crate::infer::error_reporting::note_and_explain_region; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::{SubregionOrigin, TypeTrace}; use crate::traits::ObligationCauseCode; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::intravisit::Visitor; use rustc_middle::ty::TypeVisitor; @@ -39,12 +40,20 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { = *parent.code() else { return None; }; - let mut err = self.tcx().sess.struct_span_err(cause.span, "incompatible lifetime on type"); + // FIXME: we should point at the lifetime - let mut multi_span: MultiSpan = vec![binding_span].into(); - multi_span.push_span_label(binding_span, "introduces a `'static` lifetime requirement"); - err.span_note(multi_span, "because this has an unmet lifetime requirement"); - note_and_explain_region(self.tcx(), &mut err, "", sup, "...", Some(binding_span)); + let multi_span: MultiSpan = vec![binding_span].into(); + let multispan_subdiag = LabeledMultiSpan { multi_span, binding_span }; + + let expl = note_and_explain::RegionExplanation::new( + self.tcx(), + sup, + Some(binding_span), + note_and_explain::PrefixKind::Empty, + note_and_explain::SuffixKind::Continues, + ); + let mut impl_span = None; + let mut trait_subdiags = Vec::new(); if let Some(impl_node) = self.tcx().hir().get_if_local(*impl_def_id) { // If an impl is local, then maybe this isn't what they want. Try to // be as helpful as possible with implicit lifetimes. @@ -73,31 +82,30 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // there aren't trait objects or because none are implicit, then just // write a single note on the impl itself. - let impl_span = self.tcx().def_span(*impl_def_id); - err.span_note(impl_span, "...does not necessarily outlive the static lifetime introduced by the compatible `impl`"); + impl_span = Some(self.tcx().def_span(*impl_def_id)); } else { // Otherwise, point at all implicit static lifetimes - err.note("...does not necessarily outlive the static lifetime introduced by the compatible `impl`"); for span in &traits { - err.span_note(*span, "this has an implicit `'static` lifetime requirement"); + trait_subdiags.push(TraitSubdiag::Note { span: *span }); // It would be nice to put this immediately under the above note, but they get // pushed to the end. - err.span_suggestion_verbose( - span.shrink_to_hi(), - "consider relaxing the implicit `'static` requirement", - " + '_", - Applicability::MaybeIncorrect, - ); + trait_subdiags.push(TraitSubdiag::Sugg { span: span.shrink_to_hi() }); } } } else { // Otherwise just point out the impl. - let impl_span = self.tcx().def_span(*impl_def_id); - err.span_note(impl_span, "...does not necessarily outlive the static lifetime introduced by the compatible `impl`"); + impl_span = Some(self.tcx().def_span(*impl_def_id)); } - let reported = err.emit(); + let err = MismatchedStaticLifetime { + cause_span: cause.span, + multispan_subdiag, + expl, + impl_note: ImplNote { impl_span }, + trait_subdiags, + }; + let reported = self.tcx().sess.emit_err(err); Some(reported) } } From 3190522294dac32db63b11b579f6b75a4f2f7d8e Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Wed, 31 Aug 2022 15:02:11 +0300 Subject: [PATCH 05/13] Address some comments --- compiler/rustc_infer/src/errors/mod.rs | 113 ++++++++---------- .../src/errors/note_and_explain.rs | 2 +- .../nice_region_error/different_lifetimes.rs | 4 +- .../mismatched_static_lifetime.rs | 11 +- compiler/rustc_infer/src/lib.rs | 4 - 5 files changed, 61 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index ad8eb2945fa99..e191147cdfe4e 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -1,6 +1,6 @@ use hir::GenericParamKind; use rustc_errors::{ - fluent, AddSubdiagnostic, Applicability, DiagnosticMessage, DiagnosticStyledString, + fluent, AddSubdiagnostic, Applicability, DiagnosticMessage, DiagnosticStyledString, MultiSpan, }; use rustc_hir as hir; use rustc_hir::{FnRetTy, Ty}; @@ -273,8 +273,8 @@ pub enum LifetimeMismatchLabels { ty_sup: Span, ty_sub: Span, span: Span, - label_var1: Option, - label_var2: Option, + sup: Option, + sub: Option, }, } @@ -293,8 +293,8 @@ impl AddSubdiagnostic for LifetimeMismatchLabels { ty_sup, ty_sub, span, - label_var1, - label_var2, + sup: label_var1, + sub: label_var2, } => { if hir_equal { diag.span_label(ty_sup, fluent::infer::declared_multiple); @@ -422,68 +422,57 @@ pub struct LifetimeMismatch<'a> { pub suggestion: AddLifetimeParamsSuggestion<'a>, } -pub mod mismatched_static_lifetime { - use rustc_errors::{self, fluent, AddSubdiagnostic, MultiSpan}; - use rustc_span::Span; - - use super::note_and_explain; - - pub struct LabeledMultiSpan { - pub multi_span: MultiSpan, - pub binding_span: Span, - } - - impl AddSubdiagnostic for LabeledMultiSpan { - fn add_to_diagnostic(mut self, diag: &mut rustc_errors::Diagnostic) { - self.multi_span - .push_span_label(self.binding_span, fluent::infer::msl_introduces_static); - diag.span_note(self.multi_span, fluent::infer::msl_unmet_req); - } - } +pub struct IntroducesStaticBecauseUnmetLifetimeReq { + pub unmet_requirements: MultiSpan, + pub binding_span: Span, +} - pub struct ImplNote { - pub impl_span: Option, +impl AddSubdiagnostic for IntroducesStaticBecauseUnmetLifetimeReq { + fn add_to_diagnostic(mut self, diag: &mut rustc_errors::Diagnostic) { + self.unmet_requirements + .push_span_label(self.binding_span, fluent::infer::msl_introduces_static); + diag.span_note(self.unmet_requirements, fluent::infer::msl_unmet_req); } +} - impl AddSubdiagnostic for ImplNote { - fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { - match self.impl_span { - Some(span) => diag.span_note(span, fluent::infer::msl_impl_note), - None => diag.note(fluent::infer::msl_impl_note), - }; - } - } +pub struct ImplNote { + pub impl_span: Option, +} - #[derive(SessionSubdiagnostic)] - pub enum TraitSubdiag { - #[note(infer::msl_trait_note)] - Note { - #[primary_span] - span: Span, - }, - #[suggestion_verbose( - infer::msl_trait_sugg, - code = " + '_", - applicability = "maybe-incorrect" - )] - Sugg { - #[primary_span] - span: Span, - }, +impl AddSubdiagnostic for ImplNote { + fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + match self.impl_span { + Some(span) => diag.span_note(span, fluent::infer::msl_impl_note), + None => diag.note(fluent::infer::msl_impl_note), + }; } +} - #[derive(SessionDiagnostic)] - #[diag(infer::mismatched_static_lifetime)] - pub struct MismatchedStaticLifetime<'a> { +#[derive(SessionSubdiagnostic)] +pub enum TraitSubdiag { + #[note(infer::msl_trait_note)] + Note { #[primary_span] - pub cause_span: Span, - #[subdiagnostic] - pub multispan_subdiag: LabeledMultiSpan, - #[subdiagnostic] - pub expl: Option>, - #[subdiagnostic] - pub impl_note: ImplNote, - #[subdiagnostic] - pub trait_subdiags: Vec, - } + span: Span, + }, + #[suggestion_verbose(infer::msl_trait_sugg, code = " + '_", applicability = "maybe-incorrect")] + Sugg { + #[primary_span] + span: Span, + }, +} + +#[derive(SessionDiagnostic)] +#[diag(infer::mismatched_static_lifetime)] +pub struct MismatchedStaticLifetime<'a> { + #[primary_span] + pub cause_span: Span, + #[subdiagnostic] + pub unmet_lifetime_reqs: IntroducesStaticBecauseUnmetLifetimeReq, + #[subdiagnostic] + pub expl: Option>, + #[subdiagnostic] + pub impl_note: ImplNote, + #[subdiagnostic] + pub trait_subdiags: Vec, } diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index 92bf3ecd131da..c9df277c744c0 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -91,7 +91,7 @@ impl<'a> DescriptionCtx<'a> { me.kind = "as_defined_anon"; } else { me.kind = "as_defined"; - me.arg = name.to_string(); + me.arg = name.to_string(); }; me.span = Some(sp); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs index ebd59a3fef795..3a4320a9a8f1d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -122,8 +122,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ty_sup: ty_sup.span, ty_sub: ty_sub.span, span, - label_var1: anon_param_sup.pat.simple_ident(), - label_var2: anon_param_sub.pat.simple_ident(), + sup: anon_param_sup.pat.simple_ident(), + sub: anon_param_sub.pat.simple_ident(), }, }; diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index 832a0eaba3b8e..1410e2b63b0b8 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -1,8 +1,8 @@ //! Error Reporting for when the lifetime for a type doesn't match the `impl` selected for a predicate //! to hold. -use crate::errors::mismatched_static_lifetime::{ImplNote, MismatchedStaticLifetime, TraitSubdiag}; -use crate::errors::{mismatched_static_lifetime::LabeledMultiSpan, note_and_explain}; +use crate::errors::{note_and_explain, IntroducesStaticBecauseUnmetLifetimeReq}; +use crate::errors::{ImplNote, MismatchedStaticLifetime, TraitSubdiag}; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::{SubregionOrigin, TypeTrace}; @@ -43,7 +43,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // FIXME: we should point at the lifetime let multi_span: MultiSpan = vec![binding_span].into(); - let multispan_subdiag = LabeledMultiSpan { multi_span, binding_span }; + let multispan_subdiag = IntroducesStaticBecauseUnmetLifetimeReq { + unmet_requirements: multi_span, + binding_span, + }; let expl = note_and_explain::RegionExplanation::new( self.tcx(), @@ -100,7 +103,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } let err = MismatchedStaticLifetime { cause_span: cause.span, - multispan_subdiag, + unmet_lifetime_reqs: multispan_subdiag, expl, impl_note: ImplNote { impl_span }, trait_subdiags, diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 5810616fcdbf1..931ebca7d0145 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -36,9 +36,5 @@ extern crate tracing; extern crate rustc_middle; mod errors; -pub mod public_errors { - // Probably would be useful in rustc_borrowck - pub use super::errors::AddLifetimeParamsSuggestion; -} pub mod infer; pub mod traits; From e750d7faa7e18fb3af51de96b35baebcce4123a2 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Fri, 2 Sep 2022 16:05:00 +0300 Subject: [PATCH 06/13] Remove a comment and use IntoDiagnosticArg instead of add_to() where feasible --- .../src/errors/note_and_explain.rs | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index c9df277c744c0..6f1f9522c869d 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -1,5 +1,5 @@ use crate::infer::error_reporting::nice_region_error::find_anon_type; -use rustc_errors::{self, fluent, AddSubdiagnostic}; +use rustc_errors::{self, fluent, AddSubdiagnostic, IntoDiagnosticArg}; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{symbol::kw, Span}; @@ -29,7 +29,6 @@ impl<'a> DescriptionCtx<'a> { ty::ReEmpty(ty::UniverseIndex::ROOT) => me.kind = "reempty", - // uh oh, hope no user ever sees THIS ty::ReEmpty(ui) => { me.kind = "reemptyuni"; me.arg = format!("{:?}", ui); @@ -128,19 +127,23 @@ pub enum SuffixKind { Continues, } -impl PrefixKind { - fn add_to(self, diag: &mut rustc_errors::Diagnostic) { - match self { - Self::Empty => diag.set_arg("pref_kind", "empty"), - }; +impl IntoDiagnosticArg for PrefixKind { + fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { + let kind = match self { + Self::Empty => "empty", + } + .into(); + rustc_errors::DiagnosticArgValue::Str(kind) } } -impl SuffixKind { - fn add_to(self, diag: &mut rustc_errors::Diagnostic) { - match self { - Self::Continues => diag.set_arg("suff_kind", "continues"), - }; +impl IntoDiagnosticArg for SuffixKind { + fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { + let kind = match self { + Self::Continues => "continues", + } + .into(); + rustc_errors::DiagnosticArgValue::Str(kind) } } @@ -170,7 +173,7 @@ impl AddSubdiagnostic for RegionExplanation<'_> { diag.note(fluent::infer::region_explanation); } self.desc.add_to(diag); - self.prefix.add_to(diag); - self.suffix.add_to(diag); + diag.set_arg("pref_kind", self.prefix); + diag.set_arg("suff_kind", self.suffix); } } From 59c567296a8dd2b6c36765dbb14caf68cc9cf9af Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Mon, 5 Sep 2022 19:04:35 +0300 Subject: [PATCH 07/13] Use untranslated messages for now --- compiler/rustc_infer/src/errors/mod.rs | 35 ++++++++++++++++++-------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index e191147cdfe4e..911381b367f46 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -448,18 +448,31 @@ impl AddSubdiagnostic for ImplNote { } } -#[derive(SessionSubdiagnostic)] pub enum TraitSubdiag { - #[note(infer::msl_trait_note)] - Note { - #[primary_span] - span: Span, - }, - #[suggestion_verbose(infer::msl_trait_sugg, code = " + '_", applicability = "maybe-incorrect")] - Sugg { - #[primary_span] - span: Span, - }, + Note { span: Span }, + Sugg { span: Span }, +} + +// FIXME We can't rely on Vec working well at the moment, +// as only the args from one of the subdiagnostics will actually be used. +// This results in an incorrect diagnostic if more than two subdiags with the same slug are added. +// Use untranslated messages for now. +impl AddSubdiagnostic for TraitSubdiag { + fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + match self { + TraitSubdiag::Note { span } => { + diag.span_note(span, "this has an implicit `'static` lifetime requirement"); + } + TraitSubdiag::Sugg { span } => { + diag.span_suggestion_verbose( + span, + "consider relaxing the implicit `'static` requirement", + " + '_".to_owned(), + rustc_errors::Applicability::MaybeIncorrect, + ); + } + } + } } #[derive(SessionDiagnostic)] From cb7ad9e54853aa5bc217a147d74e3289f6c45489 Mon Sep 17 00:00:00 2001 From: IQuant Date: Tue, 6 Sep 2022 17:54:29 +0300 Subject: [PATCH 08/13] Slightly more concise comment Co-authored-by: David Wood --- compiler/rustc_infer/src/errors/mod.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 911381b367f46..5eedca78489b9 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -453,10 +453,7 @@ pub enum TraitSubdiag { Sugg { span: Span }, } -// FIXME We can't rely on Vec working well at the moment, -// as only the args from one of the subdiagnostics will actually be used. -// This results in an incorrect diagnostic if more than two subdiags with the same slug are added. -// Use untranslated messages for now. +// FIXME(#100717) used in `Vec` so requires eager translation/list support impl AddSubdiagnostic for TraitSubdiag { fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { match self { From 5d94d424859933da5beb76d0ad9818fd095b382b Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 4 Sep 2022 00:55:53 +0200 Subject: [PATCH 09/13] Shrink span for bindings with subpatterns. --- compiler/rustc_mir_build/src/build/mod.rs | 2 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 7 ++- ....match_tuple.SimplifyCfg-initial.after.mir | 16 +++--- ...ove_out.move_out_by_subslice.mir_map.0.mir | 8 +-- ...atterns-slice-patterns-box-patterns.stderr | 30 ++++++------ .../borrowck/borrowck-describe-lvalue.stderr | 8 +-- .../borrowck-move-out-from-array-match.stderr | 6 +-- ...ove-out-from-array-no-overlap-match.stderr | 6 +-- ...rowck-move-out-from-array-use-match.stderr | 10 ++-- ...out-from-array-use-no-overlap-match.stderr | 6 +-- .../borrowck-move-out-from-array-use.stderr | 20 ++++---- .../borrowck-move-out-from-array.stderr | 16 +++--- ...ck-slice-pattern-element-loan-array.stderr | 8 +-- ...ck-slice-pattern-element-loan-slice.stderr | 8 +-- .../borrowck-vec-pattern-move-tail.stderr | 2 +- .../borrowck-vec-pattern-nesting.stderr | 2 +- .../ui/moves/move-out-of-array-ref.stderr | 4 +- src/test/ui/moves/move-out-of-slice-2.stderr | 8 +-- src/test/ui/nll/issue-51244.stderr | 2 +- ...can-live-while-the-other-survives-1.stderr | 10 ++-- ...nd-by-move-no-subbindings-fun-param.stderr | 5 +- .../borrowck-move-and-move.stderr | 34 ++++++------- .../borrowck-pat-at-and-box.stderr | 30 +++++------- ...orrowck-pat-by-move-and-ref-inverse.stderr | 40 ++++++--------- .../borrowck-pat-by-move-and-ref.stderr | 49 ++++++++----------- .../borrowck-pat-ref-mut-and-ref.stderr | 42 +++++++--------- .../borrowck-pat-ref-mut-twice.stderr | 32 +++++------- .../copy-and-move-mixed.stderr | 5 +- ...inding-modes-both-sides-independent.stderr | 2 +- .../nested-binding-modes-mut.stderr | 2 +- .../borrowck-move-ref-pattern.stderr | 6 +-- 31 files changed, 190 insertions(+), 236 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 763038c52d7fa..7f992c18a18e4 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -1036,7 +1036,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { VarBindingForm { binding_mode, opt_ty_info, - opt_match_place: Some((Some(place), span)), + opt_match_place: Some((None, span)), pat_span: span, }, ))))) diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index d2f93b679acc5..7e09efe5972a3 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -202,6 +202,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box> { let mut ty = self.typeck_results.node_type(pat.hir_id); + let mut span = pat.span; let kind = match pat.kind { hir::PatKind::Wild => PatKind::Wild, @@ -262,6 +263,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } hir::PatKind::Binding(_, id, ident, ref sub) => { + if let Some(ident_span) = ident.span.find_ancestor_inside(span) { + span = span.with_hi(ident_span.hi()); + } + let bm = *self .typeck_results .pat_binding_modes() @@ -326,7 +331,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { hir::PatKind::Or(ref pats) => PatKind::Or { pats: self.lower_patterns(pats) }, }; - Box::new(Pat { span: pat.span, ty, kind }) + Box::new(Pat { span, ty, kind }) } fn lower_tuple_subpats( diff --git a/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir index d39145973624f..96716a39a2bfd 100644 --- a/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir @@ -8,13 +8,13 @@ fn match_tuple(_1: (u32, bool, Option, u32)) -> u32 { let mut _4: bool; // in scope 0 at $DIR/exponential-or.rs:+2:70: +2:77 let mut _5: bool; // in scope 0 at $DIR/exponential-or.rs:+2:62: +2:67 let mut _6: bool; // in scope 0 at $DIR/exponential-or.rs:+2:62: +2:67 - let _7: u32; // in scope 0 at $DIR/exponential-or.rs:+2:10: +2:21 - let _8: u32; // in scope 0 at $DIR/exponential-or.rs:+2:57: +2:78 + let _7: u32; // in scope 0 at $DIR/exponential-or.rs:+2:10: +2:11 + let _8: u32; // in scope 0 at $DIR/exponential-or.rs:+2:57: +2:58 let mut _9: u32; // in scope 0 at $DIR/exponential-or.rs:+2:83: +2:84 let mut _10: u32; // in scope 0 at $DIR/exponential-or.rs:+2:87: +2:88 scope 1 { - debug y => _7; // in scope 1 at $DIR/exponential-or.rs:+2:10: +2:21 - debug z => _8; // in scope 1 at $DIR/exponential-or.rs:+2:57: +2:78 + debug y => _7; // in scope 1 at $DIR/exponential-or.rs:+2:10: +2:11 + debug z => _8; // in scope 1 at $DIR/exponential-or.rs:+2:57: +2:58 } bb0: { @@ -61,10 +61,10 @@ fn match_tuple(_1: (u32, bool, Option, u32)) -> u32 { } bb9: { - StorageLive(_7); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:21 - _7 = (_1.0: u32); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:21 - StorageLive(_8); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:78 - _8 = (_1.3: u32); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:78 + StorageLive(_7); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:11 + _7 = (_1.0: u32); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:11 + StorageLive(_8); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:58 + _8 = (_1.3: u32); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:58 StorageLive(_9); // scope 1 at $DIR/exponential-or.rs:+2:83: +2:84 _9 = _7; // scope 1 at $DIR/exponential-or.rs:+2:83: +2:84 StorageLive(_10); // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88 diff --git a/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir b/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir index 6e9a8b4d975fa..6a5021139cf61 100644 --- a/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir +++ b/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir @@ -15,9 +15,9 @@ fn move_out_by_subslice() -> () { let mut _11: std::boxed::Box; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 scope 1 { debug a => _1; // in scope 1 at $DIR/uniform_array_move_out.rs:+1:9: +1:10 - let _12: [std::boxed::Box; 2]; // in scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:17 + let _12: [std::boxed::Box; 2]; // in scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:12 scope 4 { - debug _y => _12; // in scope 4 at $DIR/uniform_array_move_out.rs:+2:10: +2:17 + debug _y => _12; // in scope 4 at $DIR/uniform_array_move_out.rs:+2:10: +2:12 } } scope 2 { @@ -77,8 +77,8 @@ fn move_out_by_subslice() -> () { bb6: { StorageDead(_2); // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27 FakeRead(ForLet(None), _1); // scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10 - StorageLive(_12); // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:17 - _12 = move _1[0..2]; // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:17 + StorageLive(_12); // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:12 + _12 = move _1[0..2]; // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:12 _0 = const (); // scope 0 at $DIR/uniform_array_move_out.rs:+0:27: +3:2 drop(_12) -> [return: bb7, unwind: bb9]; // scope 1 at $DIR/uniform_array_move_out.rs:+3:1: +3:2 } diff --git a/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr b/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr index d4f81930843bf..1fd1eb128511b 100644 --- a/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr +++ b/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr @@ -23,7 +23,7 @@ LL | fn bindings_after_at_slice_patterns_move_binding(x: [String; 4]) { | - move occurs because `x` has type `[String; 4]`, which does not implement the `Copy` trait LL | match x { LL | a @ [.., _] => (), - | ----------- value moved here + | - value moved here ... LL | &x; | ^^ value borrowed here after move @@ -32,7 +32,7 @@ error[E0502]: cannot borrow `x` as immutable because it is also borrowed as muta --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:28:5 | LL | ref mut foo @ [.., _] => Some(foo), - | --------------------- mutable borrow occurs here + | ----------- mutable borrow occurs here ... LL | &x; | ^^ immutable borrow occurs here @@ -44,7 +44,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:50:5 | LL | [ref foo @ .., ref bar] => Some(foo), - | ------------ immutable borrow occurs here + | ------- immutable borrow occurs here ... LL | &mut x; | ^^^^^^ mutable borrow occurs here @@ -56,7 +56,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:62:5 | LL | ref foo @ [.., ref bar] => Some(foo), - | ----------------------- immutable borrow occurs here + | ------- immutable borrow occurs here ... LL | &mut x; | ^^^^^^ mutable borrow occurs here @@ -71,7 +71,7 @@ LL | fn bindings_after_at_or_patterns_move(x: Option) { | - move occurs because `x` has type `Option`, which does not implement the `Copy` trait LL | match x { LL | foo @ Some(Test::Foo | Test::Bar) => (), - | --------------------------------- + | --- | | | value moved here | value moved here @@ -83,7 +83,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:86:5 | LL | ref foo @ Some(Test::Foo | Test::Bar) => Some(foo), - | ------------------------------------- immutable borrow occurs here + | ------- immutable borrow occurs here ... LL | &mut x; | ^^^^^^ mutable borrow occurs here @@ -95,7 +95,7 @@ error[E0502]: cannot borrow `x` as immutable because it is also borrowed as muta --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:98:5 | LL | ref mut foo @ Some(Test::Foo | Test::Bar) => Some(foo), - | ----------------------------------------- mutable borrow occurs here + | ----------- mutable borrow occurs here ... LL | &x; | ^^ immutable borrow occurs here @@ -107,7 +107,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:112:5 | LL | ref foo @ Some(box ref s) => Some(foo), - | ------------------------- immutable borrow occurs here + | ------- immutable borrow occurs here ... LL | &mut x; | ^^^^^^ mutable borrow occurs here @@ -122,7 +122,7 @@ LL | fn bindings_after_at_slice_patterns_or_patterns_moves(x: [Option; 4]) | - move occurs because `x` has type `[Option; 4]`, which does not implement the `Copy` trait LL | match x { LL | a @ [.., Some(Test::Foo | Test::Bar)] => (), - | ------------------------------------- + | - | | | value moved here | value moved here @@ -134,7 +134,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:144:5 | LL | ref a @ [ref b @ .., Some(Test::Foo | Test::Bar)] => Some(a), - | ------------------------------------------------- immutable borrow occurs here + | ----- immutable borrow occurs here ... LL | &mut x; | ^^^^^^ mutable borrow occurs here @@ -146,7 +146,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:156:5 | LL | ref a @ [ref b @ .., Some(Test::Foo | Test::Bar)] => Some(b), - | ---------- immutable borrow occurs here + | ----- immutable borrow occurs here ... LL | &mut x; | ^^^^^^ mutable borrow occurs here @@ -158,7 +158,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:170:5 | LL | [_, ref a @ Some(box ref b), ..] => Some(a), - | ----------------------- immutable borrow occurs here + | ----- immutable borrow occurs here ... LL | &mut x; | ^^^^^^ mutable borrow occurs here @@ -170,7 +170,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:186:5 | LL | [_, ref a @ Some(box Test::Foo | box Test::Bar), ..] => Some(a), - | ------------------------------------------- immutable borrow occurs here + | ----- immutable borrow occurs here ... LL | &mut x; | ^^^^^^ mutable borrow occurs here @@ -182,7 +182,7 @@ error[E0502]: cannot borrow `x` as immutable because it is also borrowed as muta --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:200:5 | LL | [_, ref mut a @ Some(box Test::Foo | box Test::Bar), ..] => Some(a), - | ----------------------------------------------- mutable borrow occurs here + | --------- mutable borrow occurs here ... LL | &x; | ^^ immutable borrow occurs here @@ -194,7 +194,7 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:214:5 | LL | ref a @ [_, ref b @ Some(box Test::Foo | box Test::Bar), ..] => Some(a), - | ------------------------------------------------------------ immutable borrow occurs here + | ----- immutable borrow occurs here ... LL | &mut x; | ^^^^^^ mutable borrow occurs here diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr index cfcc62de4383b..2c1b9c10d4660 100644 --- a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr @@ -200,7 +200,7 @@ LL | let x = &mut v; | ------ borrow of `v` occurs here LL | match v { LL | &[x @ ..] => println!("{:?}", x), - | ^^^^^^ use of borrowed `v` + | ^ use of borrowed `v` ... LL | drop(x); | - borrow later used here @@ -212,7 +212,7 @@ LL | let x = &mut v; | ------ borrow of `v` occurs here ... LL | &[_, x @ ..] => println!("{:?}", x), - | ^^^^^^ use of borrowed `v` + | ^ use of borrowed `v` ... LL | drop(x); | - borrow later used here @@ -224,7 +224,7 @@ LL | let x = &mut v; | ------ borrow of `v` occurs here ... LL | &[x @ .., _] => println!("{:?}", x), - | ^^^^^^ use of borrowed `v` + | ^ use of borrowed `v` ... LL | drop(x); | - borrow later used here @@ -236,7 +236,7 @@ LL | let x = &mut v; | ------ borrow of `v` occurs here ... LL | &[_, x @ .., _] => println!("{:?}", x), - | ^^^^^^ use of borrowed `v` + | ^ use of borrowed `v` ... LL | drop(x); | - borrow later used here diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr index 3249aae8f44a3..346b82a266644 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr @@ -79,7 +79,7 @@ error[E0382]: use of moved value: `a[..].0` --> $DIR/borrowck-move-out-from-array-match.rs:89:11 | LL | [_y @ .., _, _] => {} - | ------- value moved here + | -- value moved here ... LL | [(_x, _), _, _] => {} | ^^ value used here after move @@ -90,7 +90,7 @@ error[E0382]: use of moved value: `a[..].0` --> $DIR/borrowck-move-out-from-array-match.rs:99:15 | LL | [_, _, _y @ ..] => {} - | ------- value moved here + | -- value moved here ... LL | [.., (_x, _)] => {} | ^^ value used here after move @@ -101,7 +101,7 @@ error[E0382]: use of partially moved value: `a` --> $DIR/borrowck-move-out-from-array-match.rs:110:11 | LL | [x @ .., _] => {} - | ------ value partially moved here + | - value partially moved here LL | } LL | match a { | ^ value used here after partial move diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr index c198002265b73..6c6a25c251e70 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr @@ -68,7 +68,7 @@ error[E0382]: use of partially moved value: `a` --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:85:11 | LL | [_, _y @ ..] => {} - | ------- value partially moved here + | -- value partially moved here LL | } LL | match a { | ^ value used here after partial move @@ -79,7 +79,7 @@ error[E0382]: use of partially moved value: `a` --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:96:11 | LL | [_y @ .., _] => {} - | ------- value partially moved here + | -- value partially moved here LL | } LL | match a { | ^ value used here after partial move @@ -90,7 +90,7 @@ error[E0382]: use of partially moved value: `a` --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:109:11 | LL | [x @ .., _, _] => {} - | ------ value partially moved here + | - value partially moved here LL | } LL | match a { | ^ value used here after partial move diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr index 8f2da9d203b0d..77702e145df81 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr @@ -79,7 +79,7 @@ error[E0382]: borrow of moved value: `a[..]` --> $DIR/borrowck-move-out-from-array-use-match.rs:89:11 | LL | [_y @ .., _, _] => {} - | ------- value moved here + | -- value moved here ... LL | [(ref _x, _), _, _] => {} | ^^^^^^ value borrowed here after move @@ -90,7 +90,7 @@ error[E0382]: borrow of moved value: `a[..]` --> $DIR/borrowck-move-out-from-array-use-match.rs:99:15 | LL | [_, _, _y @ ..] => {} - | ------- value moved here + | -- value moved here ... LL | [.., (ref _x, _)] => {} | ^^^^^^ value borrowed here after move @@ -101,7 +101,7 @@ error[E0382]: use of partially moved value: `a` --> $DIR/borrowck-move-out-from-array-use-match.rs:110:11 | LL | [x @ .., _] => {} - | ------ value partially moved here + | - value partially moved here LL | } LL | match a { | ^ value used here after partial move @@ -134,7 +134,7 @@ error[E0382]: use of partially moved value: `a` --> $DIR/borrowck-move-out-from-array-use-match.rs:139:5 | LL | [_, _, _x @ ..] => {} - | ------- value partially moved here + | -- value partially moved here LL | } LL | a[0] = Default::default(); | ^^^^ value used here after partial move @@ -145,7 +145,7 @@ error[E0382]: use of partially moved value: `a` --> $DIR/borrowck-move-out-from-array-use-match.rs:147:5 | LL | [_, _, _x @ ..] => {} - | ------- value partially moved here + | -- value partially moved here LL | } LL | a[0].1 = Default::default(); | ^^^^ value used here after partial move diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr index 4b27f03dc4589..6cc2c2f7a984c 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr @@ -68,7 +68,7 @@ error[E0382]: use of partially moved value: `a` --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:85:11 | LL | [_, _y @ ..] => {} - | ------- value partially moved here + | -- value partially moved here LL | } LL | match a { | ^ value used here after partial move @@ -79,7 +79,7 @@ error[E0382]: use of partially moved value: `a` --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:96:11 | LL | [_y @ .., _] => {} - | ------- value partially moved here + | -- value partially moved here LL | } LL | match a { | ^ value used here after partial move @@ -90,7 +90,7 @@ error[E0382]: use of partially moved value: `a` --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:109:11 | LL | [x @ .., _, _] => {} - | ------ value partially moved here + | - value partially moved here LL | } LL | match a { | ^ value used here after partial move diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr index b0bad6e997887..9add7553afa70 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr @@ -34,7 +34,7 @@ error[E0382]: borrow of partially moved value: `a` LL | let [_x, _, _] = a; | -- value partially moved here LL | let [ref _y @ .., _, _] = a; - | ^^^^^^^^^^^ value borrowed here after partial move + | ^^^^^^ value borrowed here after partial move | = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait @@ -44,7 +44,7 @@ error[E0382]: borrow of partially moved value: `a` LL | let [.., _x] = a; | -- value partially moved here LL | let [_, _, ref _y @ ..] = a; - | ^^^^^^^^^^^ value borrowed here after partial move + | ^^^^^^ value borrowed here after partial move | = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait @@ -54,7 +54,7 @@ error[E0382]: borrow of partially moved value: `a` LL | let [(_x, _), _, _] = a; | -- value partially moved here LL | let [ref _y @ .., _, _] = a; - | ^^^^^^^^^^^ value borrowed here after partial move + | ^^^^^^ value borrowed here after partial move | = note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait @@ -64,7 +64,7 @@ error[E0382]: borrow of partially moved value: `a` LL | let [.., (_x, _)] = a; | -- value partially moved here LL | let [_, _, ref _y @ ..] = a; - | ^^^^^^^^^^^ value borrowed here after partial move + | ^^^^^^ value borrowed here after partial move | = note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait @@ -72,7 +72,7 @@ error[E0382]: borrow of moved value: `a[..]` --> $DIR/borrowck-move-out-from-array-use.rs:54:11 | LL | let [_y @ .., _, _] = a; - | ------- value moved here + | -- value moved here LL | let [(ref _x, _), _, _] = a; | ^^^^^^ value borrowed here after move | @@ -82,7 +82,7 @@ error[E0382]: borrow of moved value: `a[..]` --> $DIR/borrowck-move-out-from-array-use.rs:60:15 | LL | let [_, _, _y @ ..] = a; - | ------- value moved here + | -- value moved here LL | let [.., (ref _x, _)] = a; | ^^^^^^ value borrowed here after move | @@ -92,9 +92,9 @@ error[E0382]: borrow of partially moved value: `a` --> $DIR/borrowck-move-out-from-array-use.rs:68:13 | LL | let [x @ .., _] = a; - | ------ value partially moved here + | - value partially moved here LL | let [_, ref _y @ ..] = a; - | ^^^^^^^^^^^ value borrowed here after partial move + | ^^^^^^ value borrowed here after partial move | = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait @@ -122,7 +122,7 @@ error[E0382]: use of partially moved value: `a` --> $DIR/borrowck-move-out-from-array-use.rs:88:5 | LL | let [_, _, _x @ ..] = a; - | ------- value partially moved here + | -- value partially moved here LL | a[0] = Default::default(); | ^^^^ value used here after partial move | @@ -132,7 +132,7 @@ error[E0382]: use of partially moved value: `a` --> $DIR/borrowck-move-out-from-array-use.rs:94:5 | LL | let [_, _, _x @ ..] = a; - | ------- value partially moved here + | -- value partially moved here LL | a[0].1 = Default::default(); | ^^^^ value used here after partial move | diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr index 1fc2b292b84c7..363effcfe5322 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr @@ -34,7 +34,7 @@ error[E0382]: use of partially moved value: `a` LL | let [_x, _, _] = a; | -- value partially moved here LL | let [_y @ .., _, _] = a; - | ^^^^^^^ value used here after partial move + | ^^ value used here after partial move | = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait @@ -44,7 +44,7 @@ error[E0382]: use of partially moved value: `a` LL | let [.., _x] = a; | -- value partially moved here LL | let [_, _, _y @ ..] = a; - | ^^^^^^^ value used here after partial move + | ^^ value used here after partial move | = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait @@ -54,7 +54,7 @@ error[E0382]: use of partially moved value: `a` LL | let [(_x, _), _, _] = a; | -- value partially moved here LL | let [_y @ .., _, _] = a; - | ^^^^^^^ value used here after partial move + | ^^ value used here after partial move | = note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait @@ -64,7 +64,7 @@ error[E0382]: use of partially moved value: `a` LL | let [.., (_x, _)] = a; | -- value partially moved here LL | let [_, _, _y @ ..] = a; - | ^^^^^^^ value used here after partial move + | ^^ value used here after partial move | = note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait @@ -72,7 +72,7 @@ error[E0382]: use of moved value: `a[..].0` --> $DIR/borrowck-move-out-from-array.rs:54:11 | LL | let [_y @ .., _, _] = a; - | ------- value moved here + | -- value moved here LL | let [(_x, _), _, _] = a; | ^^ value used here after move | @@ -82,7 +82,7 @@ error[E0382]: use of moved value: `a[..].0` --> $DIR/borrowck-move-out-from-array.rs:60:15 | LL | let [_, _, _y @ ..] = a; - | ------- value moved here + | -- value moved here LL | let [.., (_x, _)] = a; | ^^ value used here after move | @@ -92,9 +92,9 @@ error[E0382]: use of partially moved value: `a` --> $DIR/borrowck-move-out-from-array.rs:68:13 | LL | let [x @ .., _] = a; - | ------ value partially moved here + | - value partially moved here LL | let [_, _y @ ..] = a; - | ^^^^^^^ value used here after partial move + | ^^ value used here after partial move | = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr index b8ac7a3a4469d..f4324110ccb8e 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr @@ -57,7 +57,7 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im LL | let [ref first, ref second, ..] = *s; | ---------- immutable borrow occurs here LL | let [_, ref mut tail @ ..] = *s; - | ^^^^^^^^^^^^^^^^^ mutable borrow occurs here + | ^^^^^^^^^^^^ mutable borrow occurs here LL | nop(&[first, second]); | ------ immutable borrow later used here @@ -67,7 +67,7 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im LL | let [.., ref second, ref first] = *s; | ---------- immutable borrow occurs here LL | let [ref mut tail @ .., _] = *s; - | ^^^^^^^^^^^^^^^^^ mutable borrow occurs here + | ^^^^^^^^^^^^ mutable borrow occurs here LL | nop(&[first, second]); | ------ immutable borrow later used here @@ -75,9 +75,9 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im --> $DIR/borrowck-slice-pattern-element-loan-array.rs:46:10 | LL | let [_, ref s1 @ ..] = *s; - | ----------- immutable borrow occurs here + | ------ immutable borrow occurs here LL | let [ref mut s2 @ .., _, _] = *s; - | ^^^^^^^^^^^^^^^ mutable borrow occurs here + | ^^^^^^^^^^ mutable borrow occurs here LL | nop_subslice(s1); | -- immutable borrow later used here diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr index d3388e071aa53..f9a63bd49dd57 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr @@ -88,7 +88,7 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im LL | if let [ref first, ref second, ..] = *s { | ---------- immutable borrow occurs here LL | if let [_, ref mut tail @ ..] = *s { - | ^^^^^^^^^^^^^^^^^ mutable borrow occurs here + | ^^^^^^^^^^^^ mutable borrow occurs here LL | nop(&[first, second]); | ------ immutable borrow later used here @@ -98,7 +98,7 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im LL | if let [.., ref second, ref first] = *s { | ---------- immutable borrow occurs here LL | if let [ref mut tail @ .., _] = *s { - | ^^^^^^^^^^^^^^^^^ mutable borrow occurs here + | ^^^^^^^^^^^^ mutable borrow occurs here LL | nop(&[first, second]); | ------ immutable borrow later used here @@ -106,9 +106,9 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:65:17 | LL | if let [_, _, _, ref s1 @ ..] = *s { - | ----------- immutable borrow occurs here + | ------ immutable borrow occurs here LL | if let [ref mut s2 @ .., _, _, _] = *s { - | ^^^^^^^^^^^^^^^ mutable borrow occurs here + | ^^^^^^^^^^ mutable borrow occurs here LL | nop_subslice(s1); | -- immutable borrow later used here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr index ff70ba9fcca8b..0ac7df944d781 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr @@ -2,7 +2,7 @@ error[E0506]: cannot assign to `a[_]` because it is borrowed --> $DIR/borrowck-vec-pattern-move-tail.rs:8:5 | LL | [1, 2, ref tail @ ..] => tail, - | ------------- borrow of `a[_]` occurs here + | -------- borrow of `a[_]` occurs here ... LL | a[2] = 0; | ^^^^^^^^ assignment to borrowed `a[_]` occurs here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr index ddd89afe5bf91..c3bcb7de65daa 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr @@ -14,7 +14,7 @@ error[E0506]: cannot assign to `vec[_]` because it is borrowed --> $DIR/borrowck-vec-pattern-nesting.rs:23:13 | LL | &mut [ref _b @ ..] => { - | ----------- borrow of `vec[_]` occurs here + | ------ borrow of `vec[_]` occurs here LL | LL | vec[0] = Box::new(4); | ^^^^^^ assignment to borrowed `vec[_]` occurs here diff --git a/src/test/ui/moves/move-out-of-array-ref.stderr b/src/test/ui/moves/move-out-of-array-ref.stderr index fd682e56ae1de..0caa0b83a4c7c 100644 --- a/src/test/ui/moves/move-out-of-array-ref.stderr +++ b/src/test/ui/moves/move-out-of-array-ref.stderr @@ -13,7 +13,7 @@ error[E0508]: cannot move out of type `[D; 4]`, a non-copy array --> $DIR/move-out-of-array-ref.rs:13:27 | LL | let [_, s @ .. , _] = *a; - | ------ ^^ + | - ^^ | | | | | cannot move out of here | | help: consider borrowing here: `&*a` @@ -35,7 +35,7 @@ error[E0508]: cannot move out of type `[D; 4]`, a non-copy array --> $DIR/move-out-of-array-ref.rs:23:27 | LL | let [_, s @ .. , _] = *a; - | ------ ^^ + | - ^^ | | | | | cannot move out of here | | help: consider borrowing here: `&*a` diff --git a/src/test/ui/moves/move-out-of-slice-2.stderr b/src/test/ui/moves/move-out-of-slice-2.stderr index 9a863bf31a7fb..93b0dcfc2d18a 100644 --- a/src/test/ui/moves/move-out-of-slice-2.stderr +++ b/src/test/ui/moves/move-out-of-slice-2.stderr @@ -14,7 +14,7 @@ LL | match *a { | ^^ cannot move out of here LL | LL | [a @ ..] => {} - | ------ + | - | | | data moved here | move occurs because `a` has type `[A]`, which does not implement the `Copy` trait @@ -26,7 +26,7 @@ LL | match *b { | ^^ cannot move out of here LL | LL | [_, _, b @ .., _] => {} - | ------ + | - | | | data moved here | move occurs because `b` has type `[A]`, which does not implement the `Copy` trait @@ -38,7 +38,7 @@ LL | match *c { | ^^ cannot move out of here LL | LL | [c @ ..] => {} - | ------ + | - | | | data moved here | move occurs because `c` has type `[C]`, which does not implement the `Copy` trait @@ -50,7 +50,7 @@ LL | match *d { | ^^ cannot move out of here LL | LL | [_, _, d @ .., _] => {} - | ------ + | - | | | data moved here | move occurs because `d` has type `[C]`, which does not implement the `Copy` trait diff --git a/src/test/ui/nll/issue-51244.stderr b/src/test/ui/nll/issue-51244.stderr index 19f0223a357a5..dcb6f9fec18b6 100644 --- a/src/test/ui/nll/issue-51244.stderr +++ b/src/test/ui/nll/issue-51244.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `*my_ref`, which is behind a `&` reference --> $DIR/issue-51244.rs:3:5 | LL | let ref my_ref @ _ = 0; - | -------------- help: consider changing this to be a mutable reference: `ref mut my_ref @ _` + | ---------- help: consider changing this to be a mutable reference: `ref mut my_ref` LL | *my_ref = 0; | ^^^^^^^^^^^ `my_ref` is a `&` reference, so the data it refers to cannot be written diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr index 4249a74b3ed62..fad84dda0e192 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr @@ -40,9 +40,8 @@ error[E0382]: borrow of moved value --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:12:14 | LL | Some(ref _y @ _z) => {} - | ^^^^^^^^^-- - | | | - | | value moved here + | ^^^^^^ -- value moved here + | | | value borrowed here after move | = note: move occurs because value has type `X`, which does not implement the `Copy` trait @@ -55,9 +54,8 @@ error[E0382]: borrow of moved value --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:26:14 | LL | Some(ref mut _y @ _z) => {} - | ^^^^^^^^^^^^^-- - | | | - | | value moved here + | ^^^^^^^^^^ -- value moved here + | | | value borrowed here after move | = note: move occurs because value has type `X`, which does not implement the `Copy` trait diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr index ee0885a014aa4..a481ca4683382 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr @@ -2,9 +2,8 @@ error[E0382]: use of partially moved value --> $DIR/bind-by-move-no-subbindings-fun-param.rs:7:6 | LL | fn f(a @ A(u): A) -> Box { - | ^^^^^^-^ - | | | - | | value partially moved here + | ^ - value partially moved here + | | | value used here after partial move | = note: partial move occurs because value has type `Box`, which does not implement the `Copy` trait diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr index 8e00bf5c328be..83751843b1b81 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr @@ -2,7 +2,7 @@ error[E0382]: use of moved value --> $DIR/borrowck-move-and-move.rs:11:9 | LL | let a @ b = U; - | ^^^^- - move occurs because value has type `U`, which does not implement the `Copy` trait + | ^ - - move occurs because value has type `U`, which does not implement the `Copy` trait | | | | | value moved here | value used here after move @@ -11,9 +11,8 @@ error[E0382]: use of partially moved value --> $DIR/borrowck-move-and-move.rs:13:9 | LL | let a @ (b, c) = (U, U); - | ^^^^^^^^-^ - | | | - | | value partially moved here + | ^ - value partially moved here + | | | value used here after partial move | = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait @@ -22,9 +21,8 @@ error[E0382]: use of partially moved value --> $DIR/borrowck-move-and-move.rs:15:9 | LL | let a @ (b, c) = (u(), u()); - | ^^^^^^^^-^ - | | | - | | value partially moved here + | ^ - value partially moved here + | | | value used here after partial move | = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait @@ -35,9 +33,8 @@ error[E0382]: use of moved value LL | match Ok(U) { | ----- move occurs because value has type `Result`, which does not implement the `Copy` trait LL | a @ Ok(b) | a @ Err(b) => {} - | -------^- - | | | - | | value used here after move + | - ^ value used here after move + | | | value moved here error[E0382]: use of moved value @@ -46,18 +43,16 @@ error[E0382]: use of moved value LL | match Ok(U) { | ----- move occurs because value has type `Result`, which does not implement the `Copy` trait LL | a @ Ok(b) | a @ Err(b) => {} - | --------^- - | | | - | | value used here after move + | - ^ value used here after move + | | | value moved here error[E0382]: use of partially moved value --> $DIR/borrowck-move-and-move.rs:25:9 | LL | xs @ [a, .., b] => {} - | ^^^^^^^^^^^^^-^ - | | | - | | value partially moved here + | ^^ - value partially moved here + | | | value used here after partial move | = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait @@ -66,9 +61,8 @@ error[E0382]: use of partially moved value --> $DIR/borrowck-move-and-move.rs:29:9 | LL | xs @ [_, ys @ .., _] => {} - | ^^^^^^^^^-------^^^^ - | | | - | | value partially moved here + | ^^ -- value partially moved here + | | | value used here after partial move | = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait @@ -77,7 +71,7 @@ error[E0382]: use of moved value --> $DIR/borrowck-move-and-move.rs:22:12 | LL | fn fun(a @ b: U) {} - | ^^^^- + | ^---- | | | | | value moved here | value used here after move diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr index 4b2048855ebb4..002c7609f6109 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr @@ -74,9 +74,8 @@ error[E0382]: borrow of moved value --> $DIR/borrowck-pat-at-and-box.rs:31:9 | LL | let ref a @ box b = Box::new(NC); - | ^^^^^^^^^^^^- - | | | - | | value moved here + | ^^^^^ - value moved here + | | | value borrowed here after move | = note: move occurs because value has type `NC`, which does not implement the `Copy` trait @@ -85,9 +84,8 @@ error[E0502]: cannot borrow value as immutable because it is also borrowed as mu --> $DIR/borrowck-pat-at-and-box.rs:38:9 | LL | let ref a @ box ref mut b = Box::new(NC); - | ^^^^^^^^^^^^--------- - | | | - | | mutable borrow occurs here + | ^^^^^ --------- mutable borrow occurs here + | | | immutable borrow occurs here ... LL | *b = NC; @@ -97,9 +95,8 @@ error[E0502]: cannot borrow value as immutable because it is also borrowed as mu --> $DIR/borrowck-pat-at-and-box.rs:42:9 | LL | let ref a @ box ref mut b = Box::new(NC); - | ^^^^^^^^^^^^--------- - | | | - | | mutable borrow occurs here + | ^^^^^ --------- mutable borrow occurs here + | | | immutable borrow occurs here ... LL | *b = NC; @@ -109,9 +106,8 @@ error[E0502]: cannot borrow value as mutable because it is also borrowed as immu --> $DIR/borrowck-pat-at-and-box.rs:48:9 | LL | let ref mut a @ box ref b = Box::new(NC); - | ^^^^^^^^^^^^^^^^----- - | | | - | | immutable borrow occurs here + | ^^^^^^^^^ ----- immutable borrow occurs here + | | | mutable borrow occurs here ... LL | drop(b); @@ -121,9 +117,8 @@ error[E0502]: cannot borrow value as mutable because it is also borrowed as immu --> $DIR/borrowck-pat-at-and-box.rs:62:9 | LL | ref mut a @ box ref b => { - | ^^^^^^^^^^^^^^^^----- - | | | - | | immutable borrow occurs here + | ^^^^^^^^^ ----- immutable borrow occurs here + | | | mutable borrow occurs here ... LL | drop(b); @@ -133,9 +128,8 @@ error[E0502]: cannot borrow value as mutable because it is also borrowed as immu --> $DIR/borrowck-pat-at-and-box.rs:54:11 | LL | fn f5(ref mut a @ box ref b: Box) { - | ^^^^^^^^^^^^^^^^----- - | | | - | | immutable borrow occurs here + | ^^^^^^^^^ ----- immutable borrow occurs here + | | | mutable borrow occurs here ... LL | drop(b); diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr index bc2c1625fd0ef..a9e66de084242 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr @@ -262,9 +262,8 @@ error[E0382]: use of partially moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:9 | LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); - | ^^^^^^^^^^^^^^^^^^^^^^^^---------^ - | | | - | | value partially moved here + | ^ - value partially moved here + | | | value used here after partial move | = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait @@ -273,9 +272,8 @@ error[E0382]: use of partially moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:33:9 | LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); - | ^^^^^^^^^^^^^^^^^^^^^^^^---------^ - | | | - | | value partially moved here + | ^ - value partially moved here + | | | value used here after partial move | = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait @@ -286,10 +284,7 @@ error[E0382]: use of moved value LL | match Some((U, U)) { | ------------ move occurs because value has type `Option<(U, U)>`, which does not implement the `Copy` trait LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} - | -----------------------------^^^^^^^^^-- - | | | - | | value used here after move - | value moved here + | - value moved here ^ value used here after move error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:55:30 @@ -297,9 +292,8 @@ error[E0382]: borrow of moved value LL | match Some([U, U]) { | ------------ move occurs because value has type `Option<[U; 2]>`, which does not implement the `Copy` trait LL | mut a @ Some([ref b, ref mut c]) => {} - | ---------------------^^^^^^^^^-- - | | | - | | value borrowed here after move + | ----- ^^^^^^^^^ value borrowed here after move + | | | value moved here error[E0382]: borrow of moved value @@ -308,9 +302,8 @@ error[E0382]: borrow of moved value LL | match Some(u()) { | --------- move occurs because value has type `Option`, which does not implement the `Copy` trait LL | a @ Some(ref b) => {} - | ---------^^^^^- - | | | - | | value borrowed here after move + | - ^^^^^ value borrowed here after move + | | | value moved here error[E0382]: use of moved value @@ -319,10 +312,7 @@ error[E0382]: use of moved value LL | match Some((u(), u())) { | ---------------- move occurs because value has type `Option<(U, U)>`, which does not implement the `Copy` trait LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} - | -----------------------------^^^^^^^^^-- - | | | - | | value used here after move - | value moved here + | - value moved here ^ value used here after move error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:75:30 @@ -330,18 +320,16 @@ error[E0382]: borrow of moved value LL | match Some([u(), u()]) { | ---------------- move occurs because value has type `Option<[U; 2]>`, which does not implement the `Copy` trait LL | mut a @ Some([ref b, ref mut c]) => {} - | ---------------------^^^^^^^^^-- - | | | - | | value borrowed here after move + | ----- ^^^^^^^^^ value borrowed here after move + | | | value moved here error[E0382]: use of partially moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11 | LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} - | ^^^^^^^^^^^^^^^^^^^^-------------^ - | | | - | | value partially moved here + | ^^^^^ ----- value partially moved here + | | | value used here after partial move | = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr index c019aae3dfc9c..e03a9298214e4 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr @@ -237,9 +237,8 @@ error[E0382]: borrow of partially moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:30:9 | LL | let ref mut a @ [b, mut c] = [U, U]; - | ^^^^^^^^^^^^^^^^-----^ - | | | - | | value partially moved here + | ^^^^^^^^^ ----- value partially moved here + | | | value borrowed here after partial move | = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait @@ -248,7 +247,7 @@ error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:33:9 | LL | let ref a @ b = u(); - | ^^^^^^^^- --- move occurs because value has type `U`, which does not implement the `Copy` trait + | ^^^^^ - --- move occurs because value has type `U`, which does not implement the `Copy` trait | | | | | value moved here | value borrowed here after move @@ -257,9 +256,8 @@ error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:36:18 | LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); - | ^^^^^^^^----- - | | | - | | value moved here + | ^^^^^ ----- value moved here + | | | value borrowed here after move | = note: move occurs because value has type `U`, which does not implement the `Copy` trait @@ -268,9 +266,8 @@ error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:36:33 | LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); - | ^^^^^^^^- - | | | - | | value moved here + | ^^^^^ - value moved here + | | | value borrowed here after move | = note: move occurs because value has type `U`, which does not implement the `Copy` trait @@ -279,9 +276,8 @@ error[E0382]: borrow of partially moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:42:9 | LL | let ref mut a @ [b, mut c] = [u(), u()]; - | ^^^^^^^^^^^^^^^^-----^ - | | | - | | value partially moved here + | ^^^^^^^^^ ----- value partially moved here + | | | value borrowed here after partial move | = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait @@ -290,9 +286,8 @@ error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:69:23 | LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} - | ^^^^^^^^----- - | | | - | | value moved here + | ^^^^^ ----- value moved here + | | | value borrowed here after move | = note: move occurs because value has type `U`, which does not implement the `Copy` trait @@ -305,9 +300,8 @@ error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:69:38 | LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} - | ^^^^^^^^- - | | | - | | value moved here + | ^^^^^ - value moved here + | | | value borrowed here after move | = note: move occurs because value has type `U`, which does not implement the `Copy` trait @@ -320,7 +314,7 @@ error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:11:11 | LL | fn f1(ref a @ b: U) {} - | ^^^^^^^^- + | ^^^^^---- | | | | | value moved here | value borrowed here after move @@ -330,9 +324,8 @@ error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:14:20 | LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} - | ^^^^^^^^----- - | | | - | | value moved here + | ^^^^^ ----- value moved here + | | | value borrowed here after move | = note: move occurs because value has type `U`, which does not implement the `Copy` trait @@ -341,9 +334,8 @@ error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:14:35 | LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} - | ^^^^^^^^- - | | | - | | value moved here + | ^^^^^ - value moved here + | | | value borrowed here after move | = note: move occurs because value has type `U`, which does not implement the `Copy` trait @@ -352,9 +344,8 @@ error[E0382]: borrow of partially moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:20:11 | LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {} - | ^^^^^^^^^^^^^^^^-----^ - | | | - | | value partially moved here + | ^^^^^^^^^ ----- value partially moved here + | | | value borrowed here after partial move | = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr index 2ae78d1084e0e..9fd5e229afd0a 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr @@ -298,9 +298,8 @@ error[E0502]: cannot borrow value as immutable because it is also borrowed as mu --> $DIR/borrowck-pat-ref-mut-and-ref.rs:8:31 | LL | ref mut z @ &mut Some(ref a) => { - | ----------------------^^^^^- - | | | - | | immutable borrow occurs here + | --------- ^^^^^ immutable borrow occurs here + | | | mutable borrow occurs here ... LL | **z = None; @@ -310,9 +309,8 @@ error[E0502]: cannot borrow value as mutable because it is also borrowed as immu --> $DIR/borrowck-pat-ref-mut-and-ref.rs:46:9 | LL | let ref mut a @ ref b = u(); - | ^^^^^^^^^^^^----- - | | | - | | immutable borrow occurs here + | ^^^^^^^^^ ----- immutable borrow occurs here + | | | mutable borrow occurs here ... LL | drop(b); @@ -322,9 +320,8 @@ error[E0502]: cannot borrow value as immutable because it is also borrowed as mu --> $DIR/borrowck-pat-ref-mut-and-ref.rs:51:9 | LL | let ref a @ ref mut b = u(); - | ^^^^^^^^--------- - | | | - | | mutable borrow occurs here + | ^^^^^ --------- mutable borrow occurs here + | | | immutable borrow occurs here ... LL | *b = u(); @@ -334,9 +331,8 @@ error[E0502]: cannot borrow value as mutable because it is also borrowed as immu --> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:20 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { - | -----------^^^^^^^^^- - | | | - | | mutable borrow occurs here + | ----- ^^^^^^^^^ mutable borrow occurs here + | | | immutable borrow occurs here ... LL | drop(a); @@ -346,9 +342,8 @@ error[E0502]: cannot borrow value as mutable because it is also borrowed as immu --> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:45 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { - | ------------^^^^^^^^^- - | | | - | | mutable borrow occurs here + | ----- ^^^^^^^^^ mutable borrow occurs here + | | | immutable borrow occurs here ... LL | drop(a); @@ -406,9 +401,8 @@ error[E0502]: cannot borrow value as immutable because it is also borrowed as mu --> $DIR/borrowck-pat-ref-mut-and-ref.rs:117:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); - | ^^^^^^^^^---------^^^^^^^^^^^^ - | | | - | | mutable borrow occurs here + | ^^^^^ --------- mutable borrow occurs here + | | | immutable borrow occurs here ... LL | *b = U; @@ -418,9 +412,8 @@ error[E0502]: cannot borrow value as immutable because it is also borrowed as mu --> $DIR/borrowck-pat-ref-mut-and-ref.rs:123:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); - | ^^^^^^^^^---------^^^^^^^^^^^^ - | | | - | | mutable borrow occurs here + | ^^^^^ --------- mutable borrow occurs here + | | | immutable borrow occurs here ... LL | *b = U; @@ -430,9 +423,8 @@ error[E0502]: cannot borrow value as immutable because it is also borrowed as mu --> $DIR/borrowck-pat-ref-mut-and-ref.rs:129:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); - | ^^^^^^^^^---------^^^^^^^^^^^^ - | | | - | | mutable borrow occurs here + | ^^^^^ --------- mutable borrow occurs here + | | | immutable borrow occurs here LL | LL | *b = U; @@ -442,7 +434,7 @@ error[E0382]: borrow of moved value --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:30 | LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} - | --------^^^^^^^^^^^^- + | --------^^^^^^^^^---- | | | | | | | value moved here | | value borrowed here after move diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr index aa02230419b5e..e47aea9c77e6c 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr @@ -262,9 +262,8 @@ error[E0499]: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:29:9 | LL | let ref mut a @ ref mut b = U; - | ^^^^^^^^^^^^--------- - | | | - | | first mutable borrow occurs here + | ^^^^^^^^^ --------- first mutable borrow occurs here + | | | second mutable borrow occurs here ... LL | drop(b); @@ -274,9 +273,8 @@ error[E0499]: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:39:9 | LL | let ref mut a @ ref mut b = U; - | ^^^^^^^^^^^^--------- - | | | - | | first mutable borrow occurs here + | ^^^^^^^^^ --------- first mutable borrow occurs here + | | | second mutable borrow occurs here ... LL | *b = U; @@ -286,9 +284,8 @@ error[E0499]: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:89:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - | ---------------^^^^^^^^^- - | | | - | | second mutable borrow occurs here + | --------- ^^^^^^^^^ second mutable borrow occurs here + | | | first mutable borrow occurs here ... LL | *a = Err(U); @@ -298,9 +295,8 @@ error[E0499]: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:89:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - | ----------------^^^^^^^^^- - | | | - | | second mutable borrow occurs here + | --------- ^^^^^^^^^ second mutable borrow occurs here + | | | first mutable borrow occurs here ... LL | *a = Err(U); @@ -310,9 +306,8 @@ error[E0499]: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:101:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - | ---------------^^^^^^^^^- - | | | - | | second mutable borrow occurs here + | --------- ^^^^^^^^^ second mutable borrow occurs here + | | | first mutable borrow occurs here ... LL | drop(a); @@ -322,9 +317,8 @@ error[E0499]: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:101:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - | ----------------^^^^^^^^^- - | | | - | | second mutable borrow occurs here + | --------- ^^^^^^^^^ second mutable borrow occurs here + | | | first mutable borrow occurs here ... LL | drop(a); @@ -334,7 +328,7 @@ error[E0382]: borrow of moved value --> $DIR/borrowck-pat-ref-mut-twice.rs:21:34 | LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} - | ------------^^^^^^^^^^^^- + | ------------^^^^^^^^^---- | | | | | | | value moved here | | value borrowed here after move diff --git a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr index d290144b6155a..cd3234952fa54 100644 --- a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr +++ b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr @@ -2,9 +2,8 @@ error[E0382]: use of partially moved value --> $DIR/copy-and-move-mixed.rs:12:9 | LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); - | ^^^^^^^^^^------------^ - | | | - | | value partially moved here + | ^ - value partially moved here + | | | value used here after partial move | = note: partial move occurs because value has type `NC`, which does not implement the `Copy` trait diff --git a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr index d78faa682b507..840a513d6c67d 100644 --- a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr +++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr @@ -48,7 +48,7 @@ error[E0382]: borrow of moved value --> $DIR/default-binding-modes-both-sides-independent.rs:29:9 | LL | let ref mut a @ b = NotCopy; - | ^^^^^^^^^^^^- ------- move occurs because value has type `NotCopy`, which does not implement the `Copy` trait + | ^^^^^^^^^ - ------- move occurs because value has type `NotCopy`, which does not implement the `Copy` trait | | | | | value moved here | value borrowed here after move diff --git a/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr b/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr index 3180bd0afc104..70beb5d423223 100644 --- a/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr +++ b/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr @@ -11,7 +11,7 @@ error[E0596]: cannot borrow `not_mut` as mutable, as it is not declared as mutab --> $DIR/nested-binding-modes-mut.rs:9:5 | LL | let not_mut @ mut is_mut = 42; - | -------------------- help: consider changing this to be mutable: `mut not_mut` + | ------- help: consider changing this to be mutable: `mut not_mut` LL | &mut is_mut; LL | &mut not_mut; | ^^^^^^^^^^^^ cannot borrow as mutable diff --git a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr index 5beca04d28590..bac2db6ce825c 100644 --- a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr +++ b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr @@ -35,7 +35,7 @@ error[E0502]: cannot borrow `arr[..]` as mutable because it is also borrowed as --> $DIR/borrowck-move-ref-pattern.rs:13:16 | LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; - | ---------------- immutable borrow occurs here + | ----------- immutable borrow occurs here ... LL | let [_, _, ref mut _x2, _x3, mut _x4] = arr; | ^^^^^^^^^^^ mutable borrow occurs here @@ -47,7 +47,7 @@ error[E0505]: cannot move out of `arr[..]` because it is borrowed --> $DIR/borrowck-move-ref-pattern.rs:13:29 | LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; - | ---------------- borrow of `arr[..]` occurs here + | ----------- borrow of `arr[..]` occurs here ... LL | let [_, _, ref mut _x2, _x3, mut _x4] = arr; | ^^^ move out of `arr[..]` occurs here @@ -59,7 +59,7 @@ error[E0505]: cannot move out of `arr[..]` because it is borrowed --> $DIR/borrowck-move-ref-pattern.rs:13:34 | LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; - | ---------------- borrow of `arr[..]` occurs here + | ----------- borrow of `arr[..]` occurs here ... LL | let [_, _, ref mut _x2, _x3, mut _x4] = arr; | ^^^^^^^ move out of `arr[..]` occurs here From ee74f925f57c866669c69eecaa5579c327031674 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Tue, 6 Sep 2022 22:18:56 +0300 Subject: [PATCH 10/13] Replace manual impl with a derive macro as multipart suggestions are now supported by them --- compiler/rustc_infer/src/errors/mod.rs | 89 +++++++++++-------- .../infer/error_reporting/need_type_info.rs | 10 +-- 2 files changed, 55 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 5eedca78489b9..f5519b989b64b 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -147,56 +147,67 @@ pub enum SourceKindSubdiag<'a> { }, } -// Has to be implemented manually because multipart suggestions are not supported by the derive macro. -// Would be a part of `SourceKindSubdiag` otherwise. +#[derive(SessionSubdiagnostic)] pub enum SourceKindMultiSuggestion<'a> { + #[multipart_suggestion_verbose( + infer::source_kind_fully_qualified, + applicability = "has-placeholders" + )] FullyQualified { - span: Span, + #[suggestion_part(code = "{def_path}({adjustment}")] + span_lo: Span, + #[suggestion_part(code = "{successor_pos}")] + span_hi: Span, def_path: String, adjustment: &'a str, - successor: (&'a str, BytePos), + successor_pos: &'a str, }, + #[multipart_suggestion_verbose( + infer::source_kind_closure_return, + applicability = "has-placeholders" + )] ClosureReturn { - ty_info: String, - data: &'a FnRetTy<'a>, - should_wrap_expr: Option, + #[suggestion_part(code = "{start_span_code}")] + start_span: Span, + start_span_code: String, + #[suggestion_part(code = "}}")] + end_span: Option, }, } -impl AddSubdiagnostic for SourceKindMultiSuggestion<'_> { - fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { - match self { - Self::FullyQualified { span, def_path, adjustment, successor } => { - let suggestion = vec![ - (span.shrink_to_lo(), format!("{def_path}({adjustment}")), - (span.shrink_to_hi().with_hi(successor.1), successor.0.to_string()), - ]; - diag.multipart_suggestion_verbose( - fluent::infer::source_kind_fully_qualified, - suggestion, - rustc_errors::Applicability::HasPlaceholders, - ); - } - Self::ClosureReturn { ty_info, data, should_wrap_expr } => { - let (arrow, post) = match data { - FnRetTy::DefaultReturn(_) => ("-> ", " "), - _ => ("", ""), - }; - let suggestion = match should_wrap_expr { - Some(end_span) => vec![ - (data.span(), format!("{}{}{}{{ ", arrow, ty_info, post)), - (end_span, " }".to_string()), - ], - None => vec![(data.span(), format!("{}{}{}", arrow, ty_info, post))], - }; - diag.multipart_suggestion_verbose( - fluent::infer::source_kind_closure_return, - suggestion, - rustc_errors::Applicability::HasPlaceholders, - ); - } +impl<'a> SourceKindMultiSuggestion<'a> { + pub fn new_fully_qualified( + span: Span, + def_path: String, + adjustment: &'a str, + successor: (&'a str, BytePos), + ) -> Self { + Self::FullyQualified { + span_lo: span.shrink_to_lo(), + span_hi: span.shrink_to_hi().with_hi(successor.1), + def_path, + adjustment, + successor_pos: successor.0, } } + + pub fn new_closure_return( + ty_info: String, + data: &'a FnRetTy<'a>, + should_wrap_expr: Option, + ) -> Self { + let (arrow, post) = match data { + FnRetTy::DefaultReturn(_) => ("-> ", " "), + _ => ("", ""), + }; + let (start_span, start_span_code, end_span) = match should_wrap_expr { + Some(end_span) => { + (data.span(), format!("{}{}{}{{ ", arrow, ty_info, post), Some(end_span)) + } + None => (data.span(), format!("{}{}{}", arrow, ty_info, post), None), + }; + Self::ClosureReturn { start_span, start_span_code, end_span } + } } pub enum RegionOriginNote<'a> { diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 232b9b11455db..b0f5897e34b03 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -511,20 +511,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { _ => "", }; - multi_suggestions.push(SourceKindMultiSuggestion::FullyQualified { - span: receiver.span, + multi_suggestions.push(SourceKindMultiSuggestion::new_fully_qualified( + receiver.span, def_path, adjustment, successor, - }); + )); } InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => { let ty_info = ty_to_string(self, ty); - multi_suggestions.push(SourceKindMultiSuggestion::ClosureReturn { + multi_suggestions.push(SourceKindMultiSuggestion::new_closure_return( ty_info, data, should_wrap_expr, - }); + )); } } match error_code { From 3d70be7240b826c54411c76d18d3b203f657425a Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Tue, 6 Sep 2022 22:55:49 +0300 Subject: [PATCH 11/13] Whoops forgot a space --- compiler/rustc_infer/src/errors/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index f5519b989b64b..d232a18646244 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -170,7 +170,7 @@ pub enum SourceKindMultiSuggestion<'a> { #[suggestion_part(code = "{start_span_code}")] start_span: Span, start_span_code: String, - #[suggestion_part(code = "}}")] + #[suggestion_part(code = " }}")] end_span: Option, }, } From d8d3b83e3ae6ade8498862d8c110c302abf859d9 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 28 Aug 2022 00:10:06 +0300 Subject: [PATCH 12/13] rustc: Parameterize `ty::Visibility` over used ID It allows using `LocalDefId` instead of `DefId` when possible, and also encode cheaper `Visibility` into metadata. --- compiler/rustc_metadata/src/rmeta/decoder.rs | 15 +++- .../src/rmeta/decoder/cstore_impl.rs | 6 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 7 +- compiler/rustc_metadata/src/rmeta/mod.rs | 2 +- compiler/rustc_middle/src/metadata.rs | 3 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/assoc.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 6 ++ compiler/rustc_middle/src/ty/mod.rs | 61 +++++++++------ compiler/rustc_middle/src/ty/parameterized.rs | 4 +- compiler/rustc_privacy/src/lib.rs | 76 +++++++++---------- .../rustc_resolve/src/build_reduced_graph.rs | 46 ++++++----- compiler/rustc_resolve/src/ident.rs | 13 ++-- compiler/rustc_resolve/src/imports.rs | 4 +- compiler/rustc_resolve/src/lib.rs | 16 ++-- compiler/rustc_span/src/def_id.rs | 6 ++ .../src/traits/error_reporting/mod.rs | 4 +- compiler/rustc_typeck/src/check/demand.rs | 2 +- compiler/rustc_typeck/src/check/expr.rs | 6 +- .../rustc_typeck/src/check/method/suggest.rs | 2 +- compiler/rustc_typeck/src/check/pat.rs | 2 +- src/librustdoc/clean/mod.rs | 6 +- src/tools/clippy/clippy_lints/src/default.rs | 2 +- src/tools/clippy/clippy_lints/src/derive.rs | 4 +- 24 files changed, 170 insertions(+), 127 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 6f026678170b7..562246f4e8a1b 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -911,8 +911,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { self.root.tables.generics_of.get(self, item_id).unwrap().decode((self, sess)) } - fn get_visibility(self, id: DefIndex) -> ty::Visibility { - self.root.tables.visibility.get(self, id).unwrap().decode(self) + fn get_visibility(self, id: DefIndex) -> ty::Visibility { + self.root + .tables + .visibility + .get(self, id) + .unwrap() + .decode(self) + .map_id(|index| self.local_def_id(index)) } fn get_trait_item_def_id(self, id: DefIndex) -> Option { @@ -1182,7 +1188,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .map(move |index| respan(self.get_span(index, sess), self.item_name(index))) } - fn get_struct_field_visibilities(self, id: DefIndex) -> impl Iterator + 'a { + fn get_struct_field_visibilities( + self, + id: DefIndex, + ) -> impl Iterator> + 'a { self.root .tables .children diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 6b447ebd99910..dede1b2122a3c 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -210,7 +210,6 @@ provide! { tcx, def_id, other, cdata, lookup_const_stability => { table } lookup_default_body_stability => { table } lookup_deprecation_entry => { table } - visibility => { table } unused_generic_params => { table } opt_def_kind => { table_direct } impl_parent => { table } @@ -225,6 +224,7 @@ provide! { tcx, def_id, other, cdata, generator_kind => { table } trait_def => { table } + visibility => { cdata.get_visibility(def_id.index) } adt_def => { cdata.get_adt_def(def_id.index, tcx) } adt_destructor => { let _ = cdata; @@ -485,7 +485,7 @@ impl CStore { pub fn struct_field_visibilities_untracked( &self, def: DefId, - ) -> impl Iterator + '_ { + ) -> impl Iterator> + '_ { self.get_crate_data(def.krate).get_struct_field_visibilities(def.index) } @@ -493,7 +493,7 @@ impl CStore { self.get_crate_data(def.krate).get_ctor_def_id_and_kind(def.index) } - pub fn visibility_untracked(&self, def: DefId) -> Visibility { + pub fn visibility_untracked(&self, def: DefId) -> Visibility { self.get_crate_data(def.krate).get_visibility(def.index) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 039486ba02c37..b807663b10fd0 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1138,7 +1138,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id)); } if should_encode_visibility(def_kind) { - record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id)); + let vis = + self.tcx.local_visibility(local_id).map_id(|def_id| def_id.local_def_index); + record!(self.tables.visibility[def_id] <- vis); } if should_encode_stability(def_kind) { self.encode_stability(def_id); @@ -1727,7 +1729,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.tables.opt_def_kind.set(LOCAL_CRATE.as_def_id().index, DefKind::Mod); record!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id())); self.encode_attrs(LOCAL_CRATE.as_def_id().expect_local()); - record!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- tcx.visibility(LOCAL_CRATE.as_def_id())); + let vis = tcx.local_visibility(CRATE_DEF_ID).map_id(|def_id| def_id.local_def_index); + record!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- vis); if let Some(stability) = stability { record!(self.tables.lookup_stability[LOCAL_CRATE.as_def_id()] <- stability); } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 6f849a58580e6..748b3afec37c7 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -338,7 +338,7 @@ define_tables! { children: Table>, opt_def_kind: Table, - visibility: Table>, + visibility: Table>>, def_span: Table>, def_ident_span: Table>, lookup_stability: Table>, diff --git a/compiler/rustc_middle/src/metadata.rs b/compiler/rustc_middle/src/metadata.rs index c8e78747d8e7b..5ff014c7815a9 100644 --- a/compiler/rustc_middle/src/metadata.rs +++ b/compiler/rustc_middle/src/metadata.rs @@ -2,6 +2,7 @@ use crate::ty; use rustc_hir::def::Res; use rustc_macros::HashStable; +use rustc_span::def_id::DefId; use rustc_span::symbol::Ident; use rustc_span::Span; @@ -18,7 +19,7 @@ pub struct ModChild { /// Local variables cannot be exported, so this `Res` doesn't need the ID parameter. pub res: Res, /// Visibility of the item. - pub vis: ty::Visibility, + pub vis: ty::Visibility, /// Span of the item. pub span: Span, /// A proper `macro_rules` item (not a reexport). diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 8e7bacca262e1..4478b45cf1437 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1607,7 +1607,7 @@ rustc_queries! { desc { "looking up late bound vars" } } - query visibility(def_id: DefId) -> ty::Visibility { + query visibility(def_id: DefId) -> ty::Visibility { desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) } separate_provide_extern } diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index c97156ac17ff6..55ee5bd2f810d 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -42,7 +42,7 @@ impl AssocItem { } #[inline] - pub fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility { + pub fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility { tcx.visibility(self.def_id) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 262d59f8ff8a7..c2e5decfc786e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -22,6 +22,7 @@ use crate::ty::{ FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy, + Visibility, }; use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; @@ -1728,6 +1729,11 @@ impl<'tcx> TyCtxt<'tcx> { .chain(self.crates(()).iter().copied()) .flat_map(move |cnum| self.traits_in_crate(cnum).iter().copied()) } + + #[inline] + pub fn local_visibility(self, def_id: LocalDefId) -> Visibility { + self.visibility(def_id.to_def_id()).expect_local() + } } /// A trait implemented for all `X<'a>` types that can be safely and diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a3f7880b9a568..e39a75400e7f5 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -259,11 +259,11 @@ impl fmt::Display for ImplPolarity { } #[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, Decodable, HashStable)] -pub enum Visibility { +pub enum Visibility { /// Visible everywhere (including in other crates). Public, /// Visible only in the given crate-local module. - Restricted(DefId), + Restricted(Id), } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)] @@ -354,28 +354,45 @@ impl<'tcx> DefIdTree for TyCtxt<'tcx> { } } -impl Visibility { - /// Returns `true` if an item with this visibility is accessible from the given block. - pub fn is_accessible_from(self, module: DefId, tree: T) -> bool { - let restriction = match self { - // Public items are visible everywhere. - Visibility::Public => return true, - // Restricted items are visible in an arbitrary local module. - Visibility::Restricted(other) if other.krate != module.krate => return false, - Visibility::Restricted(module) => module, - }; +impl Visibility { + pub fn is_public(self) -> bool { + matches!(self, Visibility::Public) + } + + pub fn map_id(self, f: impl FnOnce(Id) -> OutId) -> Visibility { + match self { + Visibility::Public => Visibility::Public, + Visibility::Restricted(id) => Visibility::Restricted(f(id)), + } + } +} + +impl> Visibility { + pub fn to_def_id(self) -> Visibility { + self.map_id(Into::into) + } - tree.is_descendant_of(module, restriction) + /// Returns `true` if an item with this visibility is accessible from the given module. + pub fn is_accessible_from(self, module: impl Into, tree: impl DefIdTree) -> bool { + match self { + // Public items are visible everywhere. + Visibility::Public => true, + Visibility::Restricted(id) => tree.is_descendant_of(module.into(), id.into()), + } } /// Returns `true` if this visibility is at least as accessible as the given visibility - pub fn is_at_least(self, vis: Visibility, tree: T) -> bool { - let vis_restriction = match vis { - Visibility::Public => return self == Visibility::Public, - Visibility::Restricted(module) => module, - }; + pub fn is_at_least(self, vis: Visibility>, tree: impl DefIdTree) -> bool { + match vis { + Visibility::Public => self.is_public(), + Visibility::Restricted(id) => self.is_accessible_from(id, tree), + } + } +} - self.is_accessible_from(vis_restriction, tree) +impl Visibility { + pub fn expect_local(self) -> Visibility { + self.map_id(|id| id.expect_local()) } // Returns `true` if this item is visible anywhere in the local crate. @@ -385,10 +402,6 @@ impl Visibility { Visibility::Restricted(def_id) => def_id.is_local(), } } - - pub fn is_public(self) -> bool { - matches!(self, Visibility::Public) - } } /// The crate variances map is computed during typeck and contains the @@ -1790,7 +1803,7 @@ pub enum VariantDiscr { pub struct FieldDef { pub did: DefId, pub name: Symbol, - pub vis: Visibility, + pub vis: Visibility, } impl PartialEq for FieldDef { diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index ca24c0d1ce386..9c8dc30e2db3f 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -1,4 +1,4 @@ -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, DefIndex}; use rustc_index::vec::{Idx, IndexVec}; use crate::middle::exported_symbols::ExportedSymbol; @@ -60,7 +60,7 @@ trivially_parameterized_over_tcx! { ty::ImplPolarity, ty::ReprOptions, ty::TraitDef, - ty::Visibility, + ty::Visibility, ty::adjustment::CoerceUnsizedInfo, ty::fast_reject::SimplifiedTypeGen, rustc_ast::Attribute, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index ba69bc23118b2..b2966f0d21801 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1,6 +1,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(associated_type_defaults)] #![feature(control_flow_enum)] +#![feature(let_else)] #![feature(rustc_private)] #![feature(try_blocks)] #![recursion_limit = "256"] @@ -334,7 +335,9 @@ impl<'a, 'tcx, VL: VisibilityLike> DefIdVisitor<'tcx> for FindMin<'a, 'tcx, VL> _kind: &str, _descr: &dyn fmt::Display, ) -> ControlFlow { - self.min = VL::new_min(self, def_id); + if let Some(def_id) = def_id.as_local() { + self.min = VL::new_min(self, def_id); + } ControlFlow::CONTINUE } } @@ -342,7 +345,7 @@ impl<'a, 'tcx, VL: VisibilityLike> DefIdVisitor<'tcx> for FindMin<'a, 'tcx, VL> trait VisibilityLike: Sized { const MAX: Self; const SHALLOW: bool = false; - fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self; + fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self; // Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to // associated types for which we can't determine visibility precisely. @@ -357,8 +360,8 @@ trait VisibilityLike: Sized { } impl VisibilityLike for ty::Visibility { const MAX: Self = ty::Visibility::Public; - fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self { - min(find.tcx.visibility(def_id), find.min, find.tcx) + fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self { + min(find.tcx.local_visibility(def_id), find.min, find.tcx) } } impl VisibilityLike for Option { @@ -373,15 +376,8 @@ impl VisibilityLike for Option { // both "shallow" version of its self type and "shallow" version of its trait if it exists // (which require reaching the `DefId`s in them). const SHALLOW: bool = true; - fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self { - cmp::min( - if let Some(def_id) = def_id.as_local() { - find.access_levels.map.get(&def_id).copied() - } else { - Self::MAX - }, - find.min, - ) + fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self { + cmp::min(find.access_levels.map.get(&def_id).copied(), find.min) } } @@ -511,15 +507,15 @@ impl<'tcx> EmbargoVisitor<'tcx> { let module = self.tcx.hir().get_module(module_def_id).0; for item_id in module.item_ids { let def_kind = self.tcx.def_kind(item_id.def_id); - let vis = self.tcx.visibility(item_id.def_id); + let vis = self.tcx.local_visibility(item_id.def_id); self.update_macro_reachable_def(item_id.def_id, def_kind, vis, defining_mod); } if let Some(exports) = self.tcx.module_reexports(module_def_id) { for export in exports { - if export.vis.is_accessible_from(defining_mod.to_def_id(), self.tcx) { + if export.vis.is_accessible_from(defining_mod, self.tcx) { if let Res::Def(def_kind, def_id) = export.res { if let Some(def_id) = def_id.as_local() { - let vis = self.tcx.visibility(def_id.to_def_id()); + let vis = self.tcx.local_visibility(def_id); self.update_macro_reachable_def(def_id, def_kind, vis, defining_mod); } } @@ -542,7 +538,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { match def_kind { // No type privacy, so can be directly marked as reachable. DefKind::Const | DefKind::Static(_) | DefKind::TraitAlias | DefKind::TyAlias => { - if vis.is_accessible_from(module.to_def_id(), self.tcx) { + if vis.is_accessible_from(module, self.tcx) { self.update(def_id, level); } } @@ -554,7 +550,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { DefKind::Macro(_) => { let item = self.tcx.hir().expect_item(def_id); if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }, _) = item.kind { - if vis.is_accessible_from(module.to_def_id(), self.tcx) { + if vis.is_accessible_from(module, self.tcx) { self.update(def_id, level); } } @@ -565,7 +561,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { // hygiene these don't need to be marked reachable. The contents of // the module, however may be reachable. DefKind::Mod => { - if vis.is_accessible_from(module.to_def_id(), self.tcx) { + if vis.is_accessible_from(module, self.tcx) { self.update_macro_reachable(def_id, module); } } @@ -579,8 +575,8 @@ impl<'tcx> EmbargoVisitor<'tcx> { { for field in struct_def.fields() { let def_id = self.tcx.hir().local_def_id(field.hir_id); - let field_vis = self.tcx.visibility(def_id); - if field_vis.is_accessible_from(module.to_def_id(), self.tcx) { + let field_vis = self.tcx.local_visibility(def_id); + if field_vis.is_accessible_from(module, self.tcx) { self.reach(def_id, level).ty(); } } @@ -654,7 +650,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { hir::ItemKind::Impl(ref impl_) => { for impl_item_ref in impl_.items { if impl_.of_trait.is_some() - || self.tcx.visibility(impl_item_ref.id.def_id) == ty::Visibility::Public + || self.tcx.visibility(impl_item_ref.id.def_id).is_public() { self.update(impl_item_ref.id.def_id, item_level); } @@ -682,7 +678,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } hir::ItemKind::ForeignMod { items, .. } => { for foreign_item in items { - if self.tcx.visibility(foreign_item.id.def_id) == ty::Visibility::Public { + if self.tcx.visibility(foreign_item.id.def_id).is_public() { self.update(foreign_item.id.def_id, item_level); } } @@ -1117,7 +1113,7 @@ impl<'tcx> TypePrivacyVisitor<'tcx> { } fn item_is_accessible(&self, did: DefId) -> bool { - self.tcx.visibility(did).is_accessible_from(self.current_item.to_def_id(), self.tcx) + self.tcx.visibility(did).is_accessible_from(self.current_item, self.tcx) } // Take node-id of an expression or pattern and check its type for privacy. @@ -1609,8 +1605,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { let mut found_pub_static = false; for impl_item_ref in impl_.items { if self.access_levels.is_reachable(impl_item_ref.id.def_id) - || self.tcx.visibility(impl_item_ref.id.def_id) - == ty::Visibility::Public + || self.tcx.visibility(impl_item_ref.id.def_id).is_public() { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); match impl_item_ref.kind { @@ -1780,17 +1775,17 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { ); } - let hir_id = match def_id.as_local() { - Some(def_id) => self.tcx.hir().local_def_id_to_hir_id(def_id), - None => return false, + let Some(local_def_id) = def_id.as_local() else { + return false; }; - let vis = self.tcx.visibility(def_id); + let vis = self.tcx.local_visibility(local_def_id); if !vis.is_at_least(self.required_visibility, self.tcx) { + let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id); let vis_descr = match vis { ty::Visibility::Public => "public", ty::Visibility::Restricted(vis_def_id) => { - if vis_def_id == self.tcx.parent_module(hir_id).to_def_id() { + if vis_def_id == self.tcx.parent_module(hir_id) { "private" } else if vis_def_id.is_top_level_module() { "crate-private" @@ -1906,7 +1901,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { pub fn check_item(&mut self, id: ItemId) { let tcx = self.tcx; - let item_visibility = tcx.visibility(id.def_id); + let item_visibility = tcx.local_visibility(id.def_id); let def_kind = tcx.def_kind(id.def_id); match def_kind { @@ -1957,7 +1952,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { let item = tcx.hir().item(id); if let hir::ItemKind::ForeignMod { items, .. } = item.kind { for foreign_item in items { - let vis = tcx.visibility(foreign_item.id.def_id); + let vis = tcx.local_visibility(foreign_item.id.def_id); self.check(foreign_item.id.def_id, vis).generics().predicates().ty(); } } @@ -1972,7 +1967,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { for field in struct_def.fields() { let def_id = tcx.hir().local_def_id(field.hir_id); - let field_visibility = tcx.visibility(def_id); + let field_visibility = tcx.local_visibility(def_id); self.check(def_id, min(item_visibility, field_visibility, tcx)).ty(); } } @@ -1992,7 +1987,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { } for impl_item_ref in impl_.items { let impl_item_vis = if impl_.of_trait.is_none() { - min(tcx.visibility(impl_item_ref.id.def_id), impl_vis, tcx) + min(tcx.local_visibility(impl_item_ref.id.def_id), impl_vis, tcx) } else { impl_vis }; @@ -2019,8 +2014,11 @@ pub fn provide(providers: &mut Providers) { }; } -fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility { - let def_id = def_id.expect_local(); +fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility { + local_visibility(tcx, def_id.expect_local()).to_def_id() +} + +fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility { match tcx.resolutions(()).visibilities.get(&def_id) { Some(vis) => *vis, None => { @@ -2037,7 +2035,7 @@ fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility { | Node::Item(hir::Item { kind: hir::ItemKind::Use(_, hir::UseKind::ListStem) | hir::ItemKind::OpaqueTy(..), .. - }) => ty::Visibility::Restricted(tcx.parent_module(hir_id).to_def_id()), + }) => ty::Visibility::Restricted(tcx.parent_module(hir_id)), // Visibilities of trait impl items are inherited from their traits // and are not filled in resolve. Node::ImplItem(impl_item) => { @@ -2050,7 +2048,7 @@ fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility { tcx.sess.delay_span_bug(tr.path.span, "trait without a def-id"); ty::Visibility::Public }, - |def_id| tcx.visibility(def_id), + |def_id| tcx.visibility(def_id).expect_local(), ), _ => span_bug!(impl_item.span, "the parent is not a trait impl"), } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 51e8c24b9c25a..9cb735b36856c 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -39,24 +39,26 @@ use std::ptr; type Res = def::Res; -impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, LocalExpnId) { +impl<'a, Id: Into> ToNameBinding<'a> + for (Module<'a>, ty::Visibility, Span, LocalExpnId) +{ fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> { arenas.alloc_name_binding(NameBinding { kind: NameBindingKind::Module(self.0), ambiguity: None, - vis: self.1, + vis: self.1.to_def_id(), span: self.2, expansion: self.3, }) } } -impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, LocalExpnId) { +impl<'a, Id: Into> ToNameBinding<'a> for (Res, ty::Visibility, Span, LocalExpnId) { fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> { arenas.alloc_name_binding(NameBinding { kind: NameBindingKind::Res(self.0, false), ambiguity: None, - vis: self.1, + vis: self.1.to_def_id(), span: self.2, expansion: self.3, }) @@ -70,7 +72,7 @@ impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, LocalExpnId, IsMacroE arenas.alloc_name_binding(NameBinding { kind: NameBindingKind::Res(self.0, true), ambiguity: None, - vis: self.1, + vis: self.1.to_def_id(), span: self.2, expansion: self.3, }) @@ -260,7 +262,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { self.r.visibilities[&def_id.expect_local()] } // Otherwise, the visibility is restricted to the nearest parent `mod` item. - _ => ty::Visibility::Restricted(self.parent_scope.module.nearest_parent_mod()), + _ => ty::Visibility::Restricted( + self.parent_scope.module.nearest_parent_mod().expect_local(), + ), }) } ast::VisibilityKind::Restricted { ref path, id, .. } => { @@ -311,7 +315,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } else { let vis = ty::Visibility::Restricted(res.def_id()); if self.r.is_accessible_from(vis, parent_scope.module) { - Ok(vis) + Ok(vis.expect_local()) } else { Err(VisResolutionError::AncestorOnly(path.span)) } @@ -649,7 +653,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { true, // The whole `use` item item, - ty::Visibility::Restricted(self.parent_scope.module.nearest_parent_mod()), + ty::Visibility::Restricted( + self.parent_scope.module.nearest_parent_mod().expect_local(), + ), root_span, ); } @@ -765,10 +771,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { if let Some(ctor_node_id) = vdata.ctor_id() { // If the structure is marked as non_exhaustive then lower the visibility // to within the crate. - let mut ctor_vis = if vis == ty::Visibility::Public + let mut ctor_vis = if vis.is_public() && self.r.session.contains_name(&item.attrs, sym::non_exhaustive) { - ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()) + ty::Visibility::Restricted(CRATE_DEF_ID) } else { vis }; @@ -785,7 +791,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { if ctor_vis.is_at_least(field_vis, &*self.r) { ctor_vis = field_vis; } - ret_fields.push(field_vis); + ret_fields.push(field_vis.to_def_id()); } let ctor_def_id = self.r.local_def_id(ctor_node_id); let ctor_res = Res::Def( @@ -795,7 +801,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion)); self.r.visibilities.insert(ctor_def_id, ctor_vis); - self.r.struct_constructors.insert(def_id, (ctor_res, ctor_vis, ret_fields)); + self.r + .struct_constructors + .insert(def_id, (ctor_res, ctor_vis.to_def_id(), ret_fields)); } } @@ -867,8 +875,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } .map(|module| { let used = self.process_macro_use_imports(item, module); - let binding = - (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas); + let vis = ty::Visibility::::Public; + let binding = (module, vis, sp, expansion).to_name_binding(self.r.arenas); (used, Some(ModuleOrUniformRoot::Module(module)), binding) }) .unwrap_or((true, None, self.r.dummy_binding)); @@ -1117,7 +1125,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { root_span: span, span, module_path: Vec::new(), - vis: Cell::new(Some(ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()))), + vis: Cell::new(Some(ty::Visibility::Restricted(CRATE_DEF_ID))), used: Cell::new(false), }) }; @@ -1263,7 +1271,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let vis = if is_macro_export { ty::Visibility::Public } else { - ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()) + ty::Visibility::Restricted(CRATE_DEF_ID) }; let binding = (res, vis, span, expansion).to_name_binding(self.r.arenas); self.r.set_binding_parent_module(binding, parent_scope.module); @@ -1294,7 +1302,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } _ => self.resolve_visibility(&item.vis), }; - if vis != ty::Visibility::Public { + if !vis.is_public() { self.insert_unused_macro(ident, def_id, item.id, &rule_spans); } self.r.define(module, ident, MacroNS, (res, vis, span, expansion)); @@ -1507,10 +1515,10 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { self.r.visibilities.insert(def_id, vis); // If the variant is marked as non_exhaustive then lower the visibility to within the crate. - let ctor_vis = if vis == ty::Visibility::Public + let ctor_vis = if vis.is_public() && self.r.session.contains_name(&variant.attrs, sym::non_exhaustive) { - ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()) + ty::Visibility::Restricted(CRATE_DEF_ID) } else { vis }; diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index b84a610833ddf..2287aa1eb2567 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -6,6 +6,7 @@ use rustc_middle::bug; use rustc_middle::ty; use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK; use rustc_session::lint::BuiltinLintDiagnostics; +use rustc_span::def_id::LocalDefId; use rustc_span::edition::Edition; use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext}; use rustc_span::symbol::{kw, Ident}; @@ -26,6 +27,8 @@ use Determinacy::*; use Namespace::*; use RibKind::*; +type Visibility = ty::Visibility; + impl<'a> Resolver<'a> { /// A generic scope visitor. /// Visits scopes in order to resolve some identifier in them or perform other actions. @@ -424,8 +427,7 @@ impl<'a> Resolver<'a> { let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt)); let ok = |res, span, arenas| { Ok(( - (res, ty::Visibility::Public, span, LocalExpnId::ROOT) - .to_name_binding(arenas), + (res, Visibility::Public, span, LocalExpnId::ROOT).to_name_binding(arenas), Flags::empty(), )) }; @@ -438,7 +440,7 @@ impl<'a> Resolver<'a> { { let binding = ( Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper), - ty::Visibility::Public, + Visibility::Public, attr.span, expn_id, ) @@ -841,9 +843,8 @@ impl<'a> Resolver<'a> { if ns == TypeNS { if ident.name == kw::Crate || ident.name == kw::DollarCrate { let module = self.resolve_crate_root(ident); - let binding = - (module, ty::Visibility::Public, module.span, LocalExpnId::ROOT) - .to_name_binding(self.arenas); + let binding = (module, Visibility::Public, module.span, LocalExpnId::ROOT) + .to_name_binding(self.arenas); return Ok(binding); } else if ident.name == kw::Super || ident.name == kw::SelfLower { // FIXME: Implement these with renaming requirements so that e.g. diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 27745cee52df7..c133c272bac27 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -214,7 +214,7 @@ impl<'a> Resolver<'a> { binding: &'a NameBinding<'a>, import: &'a Import<'a>, ) -> &'a NameBinding<'a> { - let import_vis = import.expect_vis(); + let import_vis = import.expect_vis().to_def_id(); let vis = if binding.vis.is_at_least(import_vis, self) || pub_use_of_private_extern_crate_hack(import, binding) { @@ -227,7 +227,7 @@ impl<'a> Resolver<'a> { if vis == import_vis || max_vis.get().map_or(true, |max_vis| vis.is_at_least(max_vis, self)) { - max_vis.set(Some(vis)) + max_vis.set(Some(vis.expect_local())) } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index aaa9ae6f32513..f7b7313d1049d 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -648,7 +648,7 @@ pub struct NameBinding<'a> { ambiguity: Option<(&'a NameBinding<'a>, AmbiguityKind)>, expansion: LocalExpnId, span: Span, - vis: ty::Visibility, + vis: ty::Visibility, } pub trait ToNameBinding<'a> { @@ -1012,7 +1012,7 @@ pub struct Resolver<'a> { /// Table for mapping struct IDs into struct constructor IDs, /// it's not used during normal resolution, only for better error reporting. /// Also includes of list of each fields visibility - struct_constructors: DefIdMap<(Res, ty::Visibility, Vec)>, + struct_constructors: DefIdMap<(Res, ty::Visibility, Vec>)>, /// Features enabled for this crate. active_features: FxHashSet, @@ -1808,7 +1808,11 @@ impl<'a> Resolver<'a> { self.pat_span_map.insert(node, span); } - fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool { + fn is_accessible_from( + &self, + vis: ty::Visibility>, + module: Module<'a>, + ) -> bool { vis.is_accessible_from(module.nearest_parent_mod(), self) } @@ -1862,10 +1866,8 @@ impl<'a> Resolver<'a> { self.crate_loader.maybe_process_path_extern(ident.name)? }; let crate_root = self.expect_module(crate_id.as_def_id()); - Some( - (crate_root, ty::Visibility::Public, DUMMY_SP, LocalExpnId::ROOT) - .to_name_binding(self.arenas), - ) + let vis = ty::Visibility::::Public; + Some((crate_root, vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(self.arenas)) } }) } diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index a1533fe46b3ef..ceb6b6c68b055 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -305,6 +305,12 @@ impl DefId { } } +impl From for DefId { + fn from(local: LocalDefId) -> DefId { + local.to_def_id() + } +} + impl Encodable for DefId { default fn encode(&self, s: &mut E) { self.krate.encode(s); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 9b8bb9e36201c..efdb1ace13992 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1895,9 +1895,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { // FIXME(compiler-errors): This could be generalized, both to // be more granular, and probably look past other `#[fundamental]` // types, too. - self.tcx - .visibility(def.did()) - .is_accessible_from(body_id.owner.to_def_id(), self.tcx) + self.tcx.visibility(def.did()).is_accessible_from(body_id.owner, self.tcx) } else { true } diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index d078252ebd4e2..e1d55ff82cbad 100644 --- a/compiler/rustc_typeck/src/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs @@ -375,7 +375,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let field_is_local = sole_field.did.is_local(); let field_is_accessible = - sole_field.vis.is_accessible_from(expr.hir_id.owner.to_def_id(), self.tcx) + sole_field.vis.is_accessible_from(expr.hir_id.owner, self.tcx) // Skip suggestions for unstable public fields (for example `Pin::pointer`) && matches!(self.tcx.eval_stability(sole_field.did, None, expr.span, None), EvalResult::Allow | EvalResult::Unmarked); diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index e4141647d7d2d..0e6a8ef8265b2 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1729,9 +1729,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let private_fields: Vec<&ty::FieldDef> = variant .fields .iter() - .filter(|field| { - !field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx) - }) + .filter(|field| !field.vis.is_accessible_from(tcx.parent_module(expr_id), tcx)) .collect(); if !private_fields.is_empty() { @@ -2343,7 +2341,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::Adt(def, _) = output_ty.kind() && !def.is_enum() { def.non_enum_variant().fields.iter().any(|field| { field.ident(self.tcx) == ident - && field.vis.is_accessible_from(expr.hir_id.owner.to_def_id(), self.tcx) + && field.vis.is_accessible_from(expr.hir_id.owner, self.tcx) }) } else if let ty::Tuple(tys) = output_ty.kind() && let Ok(idx) = ident.as_str().parse::() diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 124ac5c24fa5c..8065b848ad6f8 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -1161,7 +1161,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => None, }); if let Some((field, field_ty)) = field_receiver { - let scope = tcx.parent_module(self.body_id).to_def_id(); + let scope = tcx.parent_module(self.body_id); let is_accessible = field.vis.is_accessible_from(scope, tcx); if is_accessible { diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 9096fc442d493..9fb915a056ab6 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -1397,7 +1397,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .copied() .filter(|(field, _)| { - field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx) + field.vis.is_accessible_from(tcx.parent_module(pat.hir_id), tcx) && !matches!( tcx.eval_stability(field.did, None, DUMMY_SP, None), EvalResult::Deny { .. } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index be2227f47af61..944c44f017a5e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1777,7 +1777,7 @@ fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool { } } -pub(crate) fn clean_visibility(vis: ty::Visibility) -> Visibility { +pub(crate) fn clean_visibility(vis: ty::Visibility) -> Visibility { match vis { ty::Visibility::Public => Visibility::Public, ty::Visibility::Restricted(module) => Visibility::Restricted(module), @@ -2111,8 +2111,8 @@ fn clean_use_statement<'tcx>( // `pub(super)` or higher. If the current module is the top level // module, there isn't really a parent module, which makes the results // meaningless. In this case, we make sure the answer is `false`. - let is_visible_from_parent_mod = visibility.is_accessible_from(parent_mod.to_def_id(), cx.tcx) - && !current_mod.is_top_level_module(); + let is_visible_from_parent_mod = + visibility.is_accessible_from(parent_mod, cx.tcx) && !current_mod.is_top_level_module(); if pub_underscore { if let Some(ref inline) = inline_attr { diff --git a/src/tools/clippy/clippy_lints/src/default.rs b/src/tools/clippy/clippy_lints/src/default.rs index 74f7df611778e..4e68d6810e29b 100644 --- a/src/tools/clippy/clippy_lints/src/default.rs +++ b/src/tools/clippy/clippy_lints/src/default.rs @@ -142,7 +142,7 @@ impl<'tcx> LateLintPass<'tcx> for Default { if adt.is_struct(); let variant = adt.non_enum_variant(); if adt.did().is_local() || !variant.is_field_list_non_exhaustive(); - let module_did = cx.tcx.parent_module(stmt.hir_id).to_def_id(); + let module_did = cx.tcx.parent_module(stmt.hir_id); if variant .fields .iter() diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 9ca443b7dff6c..23c86482b46cb 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -15,7 +15,7 @@ use rustc_middle::hir::nested_filter; use rustc_middle::traits::Reveal; use rustc_middle::ty::{ self, Binder, BoundConstness, GenericParamDefKind, ImplPolarity, ParamEnv, PredicateKind, TraitPredicate, TraitRef, - Ty, TyCtxt, Visibility, + Ty, TyCtxt, }; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; @@ -464,7 +464,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> { fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>) { if_chain! { if let ty::Adt(adt, substs) = ty.kind(); - if cx.tcx.visibility(adt.did()) == Visibility::Public; + if cx.tcx.visibility(adt.did()).is_public(); if let Some(eq_trait_def_id) = cx.tcx.get_diagnostic_item(sym::Eq); if let Some(def_id) = trait_ref.trait_def_id(); if cx.tcx.is_diagnostic_item(sym::PartialEq, def_id); From 578fc49fc1bbc5498138c84eecad68ee3de54173 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Wed, 7 Sep 2022 14:46:04 -0700 Subject: [PATCH 13/13] Use HashStable_Generic in rustc_type_ir A lot of the types in this crate implemented HashStable directly to avoid circular dependencies. One way around that is to use HashStable_Generic. We adopt that here to avoid a lot of boilerplate. This doesn't update all the types, because some would require `I: Interner + HashStable`. --- Cargo.lock | 1 + compiler/rustc_query_system/Cargo.toml | 1 + .../src/ich/impls_syntax.rs | 2 + compiler/rustc_type_ir/src/lib.rs | 49 ++++--------------- compiler/rustc_type_ir/src/sty.rs | 6 +-- 5 files changed, 16 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 68ea8b51c555c..90bcc2e4be42a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3958,6 +3958,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", + "rustc_type_ir", "smallvec", "thin-vec", "tracing", diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index bafc6b0a08233..d7599a56c0b66 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -21,6 +21,7 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } +rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.8" tracing = "0.1" diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs index d7732cb1825b1..0bc811eb04412 100644 --- a/compiler/rustc_query_system/src/ich/impls_syntax.rs +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -148,3 +148,5 @@ impl<'tcx> HashStable> for rustc_feature::Features { }); } } + +impl<'ctx> rustc_type_ir::HashStableContext for StableHashingContext<'ctx> {} diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 5488bca8f471d..da30344ef7ec0 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -23,6 +23,9 @@ pub mod sty; pub use codec::*; pub use sty::*; +/// Needed so we can use #[derive(HashStable_Generic)] +pub trait HashStableContext {} + pub trait Interner { type AdtDef: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type SubstsRef: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; @@ -295,6 +298,7 @@ rustc_index::newtype_index! { /// is the outer fn. /// /// [dbi]: https://en.wikipedia.org/wiki/De_Bruijn_index + #[derive(HashStable_Generic)] pub struct DebruijnIndex { DEBUG_FORMAT = "DebruijnIndex({})", const INNERMOST = 0, @@ -366,7 +370,7 @@ impl DebruijnIndex { } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[derive(Encodable, Decodable)] +#[derive(Encodable, Decodable, HashStable_Generic)] pub enum IntTy { Isize, I8, @@ -413,7 +417,7 @@ impl IntTy { } #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)] -#[derive(Encodable, Decodable)] +#[derive(Encodable, Decodable, HashStable_Generic)] pub enum UintTy { Usize, U8, @@ -460,7 +464,7 @@ impl UintTy { } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[derive(Encodable, Decodable)] +#[derive(Encodable, Decodable, HashStable_Generic)] pub enum FloatTy { F32, F64, @@ -597,7 +601,7 @@ impl UnifyKey for FloatVid { } } -#[derive(Copy, Clone, PartialEq, Decodable, Encodable, Hash)] +#[derive(Copy, Clone, PartialEq, Decodable, Encodable, Hash, HashStable_Generic)] #[rustc_pass_by_value] pub enum Variance { Covariant, // T <: T iff A <: B -- e.g., function return type @@ -666,30 +670,6 @@ impl Variance { } } -impl HashStable for DebruijnIndex { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self.as_u32().hash_stable(ctx, hasher); - } -} - -impl HashStable for IntTy { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - discriminant(self).hash_stable(ctx, hasher); - } -} - -impl HashStable for UintTy { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - discriminant(self).hash_stable(ctx, hasher); - } -} - -impl HashStable for FloatTy { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - discriminant(self).hash_stable(ctx, hasher); - } -} - impl HashStable for InferTy { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { use InferTy::*; @@ -703,12 +683,6 @@ impl HashStable for InferTy { } } -impl HashStable for Variance { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - discriminant(self).hash_stable(ctx, hasher); - } -} - impl fmt::Debug for IntVarValue { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { @@ -811,6 +785,7 @@ rustc_index::newtype_index! { /// declared, but a type name in a non-zero universe is a placeholder /// type -- an idealized representative of "types in general" that we /// use for checking generic functions. + #[derive(HashStable_Generic)] pub struct UniverseIndex { DEBUG_FORMAT = "U{}", } @@ -850,9 +825,3 @@ impl UniverseIndex { self.private < other.private } } - -impl HashStable for UniverseIndex { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self.private.hash_stable(ctx, hasher); - } -} diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index 74737e30bb4d3..26e48d2d2147e 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -3,7 +3,6 @@ use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; use std::{fmt, hash}; -use crate::DebruijnIndex; use crate::FloatTy; use crate::IntTy; use crate::Interner; @@ -11,6 +10,7 @@ use crate::TyDecoder; use crate::TyEncoder; use crate::UintTy; use crate::UniverseIndex; +use crate::{DebruijnIndex, HashStableContext}; use self::RegionKind::*; use self::TyKind::*; @@ -774,7 +774,7 @@ where // This is not a derived impl because a derive would require `I: HashStable` #[allow(rustc::usage_of_ty_tykind)] -impl HashStable for TyKind +impl HashStable for TyKind where I::AdtDef: HashStable, I::DefId: HashStable, @@ -1286,7 +1286,7 @@ where } // This is not a derived impl because a derive would require `I: HashStable` -impl HashStable for RegionKind +impl HashStable for RegionKind where I::EarlyBoundRegion: HashStable, I::BoundRegion: HashStable,