From 14d288fe125813b130a6571bbf2ae49c5f247174 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 23 Apr 2022 11:05:31 +0100 Subject: [PATCH 01/21] socket `set_mark` addition. to be able to set a marker/id on the socket for network filtering (iptables/ipfw here) purpose. --- library/std/src/os/unix/net/stream.rs | 6 ++++++ library/std/src/sys/unix/net.rs | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index 1d6083e66e1..7eb06be3e09 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -424,6 +424,12 @@ impl UnixStream { self.0.passcred() } + #[cfg(any(doc, target_os = "linux", target_os = "freebsd",))] + #[unstable(feature = "unix_set_mark", issue = "none")] + pub fn set_mark(&self, mark: u32) -> io::Result<()> { + self.0.set_mark(mark) + } + /// Returns the value of the `SO_ERROR` option. /// /// # Examples diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs index a1bbc2d87b6..60ee52528c5 100644 --- a/library/std/src/sys/unix/net.rs +++ b/library/std/src/sys/unix/net.rs @@ -427,6 +427,16 @@ impl Socket { self.0.set_nonblocking(nonblocking) } + #[cfg(target_os = "linux")] + pub fn set_mark(&self, mark: u32) -> io::Result<()> { + setsockopt(self, libc::SOL_SOCKET, libc::SO_MARK, mark as libc::c_int) + } + + #[cfg(target_os = "freebsd")] + pub fn set_mark(&self, mark: u32) -> io::Result<()> { + setsockopt(self, libc::SOL_SOCKET, libc::SO_USER_COOKIE, mark) + } + pub fn take_error(&self) -> io::Result> { let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?; if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } From 48ef00e36f58c1debaec8d5612297b8819f7a690 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 27 Apr 2022 06:01:05 +0100 Subject: [PATCH 02/21] doc additions --- library/std/src/os/unix/net/datagram.rs | 19 +++++++++++++++++++ library/std/src/os/unix/net/stream.rs | 15 ++++++++++++++- library/std/src/sys/unix/net.rs | 5 +++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs index 8008acfd1c9..7f5d760481b 100644 --- a/library/std/src/os/unix/net/datagram.rs +++ b/library/std/src/os/unix/net/datagram.rs @@ -838,6 +838,25 @@ impl UnixDatagram { self.0.passcred() } + /// Set the id of the socket for network filtering purpose + /// and is only a setter. + /// + /// ```no_run + /// #![feature(unix_set_mark)] + /// use std::os::unix::net::UnixDatagram; + /// + /// fn main() -> std::io::Result<()> { + /// let sock = UnixDatagram::unbound()?; + /// sock.set_mark(32 as u32).expect("set_mark function failed"); + /// Ok(()) + /// } + /// ``` + #[cfg(any(doc, target_os = "linux", target_os = "freebsd", target_os = "openbsd",))] + #[unstable(feature = "unix_set_mark", issue = "none")] + pub fn set_mark(&self, mark: u32) -> io::Result<()> { + self.0.set_mark(mark) + } + /// Returns the value of the `SO_ERROR` option. /// /// # Examples diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index 7eb06be3e09..7ecb81340ac 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -424,7 +424,20 @@ impl UnixStream { self.0.passcred() } - #[cfg(any(doc, target_os = "linux", target_os = "freebsd",))] + /// Set the id of the socket for network filtering purpose + /// and is only a setter. + /// + /// ```no_run + /// #![feature(unix_set_mark)] + /// use std::os::unix::net::UnixStream; + /// + /// fn main() -> std::io::Result<()> { + /// let sock = UnixStream::connect("/tmp/sock")?; + /// sock.set_mark(32 as u32).expect("set_mark function failed"); + /// Ok(()) + /// } + /// ``` + #[cfg(any(doc, target_os = "linux", target_os = "freebsd", target_os = "openbsd",))] #[unstable(feature = "unix_set_mark", issue = "none")] pub fn set_mark(&self, mark: u32) -> io::Result<()> { self.0.set_mark(mark) diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs index 60ee52528c5..30667edafba 100644 --- a/library/std/src/sys/unix/net.rs +++ b/library/std/src/sys/unix/net.rs @@ -437,6 +437,11 @@ impl Socket { setsockopt(self, libc::SOL_SOCKET, libc::SO_USER_COOKIE, mark) } + #[cfg(target_os = "openbsd")] + pub fn set_mark(&self, mark: u32) -> io::Result<()> { + setsockopt(self, libc::SOL_SOCKET, libc::SO_RTABLE, mark as libc::c_int) + } + pub fn take_error(&self) -> io::Result> { let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?; if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } From 10f5a19a4deac4a7300ed6bfad11731d451713b0 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 6 Jul 2022 20:01:25 +0100 Subject: [PATCH 03/21] changes from feedback --- library/std/src/os/unix/net/datagram.rs | 5 ++--- library/std/src/os/unix/net/stream.rs | 5 ++--- library/std/src/sys/unix/net.rs | 20 ++++++++------------ 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs index 7f5d760481b..02d0f24cd65 100644 --- a/library/std/src/os/unix/net/datagram.rs +++ b/library/std/src/os/unix/net/datagram.rs @@ -839,7 +839,6 @@ impl UnixDatagram { } /// Set the id of the socket for network filtering purpose - /// and is only a setter. /// /// ```no_run /// #![feature(unix_set_mark)] @@ -847,12 +846,12 @@ impl UnixDatagram { /// /// fn main() -> std::io::Result<()> { /// let sock = UnixDatagram::unbound()?; - /// sock.set_mark(32 as u32).expect("set_mark function failed"); + /// sock.set_mark(32)?; /// Ok(()) /// } /// ``` #[cfg(any(doc, target_os = "linux", target_os = "freebsd", target_os = "openbsd",))] - #[unstable(feature = "unix_set_mark", issue = "none")] + #[unstable(feature = "unix_set_mark", issue = "96467")] pub fn set_mark(&self, mark: u32) -> io::Result<()> { self.0.set_mark(mark) } diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index 7ecb81340ac..ece0f91dad0 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -425,7 +425,6 @@ impl UnixStream { } /// Set the id of the socket for network filtering purpose - /// and is only a setter. /// /// ```no_run /// #![feature(unix_set_mark)] @@ -433,12 +432,12 @@ impl UnixStream { /// /// fn main() -> std::io::Result<()> { /// let sock = UnixStream::connect("/tmp/sock")?; - /// sock.set_mark(32 as u32).expect("set_mark function failed"); + /// sock.set_mark(32)?; /// Ok(()) /// } /// ``` #[cfg(any(doc, target_os = "linux", target_os = "freebsd", target_os = "openbsd",))] - #[unstable(feature = "unix_set_mark", issue = "none")] + #[unstable(feature = "unix_set_mark", issue = "96467")] pub fn set_mark(&self, mark: u32) -> io::Result<()> { self.0.set_mark(mark) } diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs index 30667edafba..c942689eddf 100644 --- a/library/std/src/sys/unix/net.rs +++ b/library/std/src/sys/unix/net.rs @@ -427,19 +427,15 @@ impl Socket { self.0.set_nonblocking(nonblocking) } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))] pub fn set_mark(&self, mark: u32) -> io::Result<()> { - setsockopt(self, libc::SOL_SOCKET, libc::SO_MARK, mark as libc::c_int) - } - - #[cfg(target_os = "freebsd")] - pub fn set_mark(&self, mark: u32) -> io::Result<()> { - setsockopt(self, libc::SOL_SOCKET, libc::SO_USER_COOKIE, mark) - } - - #[cfg(target_os = "openbsd")] - pub fn set_mark(&self, mark: u32) -> io::Result<()> { - setsockopt(self, libc::SOL_SOCKET, libc::SO_RTABLE, mark as libc::c_int) + #[cfg(target_os = "linux")] + let option = libc::SO_MARK; + #[cfg(target_os = "freebsd")] + let option = libc::SO_USER_COOKIE; + #[cfg(target_os = "openbsd")] + let option = libc::SO_RTABLE; + setsockopt(self, libc::SOL_SOCKET, option, mark as libc::c_int) } pub fn take_error(&self) -> io::Result> { From f6efb0b74f286dc806b2fb46b3bd880606533c64 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Thu, 7 Jul 2022 13:45:05 +0100 Subject: [PATCH 04/21] Fix doc build on unsupported oses --- library/std/src/os/unix/net/datagram.rs | 9 ++++++++- library/std/src/os/unix/net/stream.rs | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs index 02d0f24cd65..f758f88d0a3 100644 --- a/library/std/src/os/unix/net/datagram.rs +++ b/library/std/src/os/unix/net/datagram.rs @@ -840,7 +840,14 @@ impl UnixDatagram { /// Set the id of the socket for network filtering purpose /// - /// ```no_run + #[cfg_attr( + any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"), + doc = "```no_run" + )] + #[cfg_attr( + not(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd")), + doc = "```ignore" + )] /// #![feature(unix_set_mark)] /// use std::os::unix::net::UnixDatagram; /// diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index ece0f91dad0..240c5a77105 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -426,7 +426,14 @@ impl UnixStream { /// Set the id of the socket for network filtering purpose /// - /// ```no_run + #[cfg_attr( + any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"), + doc = "```no_run" + )] + #[cfg_attr( + not(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd")), + doc = "```ignore" + )] /// #![feature(unix_set_mark)] /// use std::os::unix::net::UnixStream; /// From 313d474b35fd6e60302324f75622d77765e1cbf8 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Sun, 21 Aug 2022 20:56:00 +0300 Subject: [PATCH 05/21] Migrate OpaqueHiddenType, E0282, E0283, E0284, E0698 --- Cargo.lock | 1 + .../locales/en-US/infer.ftl | 65 ++++ compiler/rustc_error_messages/src/lib.rs | 1 + compiler/rustc_infer/Cargo.toml | 1 + compiler/rustc_infer/src/errors.rs | 187 +++++++++++ .../infer/error_reporting/need_type_info.rs | 312 ++++++++++-------- compiler/rustc_infer/src/lib.rs | 3 + 7 files changed, 440 insertions(+), 130 deletions(-) create mode 100644 compiler/rustc_error_messages/locales/en-US/infer.ftl create mode 100644 compiler/rustc_infer/src/errors.rs diff --git a/Cargo.lock b/Cargo.lock index ebacd32db4f..853a2976bc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3983,6 +3983,7 @@ dependencies = [ "rustc_macros", "rustc_middle", "rustc_serialize", + "rustc_session", "rustc_span", "rustc_target", "smallvec", diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl new file mode 100644 index 00000000000..9250363551d --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -0,0 +1,65 @@ +infer_opaque_hidden_type = + opaque type's hidden type cannot be another opaque type from the same scope + .label = one of the two opaque types used here has to be outside its defining scope + .opaque_type = opaque type whose hidden type is being assigned + .hidden_type = opaque type being used as hidden type + +infer_type_annotations_needed = {$source_kind -> + [closure] type annotations needed for the closure `{$source_name}` + [normal] type annotations needed for `{$source_name}` + *[other] type annotations needed +} + .label = type must be known at this point + +infer_label_bad = {$bad_kind -> + *[other] cannot infer type + [more_info] cannot infer {$prefix_kind -> + *[type] type for {$prefix} + [const_with_param] the value of const parameter + [const] the value of the constant + } `{$name}`{$has_parent -> + [true] {" "}declared on the {$parent_prefix} `{$parent_name}` + *[false] {""} + } +} + +infer_source_kind_subdiag_let = {$kind -> + [with_pattern] consider giving `{$name}` an explicit type + [closure] consider giving this closure parameter an explicit type + *[other] consider giving this pattern a type +}{$x_kind -> + [has_name] , where the {$prefix_kind -> + *[type] type for {$prefix} + [const_with_param] the value of const parameter + [const] the value of the constant + } `{$arg_name}` is specified + [underscore] , where the placeholders `_` are specified + *[empty] {""} +} + +infer_source_kind_subdiag_generic_label = + cannot infer {$is_type -> + [true] type + *[false] the value + } of the {$is_type -> + [true] type + *[false] const + } {$parent_exists -> + [true] parameter `{$param_name}` declared on the {$parent_prefix} `{$parent_name}` + *[false] parameter {$param_name} + } + +infer_source_kind_subdiag_generic_suggestion = + consider specifying the generic {$arg_count -> + [one] argument + *[other] arguments + } + +infer_source_kind_fully_qualified = + try using a fully qualified path to specify the expected types + +infer_source_kind_closure_return = + try giving this closure an explicit return type + +infer_need_type_info_in_generator = + type inside {$generator_kind} must be known in this context diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 3569c7f0630..a24ab307292 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -38,6 +38,7 @@ fluent_messages! { const_eval => "../locales/en-US/const_eval.ftl", expand => "../locales/en-US/expand.ftl", interface => "../locales/en-US/interface.ftl", + infer => "../locales/en-US/infer.ftl", lint => "../locales/en-US/lint.ftl", parser => "../locales/en-US/parser.ftl", passes => "../locales/en-US/passes.ftl", diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 02ac83a5e8b..aced787d671 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -15,6 +15,7 @@ rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } +rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_infer/src/errors.rs b/compiler/rustc_infer/src/errors.rs new file mode 100644 index 00000000000..7bd418ddf5f --- /dev/null +++ b/compiler/rustc_infer/src/errors.rs @@ -0,0 +1,187 @@ +use rustc_errors::{fluent, AddSubdiagnostic}; +use rustc_hir::FnRetTy; +use rustc_macros::SessionDiagnostic; +use rustc_span::{BytePos, Span}; + +#[derive(SessionDiagnostic)] +#[diag(infer::opaque_hidden_type)] +pub struct OpaqueHiddenTypeDiag { + #[primary_span] + #[label] + pub span: Span, + #[note(infer::opaque_type)] + pub opaque_type: Span, + #[note(infer::hidden_type)] + pub hidden_type: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(infer::type_annotations_needed, code = "E0282")] +pub struct AnnotationRequired<'a> { + #[primary_span] + pub span: Span, + pub source_kind: &'static str, + pub source_name: &'a str, + #[label] + pub failure_span: Option, + #[subdiagnostic] + pub bad_label: Option>, + #[subdiagnostic] + pub infer_subdiags: Vec>, + #[subdiagnostic] + pub multi_suggestions: Vec>, +} + +// Copy of `AnnotationRequired` for E0283 +#[derive(SessionDiagnostic)] +#[diag(infer::type_annotations_needed, code = "E0283")] +pub struct AmbigousImpl<'a> { + #[primary_span] + pub span: Span, + pub source_kind: &'static str, + pub source_name: &'a str, + #[label] + pub failure_span: Option, + #[subdiagnostic] + pub bad_label: Option>, + #[subdiagnostic] + pub infer_subdiags: Vec>, + #[subdiagnostic] + pub multi_suggestions: Vec>, +} + +// Copy of `AnnotationRequired` for E0284 +#[derive(SessionDiagnostic)] +#[diag(infer::type_annotations_needed, code = "E0284")] +pub struct AmbigousReturn<'a> { + #[primary_span] + pub span: Span, + pub source_kind: &'static str, + pub source_name: &'a str, + #[label] + pub failure_span: Option, + #[subdiagnostic] + pub bad_label: Option>, + #[subdiagnostic] + pub infer_subdiags: Vec>, + #[subdiagnostic] + pub multi_suggestions: Vec>, +} + +#[derive(SessionDiagnostic)] +#[diag(infer::need_type_info_in_generator, code = "E0698")] +pub struct NeedTypeInfoInGenerator<'a> { + #[primary_span] + pub span: Span, + pub generator_kind: String, + #[subdiagnostic] + pub bad_label: InferenceBadError<'a>, +} + +// Used when a better one isn't available +#[derive(SessionSubdiagnostic)] +#[label(infer::label_bad)] +pub struct InferenceBadError<'a> { + #[primary_span] + pub span: Span, + pub bad_kind: &'static str, + pub prefix_kind: &'static str, + pub has_parent: bool, + pub prefix: &'a str, + pub parent_prefix: &'a str, + pub parent_name: String, + pub name: String, +} + +#[derive(SessionSubdiagnostic)] +pub enum SourceKindSubdiag<'a> { + #[suggestion_verbose( + infer::source_kind_subdiag_let, + code = ": {type_name}", + applicability = "has-placeholders" + )] + LetLike { + #[primary_span] + span: Span, + name: String, + type_name: String, + kind: &'static str, + x_kind: &'static str, + prefix_kind: &'static str, + prefix: &'a str, + arg_name: String, + }, + #[label(infer::source_kind_subdiag_generic_label)] + GenericLabel { + #[primary_span] + span: Span, + is_type: bool, + param_name: String, + parent_exists: bool, + parent_prefix: String, + parent_name: String, + }, + #[suggestion_verbose( + infer::source_kind_subdiag_generic_suggestion, + code = "::<{args}>", + applicability = "has-placeholders" + )] + GenericSuggestion { + #[primary_span] + span: Span, + arg_count: usize, + args: String, + }, +} + +// Has to be implemented manually because multipart suggestions are not supported by the derive macro. +// Would be a part of `SourceKindSubdiag` otherwise. +pub enum SourceKindMultiSuggestion<'a> { + FullyQualified { + span: Span, + def_path: String, + adjustment: &'a str, + successor: (&'a str, BytePos), + }, + ClosureReturn { + ty_info: String, + data: &'a FnRetTy<'a>, + should_wrap_expr: 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, + ); + } + } + } +} 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 561d1354edd..da0035d2519 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 @@ -1,6 +1,10 @@ +use crate::errors::{ + AmbigousImpl, AmbigousReturn, AnnotationRequired, InferenceBadError, NeedTypeInfoInGenerator, + SourceKindMultiSuggestion, SourceKindSubdiag, +}; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::InferCtxt; -use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def::{CtorOf, DefKind, Namespace}; @@ -14,6 +18,7 @@ use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef}; use rustc_middle::ty::{self, DefIdTree, InferConst}; use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults}; +use rustc_session::SessionDiagnostic; use rustc_span::symbol::{kw, Ident}; use rustc_span::{BytePos, Span}; use std::borrow::Cow; @@ -66,32 +71,42 @@ pub enum UnderspecifiedArgKind { } impl InferenceDiagnosticsData { - /// Generate a label for a generic argument which can't be inferred. When not - /// much is known about the argument, `use_diag` may be used to describe the - /// labeled value. - fn cannot_infer_msg(&self) -> String { - if self.name == "_" && matches!(self.kind, UnderspecifiedArgKind::Type { .. }) { - return "cannot infer type".to_string(); - } - - let suffix = match &self.parent { - Some(parent) => parent.suffix_string(), - None => String::new(), - }; - - // For example: "cannot infer type for type parameter `T`" - format!("cannot infer {} `{}`{}", self.kind.prefix_string(), self.name, suffix) + fn can_add_more_info(&self) -> bool { + !(self.name == "_" && matches!(self.kind, UnderspecifiedArgKind::Type { .. })) } - fn where_x_is_specified(&self, in_type: Ty<'_>) -> String { + fn where_x_is_kind(&self, in_type: Ty<'_>) -> &'static str { if in_type.is_ty_infer() { - String::new() + "empty" } else if self.name == "_" { // FIXME: Consider specializing this message if there is a single `_` // in the type. - ", where the placeholders `_` are specified".to_string() + "underscore" } else { - format!(", where the {} `{}` is specified", self.kind.prefix_string(), self.name) + "has_name" + } + } + + /// Generate a label for a generic argument which can't be inferred. When not + /// much is known about the argument, `use_diag` may be used to describe the + /// labeled value. + fn make_bad_error(&self, span: Span) -> InferenceBadError<'_> { + let has_parent = self.parent.is_some(); + let bad_kind = if self.can_add_more_info() { "more_info" } else { "other" }; + let (parent_prefix, parent_name) = self + .parent + .as_ref() + .map(|parent| (parent.prefix, parent.name.clone())) + .unwrap_or_default(); + InferenceBadError { + span, + bad_kind, + prefix_kind: self.kind.prefix_kind(), + prefix: self.kind.try_get_prefix().unwrap_or_default(), + name: self.name.clone(), + has_parent, + parent_prefix, + parent_name, } } } @@ -113,18 +128,20 @@ impl InferenceDiagnosticsParentData { fn for_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option { Self::for_parent_def_id(tcx, tcx.parent(def_id)) } - - fn suffix_string(&self) -> String { - format!(" declared on the {} `{}`", self.prefix, self.name) - } } impl UnderspecifiedArgKind { - fn prefix_string(&self) -> Cow<'static, str> { + fn prefix_kind(&self) -> &'static str { match self { - Self::Type { prefix } => format!("type for {}", prefix).into(), - Self::Const { is_parameter: true } => "the value of const parameter".into(), - Self::Const { is_parameter: false } => "the value of the constant".into(), + Self::Type { .. } => "type", + Self::Const { is_parameter: true } => "const_with_param", + Self::Const { is_parameter: false } => "const", + } + } + fn try_get_prefix(&self) -> Option<&str> { + match self { + Self::Type { prefix } => Some(prefix.as_ref()), + Self::Const { .. } => None, } } } @@ -303,11 +320,44 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { arg_data: InferenceDiagnosticsData, error_code: TypeAnnotationNeeded, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - let error_code = error_code.into(); - let mut err = - self.tcx.sess.struct_span_err_with_code(span, "type annotations needed", error_code); - err.span_label(span, arg_data.cannot_infer_msg()); - err + let source_kind = "other"; + let source_name = ""; + let failure_span = None; + let infer_subdiags = Vec::new(); + let multi_suggestions = Vec::new(); + let bad_label = Some(arg_data.make_bad_error(span)); + match error_code { + TypeAnnotationNeeded::E0282 => AnnotationRequired { + span, + source_kind, + source_name, + failure_span, + infer_subdiags, + multi_suggestions, + bad_label, + } + .into_diagnostic(&self.tcx.sess.parse_sess), + TypeAnnotationNeeded::E0283 => AmbigousImpl { + span, + source_kind, + source_name, + failure_span, + infer_subdiags, + multi_suggestions, + bad_label, + } + .into_diagnostic(&self.tcx.sess.parse_sess), + TypeAnnotationNeeded::E0284 => AmbigousReturn { + span, + source_kind, + source_name, + failure_span, + infer_subdiags, + multi_suggestions, + bad_label, + } + .into_diagnostic(&self.tcx.sess.parse_sess), + } } pub fn emit_inference_failure_err( @@ -340,48 +390,39 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { return self.bad_inference_failure_err(failure_span, arg_data, error_code) }; - let error_code = error_code.into(); - let mut err = self.tcx.sess.struct_span_err_with_code( - span, - &format!("type annotations needed{}", kind.ty_msg(self)), - error_code, - ); - - if should_label_span && !failure_span.overlaps(span) { - err.span_label(failure_span, "type must be known at this point"); - } + let (source_kind, name) = kind.ty_localized_msg(self); + let failure_span = if should_label_span && !failure_span.overlaps(span) { + Some(failure_span) + } else { + None + }; + let mut infer_subdiags = Vec::new(); + let mut multi_suggestions = Vec::new(); match kind { InferSourceKind::LetBinding { insert_span, pattern_name, ty } => { - let suggestion_msg = if let Some(name) = pattern_name { - format!( - "consider giving `{}` an explicit type{}", - name, - arg_data.where_x_is_specified(ty) - ) - } else { - format!( - "consider giving this pattern a type{}", - arg_data.where_x_is_specified(ty) - ) - }; - err.span_suggestion_verbose( - insert_span, - &suggestion_msg, - format!(": {}", ty_to_string(self, ty)), - Applicability::HasPlaceholders, - ); + infer_subdiags.push(SourceKindSubdiag::LetLike { + span: insert_span, + name: pattern_name.map(|name| name.to_string()).unwrap_or_else(String::new), + x_kind: arg_data.where_x_is_kind(ty), + prefix_kind: arg_data.kind.prefix_kind(), + prefix: arg_data.kind.try_get_prefix().unwrap_or_default(), + arg_name: arg_data.name, + kind: if pattern_name.is_some() { "with_pattern" } else { "other" }, + type_name: ty_to_string(self, ty), + }); } InferSourceKind::ClosureArg { insert_span, ty } => { - err.span_suggestion_verbose( - insert_span, - &format!( - "consider giving this closure parameter an explicit type{}", - arg_data.where_x_is_specified(ty) - ), - format!(": {}", ty_to_string(self, ty)), - Applicability::HasPlaceholders, - ); + infer_subdiags.push(SourceKindSubdiag::LetLike { + span: insert_span, + name: String::new(), + x_kind: arg_data.where_x_is_kind(ty), + prefix_kind: arg_data.kind.prefix_kind(), + prefix: arg_data.kind.try_get_prefix().unwrap_or_default(), + arg_name: arg_data.name, + kind: "closure", + type_name: ty_to_string(self, ty), + }); } InferSourceKind::GenericArg { insert_span, @@ -393,19 +434,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let generics = self.tcx.generics_of(generics_def_id); let is_type = matches!(arg.unpack(), GenericArgKind::Type(_)); - let cannot_infer_msg = format!( - "cannot infer {} of the {} parameter `{}`{}", - if is_type { "type" } else { "the value" }, - if is_type { "type" } else { "const" }, - generics.params[argument_index].name, - // We use the `generics_def_id` here, as even when suggesting `None::`, - // the type parameter `T` was still declared on the enum, not on the - // variant. + let (parent_exists, parent_prefix, parent_name) = InferenceDiagnosticsParentData::for_parent_def_id(self.tcx, generics_def_id) - .map_or(String::new(), |parent| parent.suffix_string()), - ); + .map_or((false, String::new(), String::new()), |parent| { + (true, parent.prefix.to_string(), parent.name) + }); - err.span_label(span, cannot_infer_msg); + infer_subdiags.push(SourceKindSubdiag::GenericLabel { + span, + is_type, + param_name: generics.params[argument_index].name.to_string(), + parent_exists, + parent_prefix, + parent_name, + }); let args = fmt_printer(self, Namespace::TypeNS) .comma_sep(generic_args.iter().copied().map(|arg| { @@ -435,15 +477,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .unwrap() .into_buffer(); - err.span_suggestion_verbose( - insert_span, - &format!( - "consider specifying the generic argument{}", - pluralize!(generic_args.len()), - ), - format!("::<{}>", args), - Applicability::HasPlaceholders, - ); + infer_subdiags.push(SourceKindSubdiag::GenericSuggestion { + span: insert_span, + arg_count: generic_args.len(), + args, + }); } InferSourceKind::FullyQualifiedMethodCall { receiver, successor, substs, def_id } => { let printer = fmt_printer(self, Namespace::ValueNS); @@ -468,37 +506,54 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { _ => "", }; - let suggestion = vec![ - (receiver.span.shrink_to_lo(), format!("{def_path}({adjustment}")), - (receiver.span.shrink_to_hi().with_hi(successor.1), successor.0.to_string()), - ]; - err.multipart_suggestion_verbose( - "try using a fully qualified path to specify the expected types", - suggestion, - Applicability::HasPlaceholders, - ); + multi_suggestions.push(SourceKindMultiSuggestion::FullyQualified { + span: receiver.span, + def_path, + adjustment, + successor, + }); } InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => { - let ret = ty_to_string(self, ty); - let (arrow, post) = match data { - FnRetTy::DefaultReturn(_) => ("-> ", " "), - _ => ("", ""), - }; - let suggestion = match should_wrap_expr { - Some(end_span) => vec![ - (data.span(), format!("{}{}{}{{ ", arrow, ret, post)), - (end_span, " }".to_string()), - ], - None => vec![(data.span(), format!("{}{}{}", arrow, ret, post))], - }; - err.multipart_suggestion_verbose( - "try giving this closure an explicit return type", - suggestion, - Applicability::HasPlaceholders, - ); + let ty_info = ty_to_string(self, ty); + multi_suggestions.push(SourceKindMultiSuggestion::ClosureReturn { + ty_info, + data, + should_wrap_expr, + }); } } - err + match error_code { + TypeAnnotationNeeded::E0282 => AnnotationRequired { + span, + source_kind, + source_name: &name, + failure_span, + infer_subdiags, + multi_suggestions, + bad_label: None, + } + .into_diagnostic(&self.tcx.sess.parse_sess), + TypeAnnotationNeeded::E0283 => AmbigousImpl { + span, + source_kind, + source_name: &name, + failure_span, + infer_subdiags, + multi_suggestions, + bad_label: None, + } + .into_diagnostic(&self.tcx.sess.parse_sess), + TypeAnnotationNeeded::E0284 => AmbigousReturn { + span, + source_kind, + source_name: &name, + failure_span, + infer_subdiags, + multi_suggestions, + bad_label: None, + } + .into_diagnostic(&self.tcx.sess.parse_sess), + } } pub fn need_type_info_err_in_generator( @@ -510,15 +565,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let ty = self.resolve_vars_if_possible(ty); let data = self.extract_inference_diagnostics_data(ty.into(), None); - let mut err = struct_span_err!( - self.tcx.sess, + NeedTypeInfoInGenerator { + bad_label: data.make_bad_error(span), span, - E0698, - "type inside {} must be known in this context", - kind, - ); - err.span_label(span, data.cannot_infer_msg()); - err + generator_kind: kind.to_string(), + } + .into_diagnostic(&self.tcx.sess.parse_sess) } } @@ -579,22 +631,22 @@ impl<'tcx> InferSource<'tcx> { } impl<'tcx> InferSourceKind<'tcx> { - fn ty_msg(&self, infcx: &InferCtxt<'_, 'tcx>) -> String { + fn ty_localized_msg(&self, infcx: &InferCtxt<'_, 'tcx>) -> (&'static str, String) { match *self { InferSourceKind::LetBinding { ty, .. } | InferSourceKind::ClosureArg { ty, .. } | InferSourceKind::ClosureReturn { ty, .. } => { if ty.is_closure() { - format!(" for the closure `{}`", closure_as_fn_str(infcx, ty)) + ("closure", closure_as_fn_str(infcx, ty)) } else if !ty.is_ty_infer() { - format!(" for `{}`", ty_to_string(infcx, ty)) + ("normal", ty_to_string(infcx, ty)) } else { - String::new() + ("other", String::new()) } } // FIXME: We should be able to add some additional info here. InferSourceKind::GenericArg { .. } - | InferSourceKind::FullyQualifiedMethodCall { .. } => String::new(), + | InferSourceKind::FullyQualifiedMethodCall { .. } => ("other", String::new()), } } } diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 1c515f5ee57..2c1d339b578 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -23,6 +23,8 @@ #![feature(never_type)] #![feature(try_blocks)] #![recursion_limit = "512"] // For rustdoc +// #![deny(rustc::untranslatable_diagnostic)] +// #![deny(rustc::diagnostic_outside_of_impl)] #[macro_use] extern crate rustc_macros; @@ -34,5 +36,6 @@ extern crate tracing; #[macro_use] extern crate rustc_middle; +mod errors; pub mod infer; pub mod traits; From 7e4f4337203b247bdbfbb0661e59ab1aa3bee3f1 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Sun, 21 Aug 2022 22:39:46 +0300 Subject: [PATCH 06/21] Actually migrate OpaqueHiddenType --- .../rustc_infer/src/infer/opaque_types.rs | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index e579afbf389..233a5004a39 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -1,3 +1,4 @@ +use crate::errors::OpaqueHiddenTypeDiag; use crate::infer::{DefiningAnchor, InferCtxt, InferOk}; use crate::traits; use hir::def_id::{DefId, LocalDefId}; @@ -153,22 +154,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if let Some(OpaqueTyOrigin::TyAlias) = did2.as_local().and_then(|did2| self.opaque_type_origin(did2, cause.span)) { - self.tcx - .sess - .struct_span_err( - cause.span, - "opaque type's hidden type cannot be another opaque type from the same scope", - ) - .span_label(cause.span, "one of the two opaque types used here has to be outside its defining scope") - .span_note( - self.tcx.def_span(def_id), - "opaque type whose hidden type is being assigned", - ) - .span_note( - self.tcx.def_span(did2), - "opaque type being used as hidden type", - ) - .emit(); + self.tcx.sess.emit_err(OpaqueHiddenTypeDiag { + span: cause.span, + hidden_type: self.tcx.def_span(did2), + opaque_type: self.tcx.def_span(def_id), + }); } } Some(self.register_hidden_type( From 3f6cb475f7aa1f4475fdb313316a7df644113376 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Mon, 22 Aug 2022 00:17:46 +0300 Subject: [PATCH 07/21] Use GeneratorKind::descr() instead of it's Display impl Those are basically the same but the first one seems to fit better --- compiler/rustc_infer/src/errors.rs | 2 +- .../rustc_infer/src/infer/error_reporting/need_type_info.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_infer/src/errors.rs b/compiler/rustc_infer/src/errors.rs index 7bd418ddf5f..51993f37bb3 100644 --- a/compiler/rustc_infer/src/errors.rs +++ b/compiler/rustc_infer/src/errors.rs @@ -73,7 +73,7 @@ pub struct AmbigousReturn<'a> { pub struct NeedTypeInfoInGenerator<'a> { #[primary_span] pub span: Span, - pub generator_kind: String, + pub generator_kind: &'static str, #[subdiagnostic] pub bad_label: InferenceBadError<'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 da0035d2519..daf64aeb053 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 @@ -568,7 +568,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { NeedTypeInfoInGenerator { bad_label: data.make_bad_error(span), span, - generator_kind: kind.to_string(), + generator_kind: kind.descr(), } .into_diagnostic(&self.tcx.sess.parse_sess) } From f50d1713fd4aab1ff9d160e9fa4b20cd2f71e68a Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Tue, 23 Aug 2022 13:48:14 +0300 Subject: [PATCH 08/21] Migrate note_region_origin function --- .../locales/en-US/infer.ftl | 43 ++++++++ compiler/rustc_infer/src/errors.rs | 64 ++++++++++- .../src/infer/error_reporting/mod.rs | 18 ++++ .../src/infer/error_reporting/note.rs | 101 +++++++++--------- 4 files changed, 173 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 9250363551d..770eaa62b41 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -61,5 +61,48 @@ infer_source_kind_fully_qualified = infer_source_kind_closure_return = try giving this closure an explicit return type +# generator_kind may need to be translated infer_need_type_info_in_generator = type inside {$generator_kind} must be known in this context + + +infer_subtype = ...so that the {$requirement -> + [method_compat] method type is compatible with trait + [type_compat] associated type is compatible with trait + [const_compat] const is compatible with trait + [expr_assignable] expression is assignable + [if_else_different] `if` and `else` have incompatible types + [no_else] `if` missing an `else` returns `()` + [fn_main_correct_type] `main` function has the correct type + [fn_start_correct_type] #[start]` function has the correct type + [intristic_correct_type] intrinsic has the correct type + [method_correct_type] method receiver has the correct type + *[other] types are compatible +} +infer_subtype_2 = ...so that {$requirement -> + [method_compat] method type is compatible with trait + [type_compat] associated type is compatible with trait + [const_compat] const is compatible with trait + [expr_assignable] expression is assignable + [if_else_different] `if` and `else` have incompatible types + [no_else] `if` missing an `else` returns `()` + [fn_main_correct_type] `main` function has the correct type + [fn_start_correct_type] #[start]` function has the correct type + [intristic_correct_type] intrinsic has the correct type + [method_correct_type] method receiver has the correct type + *[other] types are compatible +} + +infer_reborrow = ...so that reference does not outlive borrowed content +infer_reborrow_upvar = ...so that closure can access `{$name}` +infer_relate_object_bound = ...so that it can be closed over into an object +infer_data_borrowed = ...so that the type `{$name}` is not borrowed for too long +infer_reference_outlives_referent = ...so that the reference type `{$name}` does not outlive the data it points at +infer_relate_param_bound = ...so that the type `{$name}` will meet its required lifetime bounds{$continues -> +[true] ... +*[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 + diff --git a/compiler/rustc_infer/src/errors.rs b/compiler/rustc_infer/src/errors.rs index 51993f37bb3..1db8763e499 100644 --- a/compiler/rustc_infer/src/errors.rs +++ b/compiler/rustc_infer/src/errors.rs @@ -1,4 +1,4 @@ -use rustc_errors::{fluent, AddSubdiagnostic}; +use rustc_errors::{fluent, AddSubdiagnostic, DiagnosticMessage, DiagnosticStyledString}; use rustc_hir::FnRetTy; use rustc_macros::SessionDiagnostic; use rustc_span::{BytePos, Span}; @@ -185,3 +185,65 @@ impl AddSubdiagnostic for SourceKindMultiSuggestion<'_> { } } } + +pub enum RegionOriginNote<'a> { + Plain { + span: Span, + msg: DiagnosticMessage, + }, + WithName { + span: Span, + msg: DiagnosticMessage, + name: &'a str, + continues: bool, + }, + WithRequirement { + span: Span, + requirement: &'static str, + expected_found: Option<(DiagnosticStyledString, DiagnosticStyledString)>, + }, +} + +impl AddSubdiagnostic for RegionOriginNote<'_> { + fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + let mut label_or_note = |span, msg: DiagnosticMessage| { + let sub_count = diag.children.iter().filter(|d| d.span.is_dummy()).count(); + let expanded_sub_count = diag.children.iter().filter(|d| !d.span.is_dummy()).count(); + let span_is_primary = diag.span.primary_spans().iter().all(|&sp| sp == span); + if span_is_primary && sub_count == 0 && expanded_sub_count == 0 { + diag.span_label(span, msg); + } else if span_is_primary && expanded_sub_count == 0 { + diag.note(msg); + } else { + diag.span_note(span, msg); + } + }; + match self { + RegionOriginNote::Plain { span, msg } => { + label_or_note(span, msg); + } + RegionOriginNote::WithName { span, msg, name, continues } => { + label_or_note(span, msg); + diag.set_arg("name", name); + diag.set_arg("continues", continues); + } + RegionOriginNote::WithRequirement { + span, + requirement, + expected_found: Some((expected, found)), + } => { + label_or_note(span, fluent::infer::subtype); + diag.set_arg("requirement", requirement); + + diag.note_expected_found(&"", expected, &"", found); + } + RegionOriginNote::WithRequirement { span, requirement, expected_found: None } => { + // FIXME: this really should be handled at some earlier stage. Our + // handling of region checking when type errors are present is + // *terrible*. + label_or_note(span, fluent::infer::subtype_2); + diag.set_arg("requirement", requirement); + } + }; + } +} diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 59ea1f3f9de..13951326665 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2811,6 +2811,7 @@ pub enum FailureCode { pub trait ObligationCauseExt<'tcx> { fn as_failure_code(&self, terr: TypeError<'tcx>) -> FailureCode; fn as_requirement_str(&self) -> &'static str; + fn as_requirement_localised(&self) -> &'static str; } impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> { @@ -2879,6 +2880,23 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> { _ => "types are compatible", } } + + fn as_requirement_localised(&self) -> &'static str { + use crate::traits::ObligationCauseCode::*; + match self.code() { + CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => "method_compat", + CompareImplItemObligation { kind: ty::AssocKind::Type, .. } => "type_compat", + CompareImplItemObligation { kind: ty::AssocKind::Const, .. } => "const_compat", + ExprAssignable => "expr_assignable", + IfExpression { .. } => "if_else_different", + IfExpressionWithNoElse => "no_else", + MainFunctionType => "fn_main_correct_type", + StartFunctionType => "fn_start_correct_type", + IntrinsicType => "intristic_correct_type", + MethodReceiver => "method_correct_type", + _ => "other", + } + } } /// This is a bare signal of what kind of type we're dealing with. `ty::TyKind` tracks diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 8c465b08760..36efbd6824a 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -1,13 +1,17 @@ +use crate::errors::RegionOriginNote; use crate::infer::error_reporting::{note_and_explain_region, ObligationCauseExt}; use crate::infer::{self, InferCtxt, SubregionOrigin}; -use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{ + fluent, struct_span_err, AddSubdiagnostic, Diagnostic, DiagnosticBuilder, DiagnosticMessage, + ErrorGuaranteed, +}; use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{self, Region}; impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub(super) fn note_region_origin(&self, err: &mut Diagnostic, origin: &SubregionOrigin<'tcx>) { - let mut label_or_note = |span, msg: &str| { + let mut label_or_note = |span, msg: DiagnosticMessage| { let sub_count = err.children.iter().filter(|d| d.span.is_dummy()).count(); let expanded_sub_count = err.children.iter().filter(|d| !d.span.is_dummy()).count(); let span_is_primary = err.span.primary_spans().iter().all(|&sp| sp == span); @@ -20,77 +24,70 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } }; match *origin { - infer::Subtype(ref trace) => { - if let Some((expected, found)) = self.values_str(trace.values) { - label_or_note( - trace.cause.span, - &format!("...so that the {}", trace.cause.as_requirement_str()), - ); - - err.note_expected_found(&"", expected, &"", found); - } else { - // FIXME: this really should be handled at some earlier stage. Our - // handling of region checking when type errors are present is - // *terrible*. - - label_or_note( - trace.cause.span, - &format!("...so that {}", trace.cause.as_requirement_str()), - ); - } + infer::Subtype(ref trace) => RegionOriginNote::WithRequirement { + span: trace.cause.span, + requirement: trace.cause.as_requirement_localised(), + expected_found: self.values_str(trace.values), } + .add_to_diagnostic(err), infer::Reborrow(span) => { - label_or_note(span, "...so that reference does not outlive borrowed content"); + label_or_note(span, fluent::infer::reborrow); + RegionOriginNote::Plain { span, msg: fluent::infer::reborrow } + .add_to_diagnostic(err) } infer::ReborrowUpvar(span, ref upvar_id) => { let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); - label_or_note(span, &format!("...so that closure can access `{}`", var_name)); + RegionOriginNote::WithName { + span, + msg: fluent::infer::reborrow, + name: &var_name.to_string(), + continues: false, + } + .add_to_diagnostic(err); } infer::RelateObjectBound(span) => { - label_or_note(span, "...so that it can be closed over into an object"); + label_or_note(span, fluent::infer::relate_object_bound); + RegionOriginNote::Plain { span, msg: fluent::infer::relate_object_bound } + .add_to_diagnostic(err); } infer::DataBorrowed(ty, span) => { - label_or_note( + RegionOriginNote::WithName { span, - &format!( - "...so that the type `{}` is not borrowed for too long", - self.ty_to_string(ty) - ), - ); + msg: fluent::infer::data_borrowed, + name: &self.ty_to_string(ty), + continues: false, + } + .add_to_diagnostic(err); } infer::ReferenceOutlivesReferent(ty, span) => { - label_or_note( + RegionOriginNote::WithName { span, - &format!( - "...so that the reference type `{}` does not outlive the data it points at", - self.ty_to_string(ty) - ), - ); + msg: fluent::infer::reference_outlives_referent, + name: &self.ty_to_string(ty), + continues: false, + } + .add_to_diagnostic(err); } - infer::RelateParamBound(span, t, opt_span) => { - label_or_note( + infer::RelateParamBound(span, ty, opt_span) => { + RegionOriginNote::WithName { span, - &format!( - "...so that the type `{}` will meet its required lifetime bounds{}", - self.ty_to_string(t), - if opt_span.is_some() { "..." } else { "" }, - ), - ); + msg: fluent::infer::relate_param_bound, + name: &self.ty_to_string(ty), + continues: opt_span.is_some(), + } + .add_to_diagnostic(err); if let Some(span) = opt_span { - err.span_note(span, "...that is required by this bound"); + RegionOriginNote::Plain { span, msg: fluent::infer::relate_param_bound_2 } + .add_to_diagnostic(err); } } infer::RelateRegionParamBound(span) => { - label_or_note( - span, - "...so that the declared lifetime parameter bounds are satisfied", - ); + RegionOriginNote::Plain { span, msg: fluent::infer::relate_region_param_bound } + .add_to_diagnostic(err); } infer::CompareImplItemObligation { span, .. } => { - label_or_note( - span, - "...so that the definition in impl matches the definition from the trait", - ); + RegionOriginNote::Plain { span, msg: fluent::infer::compare_impl_item_obligation } + .add_to_diagnostic(err); } infer::CheckAssociatedTypeBounds { ref parent, .. } => { self.note_region_origin(err, &parent); From cb4cd7366415deb659641edcff695aa2e4ffb105 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 22 Aug 2022 21:25:03 -0400 Subject: [PATCH 09/21] extra sanity check against consts pointing to mutable memory --- .../src/interpret/validity.rs | 72 ++++++++++++------- .../const-points-to-static.32bit.stderr | 2 +- .../const-points-to-static.64bit.stderr | 2 +- .../const_refers_to_static2.32bit.stderr | 4 +- .../const_refers_to_static2.64bit.stderr | 4 +- ..._refers_to_static_cross_crate.32bit.stderr | 4 +- ..._refers_to_static_cross_crate.64bit.stderr | 4 +- 7 files changed, 55 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index f1b1855c3ec..0e60f0c7ef1 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -8,6 +8,7 @@ use std::convert::TryFrom; use std::fmt::Write; use std::num::NonZeroUsize; +use rustc_ast::Mutability; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_middle::mir::interpret::InterpError; @@ -411,34 +412,51 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' // Proceed recursively even for ZST, no reason to skip them! // `!` is a ZST and we want to validate it. if let Ok((alloc_id, _offset, _prov)) = self.ecx.ptr_try_get_alloc_id(place.ptr) { - // Special handling for pointers to statics (irrespective of their type). + // Let's see what kind of memory this points to. let alloc_kind = self.ecx.tcx.try_get_global_alloc(alloc_id); - if let Some(GlobalAlloc::Static(did)) = alloc_kind { - assert!(!self.ecx.tcx.is_thread_local_static(did)); - assert!(self.ecx.tcx.is_static(did)); - if matches!( - self.ctfe_mode, - Some(CtfeValidationMode::Const { allow_static_ptrs: false, .. }) - ) { - // See const_eval::machine::MemoryExtra::can_access_statics for why - // this check is so important. - // This check is reachable when the const just referenced the static, - // but never read it (so we never entered `before_access_global`). - throw_validation_failure!(self.path, - { "a {} pointing to a static variable", kind } - ); + match alloc_kind { + Some(GlobalAlloc::Static(did)) => { + // Special handling for pointers to statics (irrespective of their type). + assert!(!self.ecx.tcx.is_thread_local_static(did)); + assert!(self.ecx.tcx.is_static(did)); + if matches!( + self.ctfe_mode, + Some(CtfeValidationMode::Const { allow_static_ptrs: false, .. }) + ) { + // See const_eval::machine::MemoryExtra::can_access_statics for why + // this check is so important. + // This check is reachable when the const just referenced the static, + // but never read it (so we never entered `before_access_global`). + throw_validation_failure!(self.path, + { "a {} pointing to a static variable in a constant", kind } + ); + } + // We skip recursively checking other statics. These statics must be sound by + // themselves, and the only way to get broken statics here is by using + // unsafe code. + // The reasons we don't check other statics is twofold. For one, in all + // sound cases, the static was already validated on its own, and second, we + // trigger cycle errors if we try to compute the value of the other static + // and that static refers back to us. + // We might miss const-invalid data, + // but things are still sound otherwise (in particular re: consts + // referring to statics). + return Ok(()); } - // We skip checking other statics. These statics must be sound by - // themselves, and the only way to get broken statics here is by using - // unsafe code. - // The reasons we don't check other statics is twofold. For one, in all - // sound cases, the static was already validated on its own, and second, we - // trigger cycle errors if we try to compute the value of the other static - // and that static refers back to us. - // We might miss const-invalid data, - // but things are still sound otherwise (in particular re: consts - // referring to statics). - return Ok(()); + Some(GlobalAlloc::Memory(alloc)) => { + if alloc.inner().mutability == Mutability::Mut + && matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { .. })) + { + // This should be unreachable, but if someone manages to copy a pointer + // out of a `static`, then that pointer might point to mutable memory, + // and we would catch that here. + throw_validation_failure!(self.path, + { "a {} pointing to mutable memory in a constant", kind } + ); + } + } + // Nothing to check for these. + None | Some(GlobalAlloc::Function(..) | GlobalAlloc::VTable(..)) => {} } } let path = &self.path; @@ -544,7 +562,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' } ty::Ref(_, ty, mutbl) => { if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { .. })) - && *mutbl == hir::Mutability::Mut + && *mutbl == Mutability::Mut { // A mutable reference inside a const? That does not seem right (except if it is // a ZST). diff --git a/src/test/ui/consts/const-points-to-static.32bit.stderr b/src/test/ui/consts/const-points-to-static.32bit.stderr index 97825dd0eb5..c7a435a1ee3 100644 --- a/src/test/ui/consts/const-points-to-static.32bit.stderr +++ b/src/test/ui/consts/const-points-to-static.32bit.stderr @@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const-points-to-static.rs:6:1 | LL | const TEST: &u8 = &MY_STATIC; - | ^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable + | ^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { diff --git a/src/test/ui/consts/const-points-to-static.64bit.stderr b/src/test/ui/consts/const-points-to-static.64bit.stderr index 0d4a5a8ce4f..4d5b8eac541 100644 --- a/src/test/ui/consts/const-points-to-static.64bit.stderr +++ b/src/test/ui/consts/const-points-to-static.64bit.stderr @@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const-points-to-static.rs:6:1 | LL | const TEST: &u8 = &MY_STATIC; - | ^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable + | ^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.32bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.32bit.stderr index b3ad81e49bc..14173ac9f69 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.32bit.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.32bit.stderr @@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const_refers_to_static2.rs:11:1 | LL | const REF_INTERIOR_MUT: &usize = { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { @@ -13,7 +13,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const_refers_to_static2.rs:18:1 | LL | const READ_IMMUT: &usize = { - | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable + | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.64bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.64bit.stderr index 24bd0709282..e7e51a41856 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.64bit.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.64bit.stderr @@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const_refers_to_static2.rs:11:1 | LL | const REF_INTERIOR_MUT: &usize = { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { @@ -13,7 +13,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const_refers_to_static2.rs:18:1 | LL | const READ_IMMUT: &usize = { - | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable + | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr index 20a96b57f29..3a22b068916 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr @@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const_refers_to_static_cross_crate.rs:12:1 | LL | const SLICE_MUT: &[u8; 1] = { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable + | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { @@ -19,7 +19,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const_refers_to_static_cross_crate.rs:17:1 | LL | const U8_MUT: &u8 = { - | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable + | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr index dfa0f76baa1..39c874d6498 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr @@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const_refers_to_static_cross_crate.rs:12:1 | LL | const SLICE_MUT: &[u8; 1] = { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable + | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { @@ -19,7 +19,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const_refers_to_static_cross_crate.rs:17:1 | LL | const U8_MUT: &u8 = { - | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable + | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { From 74f99738244fc9ba2f6ad93b8c891d44d638b0f8 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Tue, 23 Aug 2022 15:33:06 +0300 Subject: [PATCH 10/21] Fix formating in infer.ftl to make tidy happy --- .../rustc_error_messages/locales/en-US/infer.ftl | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 770eaa62b41..6ae60d92e26 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -1,4 +1,4 @@ -infer_opaque_hidden_type = +infer_opaque_hidden_type = opaque type's hidden type cannot be another opaque type from the same scope .label = one of the two opaque types used here has to be outside its defining scope .opaque_type = opaque type whose hidden type is being assigned @@ -8,7 +8,7 @@ infer_type_annotations_needed = {$source_kind -> [closure] type annotations needed for the closure `{$source_name}` [normal] type annotations needed for `{$source_name}` *[other] type annotations needed -} +} .label = type must be known at this point infer_label_bad = {$bad_kind -> @@ -38,24 +38,24 @@ infer_source_kind_subdiag_let = {$kind -> } infer_source_kind_subdiag_generic_label = - cannot infer {$is_type -> + cannot infer {$is_type -> [true] type *[false] the value - } of the {$is_type -> + } of the {$is_type -> [true] type *[false] const } {$parent_exists -> [true] parameter `{$param_name}` declared on the {$parent_prefix} `{$parent_name}` - *[false] parameter {$param_name} + *[false] parameter {$param_name} } infer_source_kind_subdiag_generic_suggestion = - consider specifying the generic {$arg_count -> + consider specifying the generic {$arg_count -> [one] argument *[other] arguments } -infer_source_kind_fully_qualified = +infer_source_kind_fully_qualified = try using a fully qualified path to specify the expected types infer_source_kind_closure_return = @@ -105,4 +105,3 @@ infer_relate_param_bound = ...so that the type `{$name}` will meet its required 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 - From 3fae3904b130272c782255066f79a13fa9fcdad6 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Wed, 24 Aug 2022 15:46:29 +0300 Subject: [PATCH 11/21] Use `IntoDiagnosticArg` where it makes sense --- .../locales/en-US/infer.ftl | 7 +++- compiler/rustc_infer/src/errors.rs | 13 +++++-- .../src/infer/error_reporting/mod.rs | 16 +++++--- .../infer/error_reporting/need_type_info.rs | 37 ++++++++++++++----- .../src/infer/error_reporting/note.rs | 29 ++++----------- 5 files changed, 61 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 6ae60d92e26..60086cd6e47 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -63,7 +63,12 @@ infer_source_kind_closure_return = # generator_kind may need to be translated infer_need_type_info_in_generator = - type inside {$generator_kind} must be known in this context + type inside {$generator_kind -> + [async_block] `async` block + [async_closure] `async` closure + [async_fn] `async fn` body + *[generator] generator + } must be known in this context infer_subtype = ...so that the {$requirement -> diff --git a/compiler/rustc_infer/src/errors.rs b/compiler/rustc_infer/src/errors.rs index 1db8763e499..938f8aa77a5 100644 --- a/compiler/rustc_infer/src/errors.rs +++ b/compiler/rustc_infer/src/errors.rs @@ -3,6 +3,11 @@ use rustc_hir::FnRetTy; use rustc_macros::SessionDiagnostic; use rustc_span::{BytePos, Span}; +use crate::infer::error_reporting::{ + need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind}, + ObligationCauseAsDiagArg, +}; + #[derive(SessionDiagnostic)] #[diag(infer::opaque_hidden_type)] pub struct OpaqueHiddenTypeDiag { @@ -73,7 +78,7 @@ pub struct AmbigousReturn<'a> { pub struct NeedTypeInfoInGenerator<'a> { #[primary_span] pub span: Span, - pub generator_kind: &'static str, + pub generator_kind: GeneratorKindAsDiagArg, #[subdiagnostic] pub bad_label: InferenceBadError<'a>, } @@ -85,7 +90,7 @@ pub struct InferenceBadError<'a> { #[primary_span] pub span: Span, pub bad_kind: &'static str, - pub prefix_kind: &'static str, + pub prefix_kind: UnderspecifiedArgKind, pub has_parent: bool, pub prefix: &'a str, pub parent_prefix: &'a str, @@ -107,7 +112,7 @@ pub enum SourceKindSubdiag<'a> { type_name: String, kind: &'static str, x_kind: &'static str, - prefix_kind: &'static str, + prefix_kind: UnderspecifiedArgKind, prefix: &'a str, arg_name: String, }, @@ -199,7 +204,7 @@ pub enum RegionOriginNote<'a> { }, WithRequirement { span: Span, - requirement: &'static str, + requirement: ObligationCauseAsDiagArg<'a>, expected_found: Option<(DiagnosticStyledString, DiagnosticStyledString)>, }, } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 13951326665..c7e258578e4 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -58,7 +58,7 @@ use crate::traits::{ }; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed}; +use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed, IntoDiagnosticArg}; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -78,7 +78,7 @@ use std::{cmp, fmt, iter}; mod note; -mod need_type_info; +pub(crate) mod need_type_info; pub use need_type_info::TypeAnnotationNeeded; pub mod nice_region_error; @@ -2811,7 +2811,6 @@ pub enum FailureCode { pub trait ObligationCauseExt<'tcx> { fn as_failure_code(&self, terr: TypeError<'tcx>) -> FailureCode; fn as_requirement_str(&self) -> &'static str; - fn as_requirement_localised(&self) -> &'static str; } impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> { @@ -2880,10 +2879,15 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> { _ => "types are compatible", } } +} - fn as_requirement_localised(&self) -> &'static str { +/// Newtype to allow implementing IntoDiagnosticArg +pub struct ObligationCauseAsDiagArg<'tcx>(pub ObligationCause<'tcx>); + +impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> { + fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { use crate::traits::ObligationCauseCode::*; - match self.code() { + let kind = match self.0.code() { CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => "method_compat", CompareImplItemObligation { kind: ty::AssocKind::Type, .. } => "type_compat", CompareImplItemObligation { kind: ty::AssocKind::Const, .. } => "const_compat", @@ -2896,6 +2900,8 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> { MethodReceiver => "method_correct_type", _ => "other", } + .into(); + rustc_errors::DiagnosticArgValue::Str(kind) } } 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 daf64aeb053..e990fe7ecb5 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 @@ -4,7 +4,7 @@ use crate::errors::{ }; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::InferCtxt; -use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, IntoDiagnosticArg}; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def::{CtorOf, DefKind, Namespace}; @@ -65,6 +65,7 @@ pub struct InferenceDiagnosticsParentData { name: String, } +#[derive(Clone)] pub enum UnderspecifiedArgKind { Type { prefix: Cow<'static, str> }, Const { is_parameter: bool }, @@ -101,7 +102,7 @@ impl InferenceDiagnosticsData { InferenceBadError { span, bad_kind, - prefix_kind: self.kind.prefix_kind(), + prefix_kind: self.kind.clone(), prefix: self.kind.try_get_prefix().unwrap_or_default(), name: self.name.clone(), has_parent, @@ -130,14 +131,18 @@ impl InferenceDiagnosticsParentData { } } -impl UnderspecifiedArgKind { - fn prefix_kind(&self) -> &'static str { - match self { +impl IntoDiagnosticArg for UnderspecifiedArgKind { + fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { + let kind = match self { Self::Type { .. } => "type", Self::Const { is_parameter: true } => "const_with_param", Self::Const { is_parameter: false } => "const", - } + }; + rustc_errors::DiagnosticArgValue::Str(kind.into()) } +} + +impl UnderspecifiedArgKind { fn try_get_prefix(&self) -> Option<&str> { match self { Self::Type { prefix } => Some(prefix.as_ref()), @@ -405,7 +410,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { span: insert_span, name: pattern_name.map(|name| name.to_string()).unwrap_or_else(String::new), x_kind: arg_data.where_x_is_kind(ty), - prefix_kind: arg_data.kind.prefix_kind(), + prefix_kind: arg_data.kind.clone(), prefix: arg_data.kind.try_get_prefix().unwrap_or_default(), arg_name: arg_data.name, kind: if pattern_name.is_some() { "with_pattern" } else { "other" }, @@ -417,7 +422,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { span: insert_span, name: String::new(), x_kind: arg_data.where_x_is_kind(ty), - prefix_kind: arg_data.kind.prefix_kind(), + prefix_kind: arg_data.kind.clone(), prefix: arg_data.kind.try_get_prefix().unwrap_or_default(), arg_name: arg_data.name, kind: "closure", @@ -568,12 +573,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { NeedTypeInfoInGenerator { bad_label: data.make_bad_error(span), span, - generator_kind: kind.descr(), + generator_kind: GeneratorKindAsDiagArg(kind), } .into_diagnostic(&self.tcx.sess.parse_sess) } } +pub struct GeneratorKindAsDiagArg(pub hir::GeneratorKind); + +impl IntoDiagnosticArg for GeneratorKindAsDiagArg { + fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { + let kind = match self.0 { + hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "async_block", + hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "async_closure", + hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "async_fn", + hir::GeneratorKind::Gen => "generator", + }; + rustc_errors::DiagnosticArgValue::Str(kind.into()) + } +} + #[derive(Debug)] struct InferSource<'tcx> { span: Span, diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 36efbd6824a..cffdf56bb6d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -1,40 +1,26 @@ use crate::errors::RegionOriginNote; -use crate::infer::error_reporting::{note_and_explain_region, ObligationCauseExt}; +use crate::infer::error_reporting::note_and_explain_region; use crate::infer::{self, InferCtxt, SubregionOrigin}; use rustc_errors::{ - fluent, struct_span_err, AddSubdiagnostic, Diagnostic, DiagnosticBuilder, DiagnosticMessage, - ErrorGuaranteed, + fluent, struct_span_err, AddSubdiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, }; use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{self, Region}; +use super::ObligationCauseAsDiagArg; + impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub(super) fn note_region_origin(&self, err: &mut Diagnostic, origin: &SubregionOrigin<'tcx>) { - let mut label_or_note = |span, msg: DiagnosticMessage| { - let sub_count = err.children.iter().filter(|d| d.span.is_dummy()).count(); - let expanded_sub_count = err.children.iter().filter(|d| !d.span.is_dummy()).count(); - let span_is_primary = err.span.primary_spans().iter().all(|&sp| sp == span); - if span_is_primary && sub_count == 0 && expanded_sub_count == 0 { - err.span_label(span, msg); - } else if span_is_primary && expanded_sub_count == 0 { - err.note(msg); - } else { - err.span_note(span, msg); - } - }; match *origin { infer::Subtype(ref trace) => RegionOriginNote::WithRequirement { span: trace.cause.span, - requirement: trace.cause.as_requirement_localised(), + requirement: ObligationCauseAsDiagArg(trace.cause.clone()), expected_found: self.values_str(trace.values), } .add_to_diagnostic(err), - infer::Reborrow(span) => { - label_or_note(span, fluent::infer::reborrow); - RegionOriginNote::Plain { span, msg: fluent::infer::reborrow } - .add_to_diagnostic(err) - } + infer::Reborrow(span) => RegionOriginNote::Plain { span, msg: fluent::infer::reborrow } + .add_to_diagnostic(err), infer::ReborrowUpvar(span, ref upvar_id) => { let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); RegionOriginNote::WithName { @@ -46,7 +32,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .add_to_diagnostic(err); } infer::RelateObjectBound(span) => { - label_or_note(span, fluent::infer::relate_object_bound); RegionOriginNote::Plain { span, msg: fluent::infer::relate_object_bound } .add_to_diagnostic(err); } From e1765a9c56d8d9b235bc5b8fda2a0f1d4e92ff49 Mon Sep 17 00:00:00 2001 From: IQuant Date: Wed, 24 Aug 2022 17:09:07 +0300 Subject: [PATCH 12/21] Remove commented lines --- compiler/rustc_infer/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 2c1d339b578..eed2efd3ee0 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -23,8 +23,6 @@ #![feature(never_type)] #![feature(try_blocks)] #![recursion_limit = "512"] // For rustdoc -// #![deny(rustc::untranslatable_diagnostic)] -// #![deny(rustc::diagnostic_outside_of_impl)] #[macro_use] extern crate rustc_macros; From b508b50617bd6a976f77d33962a6f0df52eee12d Mon Sep 17 00:00:00 2001 From: Luis Cardoso <61982523+LuisCardosoOliveira@users.noreply.github.com> Date: Wed, 24 Aug 2022 17:57:10 +0200 Subject: [PATCH 13/21] translations: rename warn_ to warning The macro warn_ was named like that because it the keyword warn is a built-in attribute and at the time this macro was created the word 'warning' was also taken. However it is no longer the case and we can rename warn_ to warning. --- .../src/diagnostics/diagnostic_builder.rs | 31 ++++++++++--------- .../src/diagnostics/subdiagnostic.rs | 4 +-- compiler/rustc_macros/src/lib.rs | 6 ++-- compiler/rustc_passes/src/errors.rs | 16 +++++----- .../session-diagnostic/diagnostic-derive.rs | 10 +++--- .../diagnostic-derive.stderr | 28 ++++++++--------- .../subdiagnostic-derive.rs | 7 ++--- 7 files changed, 52 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index 9df9fa4e9bf..a4ccfcace19 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -148,9 +148,9 @@ impl DiagnosticDeriveBuilder { // `#[help(..)]`/`#[note(..)]` when the user is specifying a alternative slug. Meta::List(MetaList { ref nested, .. }) => nested, // Subdiagnostics without spans can be applied to the type too, and these are just - // paths: `#[help]`, `#[note]` and `#[warn_]` + // paths: `#[help]`, `#[note]` and `#[warning]` Meta::Path(_) if !is_diag => { - let fn_name = if name == "warn_" { + let fn_name = if name == "warning" { Ident::new("warn", attr.span()) } else { Ident::new(name, attr.span()) @@ -163,12 +163,15 @@ impl DiagnosticDeriveBuilder { // Check the kind before doing any further processing so that there aren't misleading // "no kind specified" errors if there are failures later. match name { - "error" | "warning" | "lint" => throw_invalid_attr!(attr, &meta, |diag| { - diag.help("`error`, `warning` and `lint` have been replaced by `diag`") + "error" | "lint" => throw_invalid_attr!(attr, &meta, |diag| { + diag.help("`error` and `lint` have been replaced by `diag`") }), - "diag" | "help" | "note" | "warn_" => (), + "warn_" => throw_invalid_attr!(attr, &meta, |diag| { + diag.help("`warn_` have been replaced by `warning`") + }), + "diag" | "help" | "note" | "warning" => (), _ => throw_invalid_attr!(attr, &meta, |diag| { - diag.help("only `diag`, `help`, `note` and `warn_` are valid attributes") + diag.help("only `diag`, `help`, `note` and `warning` are valid attributes") }), } @@ -180,7 +183,7 @@ impl DiagnosticDeriveBuilder { if !is_diag && nested_iter.next().is_some() { throw_invalid_nested_attr!(attr, &nested_attr, |diag| { diag.help( - "`help`, `note` and `warn_` struct attributes can only have one argument", + "`help`, `note` and `warning` struct attributes can only have one argument", ) }); } @@ -348,12 +351,12 @@ impl DiagnosticDeriveBuilder { report_error_if_not_applied_to_span(attr, &info)?; Ok(self.add_spanned_subdiagnostic(binding, ident, parse_quote! { _subdiag::label })) } - "note" | "help" | "warn_" => { + "note" | "help" | "warning" => { let warn_ident = Ident::new("warn", Span::call_site()); let (ident, path) = match name { "note" => (ident, parse_quote! { _subdiag::note }), "help" => (ident, parse_quote! { _subdiag::help }), - "warn_" => (&warn_ident, parse_quote! { _subdiag::warn }), + "warning" => (&warn_ident, parse_quote! { _subdiag::warn }), _ => unreachable!(), }; if type_matches_path(&info.ty, &["rustc_span", "Span"]) { @@ -390,7 +393,7 @@ impl DiagnosticDeriveBuilder { "suggestion" | "suggestion_short" | "suggestion_hidden" | "suggestion_verbose" => { return self.generate_inner_field_code_suggestion(attr, info); } - "label" | "help" | "note" | "warn_" => (), + "label" | "help" | "note" | "warning" => (), _ => throw_invalid_attr!(attr, &meta, |diag| { diag.help( "only `label`, `help`, `note`, `warn` or `suggestion{,_short,_hidden,_verbose}` are \ @@ -422,14 +425,14 @@ impl DiagnosticDeriveBuilder { Ok(self.add_spanned_subdiagnostic(binding, ident, msg)) } "note" | "help" if type_is_unit(&info.ty) => Ok(self.add_subdiagnostic(ident, msg)), - // `warn_` must be special-cased because the attribute `warn` already has meaning and + // `warning` must be special-cased because the attribute `warn` already has meaning and // so isn't used, despite the diagnostic API being named `warn`. - "warn_" if type_matches_path(&info.ty, &["rustc_span", "Span"]) => Ok(self + "warning" if type_matches_path(&info.ty, &["rustc_span", "Span"]) => Ok(self .add_spanned_subdiagnostic(binding, &Ident::new("warn", Span::call_site()), msg)), - "warn_" if type_is_unit(&info.ty) => { + "warning" if type_is_unit(&info.ty) => { Ok(self.add_subdiagnostic(&Ident::new("warn", Span::call_site()), msg)) } - "note" | "help" | "warn_" => report_type_error(attr, "`Span` or `()`")?, + "note" | "help" | "warning" => report_type_error(attr, "`Span` or `()`")?, _ => unreachable!(), } } diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index edf4dbed985..666dbc23c28 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -37,7 +37,7 @@ enum SubdiagnosticKind { Note, /// `#[help(...)]` Help, - /// `#[warn_(...)]` + /// `#[warning(...)]` Warn, /// `#[suggestion{,_short,_hidden,_verbose}]` Suggestion(SubdiagnosticSuggestionKind), @@ -51,7 +51,7 @@ impl FromStr for SubdiagnosticKind { "label" => Ok(SubdiagnosticKind::Label), "note" => Ok(SubdiagnosticKind::Note), "help" => Ok(SubdiagnosticKind::Help), - "warn_" => Ok(SubdiagnosticKind::Warn), + "warning" => Ok(SubdiagnosticKind::Warn), "suggestion" => Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Normal)), "suggestion_short" => { Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Short)) diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 87d7ab6ed51..8faac8ef36a 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -132,7 +132,7 @@ decl_derive!( diag, help, note, - warn_, + warning, // field attributes skip_arg, primary_span, @@ -149,7 +149,7 @@ decl_derive!( diag, help, note, - warn_, + warning, // field attributes skip_arg, primary_span, @@ -166,7 +166,7 @@ decl_derive!( label, help, note, - warn_, + warning, suggestion, suggestion_short, suggestion_hidden, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 383982013d9..901f56ad96d 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -28,7 +28,7 @@ pub struct IgnoredInlineAttrFnProto; #[derive(LintDiagnostic)] #[diag(passes::inline_ignored_constants)] -#[warn_] +#[warning] #[note] pub struct IgnoredInlineAttrConstants; @@ -347,7 +347,7 @@ pub struct MustNotSuspend { #[derive(LintDiagnostic)] #[diag(passes::cold)] -#[warn_] +#[warning] pub struct Cold { #[label] pub span: Span, @@ -355,7 +355,7 @@ pub struct Cold { #[derive(LintDiagnostic)] #[diag(passes::link)] -#[warn_] +#[warning] pub struct Link { #[label] pub span: Option, @@ -363,7 +363,7 @@ pub struct Link { #[derive(LintDiagnostic)] #[diag(passes::link_name)] -#[warn_] +#[warning] pub struct LinkName<'a> { #[help] pub attr_span: Option, @@ -449,7 +449,7 @@ pub struct RustcDirtyClean { #[derive(LintDiagnostic)] #[diag(passes::link_section)] -#[warn_] +#[warning] pub struct LinkSection { #[label] pub span: Span, @@ -457,7 +457,7 @@ pub struct LinkSection { #[derive(LintDiagnostic)] #[diag(passes::no_mangle_foreign)] -#[warn_] +#[warning] #[note] pub struct NoMangleForeign { #[label] @@ -469,7 +469,7 @@ pub struct NoMangleForeign { #[derive(LintDiagnostic)] #[diag(passes::no_mangle)] -#[warn_] +#[warning] pub struct NoMangle { #[label] pub span: Span, @@ -617,7 +617,7 @@ pub struct UnusedDuplicate { pub this: Span, #[note] pub other: Span, - #[warn_] + #[warning] pub warning: Option<()>, } diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index aaa8caa64f3..b1f557cb94d 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -549,7 +549,7 @@ struct ErrorWithMultiSpan { #[derive(SessionDiagnostic)] #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] -#[warn_] +#[warning] struct ErrorWithWarn { val: String, } @@ -562,11 +562,11 @@ struct ErrorWithWarn { struct ErrorAttribute {} #[derive(SessionDiagnostic)] -#[warning(typeck::ambiguous_lifetime_bound, code = "E0123")] -//~^ ERROR `#[warning(...)]` is not a valid attribute +#[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")] +//~^ ERROR `#[warn_(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified -//~| ERROR cannot find attribute `warning` in this scope -struct WarningAttribute {} +//~| ERROR cannot find attribute `warn_` in this scope +struct WarnAttribute {} #[derive(SessionDiagnostic)] #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 866b1a1de99..621c59f4489 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -21,7 +21,7 @@ error: `#[nonsense(...)]` is not a valid attribute LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: only `diag`, `help`, `note` and `warn_` are valid attributes + = help: only `diag`, `help`, `note` and `warning` are valid attributes error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:53:1 @@ -329,7 +329,7 @@ error: `#[error(...)]` is not a valid attribute LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: `error`, `warning` and `lint` have been replaced by `diag` + = help: `error` and `lint` have been replaced by `diag` error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:558:1 @@ -343,23 +343,23 @@ LL | | struct ErrorAttribute {} | = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` -error: `#[warning(...)]` is not a valid attribute +error: `#[warn_(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:565:1 | -LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: `error`, `warning` and `lint` have been replaced by `diag` + = help: `warn_` have been replaced by `warning` error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:565:1 | -LL | / #[warning(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | / #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")] LL | | LL | | LL | | -LL | | struct WarningAttribute {} - | |__________________________^ +LL | | struct WarnAttribute {} + | |_______________________^ | = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` @@ -369,7 +369,7 @@ error: `#[lint(...)]` is not a valid attribute LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: `error`, `warning` and `lint` have been replaced by `diag` + = help: `error` and `lint` have been replaced by `diag` error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:572:1 @@ -389,7 +389,7 @@ error: `#[lint(...)]` is not a valid attribute LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: `error`, `warning` and `lint` have been replaced by `diag` + = help: `error` and `lint` have been replaced by `diag` error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:579:1 @@ -421,11 +421,11 @@ error: cannot find attribute `error` in this scope LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] | ^^^^^ -error: cannot find attribute `warning` in this scope +error: cannot find attribute `warn_` in this scope --> $DIR/diagnostic-derive.rs:565:3 | -LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^ +LL | #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^ help: a built-in attribute with a similar name exists: `warn` error: cannot find attribute `lint` in this scope --> $DIR/diagnostic-derive.rs:572:3 diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index 16da25c402b..ddfc0d3365d 100644 --- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -510,12 +510,11 @@ enum AX { } #[derive(SessionSubdiagnostic)] -#[warn_(parser::add_paren)] -struct AY { -} +#[warning(parser::add_paren)] +struct AY {} #[derive(SessionSubdiagnostic)] -#[warn_(parser::add_paren)] +#[warning(parser::add_paren)] struct AZ { #[primary_span] span: Span, From 4e976262a1598fa48cd08fa0e429f05299d1ae3e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 12 Aug 2022 02:00:37 +0000 Subject: [PATCH 14/21] Call them constants instead of types --- .../src/infer/error_reporting/mod.rs | 5 +++ .../generic-expr-default-concrete.stderr | 4 +-- ...neric-expr-default-mismatched-types.stderr | 4 +-- .../abstract-const-as-cast-3.stderr | 32 +++++++++---------- .../generic_const_exprs/different-fn.stderr | 4 +-- .../issue-62504.full.stderr | 4 +-- ...ue-72819-generic-in-const-eval.full.stderr | 8 ++--- .../generic_const_exprs/issue-83765.stderr | 8 ++--- .../generic_const_exprs/issue-85848.stderr | 4 +-- .../const-generics/issues/issue-73260.stderr | 8 ++--- .../const-generics/issues/issue-79674.stderr | 4 +-- .../types-mismatch-const-args.full.stderr | 4 +-- 12 files changed, 47 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 59ea1f3f9de..16cffb45f0f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1588,9 +1588,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { Mismatch::Variable(infer::ExpectedFound { expected, found }), ) } + ValuePairs::Terms(infer::ExpectedFound { + expected: ty::Term::Const(_), + found: ty::Term::Const(_), + }) => (false, Mismatch::Fixed("constant")), ValuePairs::TraitRefs(_) | ValuePairs::PolyTraitRefs(_) => { (false, Mismatch::Fixed("trait")) } + ValuePairs::Regions(_) => (false, Mismatch::Fixed("lifetime")), _ => (false, Mismatch::Fixed("type")), }; let vals = match self.values_str(values) { diff --git a/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr b/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr index e8826ce4335..61b3551182c 100644 --- a/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr +++ b/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types LL | Foo::<10, 12> | ^^^^^^^^^^^^^ expected `11`, found `12` | - = note: expected type `11` - found type `12` + = note: expected constant `11` + found constant `12` error: aborting due to previous error diff --git a/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr b/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr index d5a3071b77d..e83f89a6033 100644 --- a/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr +++ b/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types LL | Foo:: | ^^^^^^^^^^^^^^^^^^^ expected `{ N + 1 }`, found `{ N + 2 }` | - = note: expected type `{ N + 1 }` - found type `{ N + 2 }` + = note: expected constant `{ N + 1 }` + found constant `{ N + 2 }` error: aborting due to previous error diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr index 615dc875f67..9e1297d5ee4 100644 --- a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr @@ -22,8 +22,8 @@ error[E0308]: mismatched types LL | assert_impl::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }` | - = note: expected type `{ N as u128 }` - found type `{ O as u128 }` + = note: expected constant `{ N as u128 }` + found constant `{ O as u128 }` error: unconstrained generic constant --> $DIR/abstract-const-as-cast-3.rs:20:19 @@ -49,8 +49,8 @@ error[E0308]: mismatched types LL | assert_impl::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }` | - = note: expected type `{ N as _ }` - found type `{ O as u128 }` + = note: expected constant `{ N as _ }` + found constant `{ O as u128 }` error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:23:5 @@ -58,8 +58,8 @@ error[E0308]: mismatched types LL | assert_impl::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13` | - = note: expected type `12` - found type `13` + = note: expected constant `12` + found constant `13` error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:25:5 @@ -67,8 +67,8 @@ error[E0308]: mismatched types LL | assert_impl::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14` | - = note: expected type `13` - found type `14` + = note: expected constant `13` + found constant `14` error: unconstrained generic constant --> $DIR/abstract-const-as-cast-3.rs:35:19 @@ -94,8 +94,8 @@ error[E0308]: mismatched types LL | assert_impl::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }` | - = note: expected type `{ N as u128 }` - found type `{ O as u128 }` + = note: expected constant `{ N as u128 }` + found constant `{ O as u128 }` error: unconstrained generic constant --> $DIR/abstract-const-as-cast-3.rs:38:19 @@ -121,8 +121,8 @@ error[E0308]: mismatched types LL | assert_impl::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }` | - = note: expected type `{ N as _ }` - found type `{ O as u128 }` + = note: expected constant `{ N as _ }` + found constant `{ O as u128 }` error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:41:5 @@ -130,8 +130,8 @@ error[E0308]: mismatched types LL | assert_impl::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13` | - = note: expected type `12` - found type `13` + = note: expected constant `12` + found constant `13` error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:43:5 @@ -139,8 +139,8 @@ error[E0308]: mismatched types LL | assert_impl::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14` | - = note: expected type `13` - found type `14` + = note: expected constant `13` + found constant `14` error: aborting due to 12 previous errors diff --git a/src/test/ui/const-generics/generic_const_exprs/different-fn.stderr b/src/test/ui/const-generics/generic_const_exprs/different-fn.stderr index 2aeb9b961ff..83a2f3740b1 100644 --- a/src/test/ui/const-generics/generic_const_exprs/different-fn.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/different-fn.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types LL | [0; size_of::>()] | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `size_of::()`, found `size_of::>()` | - = note: expected type `size_of::()` - found type `size_of::>()` + = note: expected constant `size_of::()` + found constant `size_of::>()` error: unconstrained generic constant --> $DIR/different-fn.rs:10:9 diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr index f2ae361dc81..0742db398c9 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types LL | ArrayHolder([0; Self::SIZE]) | ^^^^^^^^^^^^^^^ expected `X`, found `Self::SIZE` | - = note: expected type `X` - found type `Self::SIZE` + = note: expected constant `X` + found constant `Self::SIZE` error: unconstrained generic constant --> $DIR/issue-62504.rs:18:25 diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr index d536f6fd1d5..38dfa65e409 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types LL | let x: Arr<{usize::MAX}> = Arr {}; | ^^^^^^^^^^^^^^^^^ expected `false`, found `true` | - = note: expected type `false` - found type `true` + = note: expected constant `false` + found constant `true` error[E0308]: mismatched types --> $DIR/issue-72819-generic-in-const-eval.rs:20:32 @@ -13,8 +13,8 @@ error[E0308]: mismatched types LL | let x: Arr<{usize::MAX}> = Arr {}; | ^^^ expected `false`, found `true` | - = note: expected type `false` - found type `true` + = note: expected constant `false` + found constant `true` error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr index 0332e82fe07..b693023f125 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr @@ -4,8 +4,8 @@ error[E0308]: method not compatible with trait LL | fn size(&self) -> [usize; DIM] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM` | - = note: expected type `Self::DIM` - found type `DIM` + = note: expected constant `Self::DIM` + found constant `DIM` error: unconstrained generic constant --> $DIR/issue-83765.rs:32:24 @@ -26,8 +26,8 @@ error[E0308]: mismatched types LL | self.reference.size() | ^^^^^^^^^^^^^^^^^^^^^ expected `DIM`, found `Self::DIM` | - = note: expected type `DIM` - found type `Self::DIM` + = note: expected constant `DIM` + found constant `Self::DIM` error: aborting due to 3 previous errors diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr index 808b305c680..09bcb0860b7 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr @@ -54,8 +54,8 @@ error[E0308]: mismatched types LL | writes_to_specific_path(&cap); | ^^^^^^^^^^^^^^^^^^^^^^^ expected `true`, found `{ contains::() }` | - = note: expected type `true` - found type `{ contains::() }` + = note: expected constant `true` + found constant `{ contains::() }` error: aborting due to 3 previous errors diff --git a/src/test/ui/const-generics/issues/issue-73260.stderr b/src/test/ui/const-generics/issues/issue-73260.stderr index f1fc50e6e59..3d1f90271f9 100644 --- a/src/test/ui/const-generics/issues/issue-73260.stderr +++ b/src/test/ui/const-generics/issues/issue-73260.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types LL | let x: Arr<{usize::MAX}> = Arr {}; | ^^^^^^^^^^^^^^^^^ expected `false`, found `true` | - = note: expected type `false` - found type `true` + = note: expected constant `false` + found constant `true` error[E0308]: mismatched types --> $DIR/issue-73260.rs:16:32 @@ -13,8 +13,8 @@ error[E0308]: mismatched types LL | let x: Arr<{usize::MAX}> = Arr {}; | ^^^ expected `false`, found `true` | - = note: expected type `false` - found type `true` + = note: expected constant `false` + found constant `true` error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/issues/issue-79674.stderr b/src/test/ui/const-generics/issues/issue-79674.stderr index 8c029289cbb..344b2c56310 100644 --- a/src/test/ui/const-generics/issues/issue-79674.stderr +++ b/src/test/ui/const-generics/issues/issue-79674.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types LL | requires_distinct("str", 12); | ^^^^^^^^^^^^^^^^^ expected `true`, found `false` | - = note: expected type `true` - found type `false` + = note: expected constant `true` + found constant `false` error: aborting due to previous error diff --git a/src/test/ui/const-generics/types-mismatch-const-args.full.stderr b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr index 486506239dd..b6a22df7436 100644 --- a/src/test/ui/const-generics/types-mismatch-const-args.full.stderr +++ b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types LL | let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {2u32 + 2u32}, {3u32}> { data: PhantomData }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2`, found `4` | - = note: expected type `2` - found type `4` + = note: expected constant `2` + found constant `4` error[E0308]: mismatched types --> $DIR/types-mismatch-const-args.rs:16:41 From 4ff587263e0a7f2081e2ad5fd3e88460a94adbb5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 12 Aug 2022 03:13:45 +0000 Subject: [PATCH 15/21] Note binding obligation causes for const equate errors --- compiler/rustc_middle/src/traits/mod.rs | 7 ++++ .../src/traits/error_reporting/mod.rs | 19 +++++++-- .../abstract-const-as-cast-3.stderr | 40 +++++++++++++++++++ ...ue-72819-generic-in-const-eval.full.stderr | 14 +++++++ .../const-generics/issues/issue-73260.stderr | 16 ++++++++ .../const-generics/issues/issue-79674.stderr | 8 ++++ 6 files changed, 101 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 9b82320e556..ab7e5ba3a10 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -469,6 +469,13 @@ impl<'tcx> ObligationCauseCode<'tcx> { _ => None, } } + + pub fn peel_match_impls(&self) -> &Self { + match self { + MatchImpl(cause, _) => cause.code(), + _ => self, + } + } } // `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger. 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 70fac83325a..1f031d33e06 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1506,13 +1506,26 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { .emit(); } FulfillmentErrorCode::CodeConstEquateError(ref expected_found, ref err) => { - self.report_mismatched_consts( + let mut diag = self.report_mismatched_consts( &error.obligation.cause, expected_found.expected, expected_found.found, err.clone(), - ) - .emit(); + ); + let code = error.obligation.cause.code().peel_derives().peel_match_impls(); + if let ObligationCauseCode::BindingObligation(..) + | ObligationCauseCode::ItemObligation(..) = code + { + self.note_obligation_cause_code( + &mut diag, + &error.obligation.predicate, + error.obligation.param_env, + code, + &mut vec![], + &mut Default::default(), + ); + } + diag.emit(); } } } diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr index 9e1297d5ee4..ada1050d35f 100644 --- a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr @@ -24,6 +24,11 @@ LL | assert_impl::>(); | = note: expected constant `{ N as u128 }` found constant `{ O as u128 }` +note: required by a bound in `use_trait_impl::assert_impl` + --> $DIR/abstract-const-as-cast-3.rs:14:23 + | +LL | fn assert_impl() {} + | ^^^^^ required by this bound in `use_trait_impl::assert_impl` error: unconstrained generic constant --> $DIR/abstract-const-as-cast-3.rs:20:19 @@ -51,6 +56,11 @@ LL | assert_impl::>(); | = note: expected constant `{ N as _ }` found constant `{ O as u128 }` +note: required by a bound in `use_trait_impl::assert_impl` + --> $DIR/abstract-const-as-cast-3.rs:14:23 + | +LL | fn assert_impl() {} + | ^^^^^ required by this bound in `use_trait_impl::assert_impl` error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:23:5 @@ -60,6 +70,11 @@ LL | assert_impl::>(); | = note: expected constant `12` found constant `13` +note: required by a bound in `use_trait_impl::assert_impl` + --> $DIR/abstract-const-as-cast-3.rs:14:23 + | +LL | fn assert_impl() {} + | ^^^^^ required by this bound in `use_trait_impl::assert_impl` error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:25:5 @@ -69,6 +84,11 @@ LL | assert_impl::>(); | = note: expected constant `13` found constant `14` +note: required by a bound in `use_trait_impl::assert_impl` + --> $DIR/abstract-const-as-cast-3.rs:14:23 + | +LL | fn assert_impl() {} + | ^^^^^ required by this bound in `use_trait_impl::assert_impl` error: unconstrained generic constant --> $DIR/abstract-const-as-cast-3.rs:35:19 @@ -96,6 +116,11 @@ LL | assert_impl::>(); | = note: expected constant `{ N as u128 }` found constant `{ O as u128 }` +note: required by a bound in `use_trait_impl_2::assert_impl` + --> $DIR/abstract-const-as-cast-3.rs:32:23 + | +LL | fn assert_impl() {} + | ^^^^^ required by this bound in `use_trait_impl_2::assert_impl` error: unconstrained generic constant --> $DIR/abstract-const-as-cast-3.rs:38:19 @@ -123,6 +148,11 @@ LL | assert_impl::>(); | = note: expected constant `{ N as _ }` found constant `{ O as u128 }` +note: required by a bound in `use_trait_impl_2::assert_impl` + --> $DIR/abstract-const-as-cast-3.rs:32:23 + | +LL | fn assert_impl() {} + | ^^^^^ required by this bound in `use_trait_impl_2::assert_impl` error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:41:5 @@ -132,6 +162,11 @@ LL | assert_impl::>(); | = note: expected constant `12` found constant `13` +note: required by a bound in `use_trait_impl_2::assert_impl` + --> $DIR/abstract-const-as-cast-3.rs:32:23 + | +LL | fn assert_impl() {} + | ^^^^^ required by this bound in `use_trait_impl_2::assert_impl` error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:43:5 @@ -141,6 +176,11 @@ LL | assert_impl::>(); | = note: expected constant `13` found constant `14` +note: required by a bound in `use_trait_impl_2::assert_impl` + --> $DIR/abstract-const-as-cast-3.rs:32:23 + | +LL | fn assert_impl() {} + | ^^^^^ required by this bound in `use_trait_impl_2::assert_impl` error: aborting due to 12 previous errors diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr index 38dfa65e409..f2fddfbfbb5 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr @@ -6,6 +6,13 @@ LL | let x: Arr<{usize::MAX}> = Arr {}; | = note: expected constant `false` found constant `true` +note: required by a bound in `Arr` + --> $DIR/issue-72819-generic-in-const-eval.rs:8:39 + | +LL | struct Arr + | --- required by a bound in this +LL | where Assert::<{N < usize::MAX / 2}>: IsTrue, + | ^^^^^^ required by this bound in `Arr` error[E0308]: mismatched types --> $DIR/issue-72819-generic-in-const-eval.rs:20:32 @@ -15,6 +22,13 @@ LL | let x: Arr<{usize::MAX}> = Arr {}; | = note: expected constant `false` found constant `true` +note: required by a bound in `Arr` + --> $DIR/issue-72819-generic-in-const-eval.rs:8:39 + | +LL | struct Arr + | --- required by a bound in this +LL | where Assert::<{N < usize::MAX / 2}>: IsTrue, + | ^^^^^^ required by this bound in `Arr` error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/issues/issue-73260.stderr b/src/test/ui/const-generics/issues/issue-73260.stderr index 3d1f90271f9..7670032e5b7 100644 --- a/src/test/ui/const-generics/issues/issue-73260.stderr +++ b/src/test/ui/const-generics/issues/issue-73260.stderr @@ -6,6 +6,14 @@ LL | let x: Arr<{usize::MAX}> = Arr {}; | = note: expected constant `false` found constant `true` +note: required by a bound in `Arr` + --> $DIR/issue-73260.rs:6:37 + | +LL | struct Arr + | --- required by a bound in this +LL | where +LL | Assert::<{N < usize::MAX / 2}>: IsTrue, + | ^^^^^^ required by this bound in `Arr` error[E0308]: mismatched types --> $DIR/issue-73260.rs:16:32 @@ -15,6 +23,14 @@ LL | let x: Arr<{usize::MAX}> = Arr {}; | = note: expected constant `false` found constant `true` +note: required by a bound in `Arr` + --> $DIR/issue-73260.rs:6:37 + | +LL | struct Arr + | --- required by a bound in this +LL | where +LL | Assert::<{N < usize::MAX / 2}>: IsTrue, + | ^^^^^^ required by this bound in `Arr` error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/issues/issue-79674.stderr b/src/test/ui/const-generics/issues/issue-79674.stderr index 344b2c56310..02b48b55f8b 100644 --- a/src/test/ui/const-generics/issues/issue-79674.stderr +++ b/src/test/ui/const-generics/issues/issue-79674.stderr @@ -6,6 +6,14 @@ LL | requires_distinct("str", 12); | = note: expected constant `true` found constant `false` +note: required by a bound in `requires_distinct` + --> $DIR/issue-79674.rs:23:37 + | +LL | fn requires_distinct(_a: A, _b: B) where + | ----------------- required by a bound in this +LL | A: MiniTypeId, B: MiniTypeId, +LL | Lift<{is_same_type::()}>: IsFalse {} + | ^^^^^^^ required by this bound in `requires_distinct` error: aborting due to previous error From d464d3a700138b48e13d62846a35165d661e2ea4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 12 Aug 2022 03:41:57 +0000 Subject: [PATCH 16/21] Add test for #100414 --- .../generic_const_exprs/obligation-cause.rs | 24 +++++++++++++++++++ .../obligation-cause.stderr | 20 ++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/test/ui/const-generics/generic_const_exprs/obligation-cause.rs create mode 100644 src/test/ui/const-generics/generic_const_exprs/obligation-cause.stderr diff --git a/src/test/ui/const-generics/generic_const_exprs/obligation-cause.rs b/src/test/ui/const-generics/generic_const_exprs/obligation-cause.rs new file mode 100644 index 00000000000..e7c8e4f667d --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/obligation-cause.rs @@ -0,0 +1,24 @@ +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +trait True {} + +struct Is; + +impl True for Is {} + +fn g() +//~^ NOTE required by a bound in this +where + Is<{ std::mem::size_of::() == 0 }>: True, + //~^ NOTE required by a bound in `g` + //~| NOTE required by this bound in `g` +{ +} + +fn main() { + g::(); + //~^ ERROR mismatched types + //~| NOTE expected `false`, found `true` + //~| NOTE expected constant `false` +} diff --git a/src/test/ui/const-generics/generic_const_exprs/obligation-cause.stderr b/src/test/ui/const-generics/generic_const_exprs/obligation-cause.stderr new file mode 100644 index 00000000000..a253ec676f7 --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/obligation-cause.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/obligation-cause.rs:20:5 + | +LL | g::(); + | ^^^^^^^^^^ expected `false`, found `true` + | + = note: expected constant `false` + found constant `true` +note: required by a bound in `g` + --> $DIR/obligation-cause.rs:13:44 + | +LL | fn g() + | - required by a bound in this +... +LL | Is<{ std::mem::size_of::() == 0 }>: True, + | ^^^^ required by this bound in `g` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From 8189a4536be3730ecc161c77fc655b08be179b50 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 23 Aug 2022 05:38:18 +0000 Subject: [PATCH 17/21] Use ExprItemObligation and ExprBindingObligation too --- .../rustc_trait_selection/src/traits/error_reporting/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 1f031d33e06..e4af7022239 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1514,7 +1514,9 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { ); let code = error.obligation.cause.code().peel_derives().peel_match_impls(); if let ObligationCauseCode::BindingObligation(..) - | ObligationCauseCode::ItemObligation(..) = code + | ObligationCauseCode::ItemObligation(..) + | ObligationCauseCode::ExprBindingObligation(..) + | ObligationCauseCode::ExprItemObligation(..) = code { self.note_obligation_cause_code( &mut diag, From 8bb4b5f44c8b7c811e2075022e5205f927287e0a Mon Sep 17 00:00:00 2001 From: marmeladema Date: Sat, 12 Mar 2022 19:32:41 +0100 Subject: [PATCH 18/21] Support parsing IP addresses from a byte string --- library/std/src/net/parser.rs | 138 ++++++++++++++++++++++++++++++---- 1 file changed, 125 insertions(+), 13 deletions(-) diff --git a/library/std/src/net/parser.rs b/library/std/src/net/parser.rs index 069b6609985..a38031c48c8 100644 --- a/library/std/src/net/parser.rs +++ b/library/std/src/net/parser.rs @@ -39,8 +39,8 @@ struct Parser<'a> { } impl<'a> Parser<'a> { - fn new(input: &'a str) -> Parser<'a> { - Parser { state: input.as_bytes() } + fn new(input: &'a [u8]) -> Parser<'a> { + Parser { state: input } } /// Run a parser, and restore the pre-parse state if it fails. @@ -273,11 +273,54 @@ impl<'a> Parser<'a> { } } +impl IpAddr { + /// Parse an IP address from a slice of bytes. + /// + /// ``` + /// #![feature(addr_parse_ascii)] + /// + /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; + /// + /// let localhost_v4 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)); + /// let localhost_v6 = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); + /// + /// assert_eq!(IpAddr::parse_ascii(b"127.0.0.1"), Ok(localhost_v4)); + /// assert_eq!(IpAddr::parse_ascii(b"::1"), Ok(localhost_v6)); + /// ``` + #[unstable(feature = "addr_parse_ascii", issue = "101035")] + pub fn parse_ascii(b: &[u8]) -> Result { + Parser::new(b).parse_with(|p| p.read_ip_addr(), AddrKind::Ip) + } +} + #[stable(feature = "ip_addr", since = "1.7.0")] impl FromStr for IpAddr { type Err = AddrParseError; fn from_str(s: &str) -> Result { - Parser::new(s).parse_with(|p| p.read_ip_addr(), AddrKind::Ip) + Self::parse_ascii(s.as_bytes()) + } +} + +impl Ipv4Addr { + /// Parse an IPv4 address from a slice of bytes. + /// + /// ``` + /// #![feature(addr_parse_ascii)] + /// + /// use std::net::Ipv4Addr; + /// + /// let localhost = Ipv4Addr::new(127, 0, 0, 1); + /// + /// assert_eq!(Ipv4Addr::parse_ascii(b"127.0.0.1"), Ok(localhost)); + /// ``` + #[unstable(feature = "addr_parse_ascii", issue = "101035")] + pub fn parse_ascii(b: &[u8]) -> Result { + // don't try to parse if too long + if b.len() > 15 { + Err(AddrParseError(AddrKind::Ipv4)) + } else { + Parser::new(b).parse_with(|p| p.read_ipv4_addr(), AddrKind::Ipv4) + } } } @@ -285,12 +328,25 @@ impl FromStr for IpAddr { impl FromStr for Ipv4Addr { type Err = AddrParseError; fn from_str(s: &str) -> Result { - // don't try to parse if too long - if s.len() > 15 { - Err(AddrParseError(AddrKind::Ipv4)) - } else { - Parser::new(s).parse_with(|p| p.read_ipv4_addr(), AddrKind::Ipv4) - } + Self::parse_ascii(s.as_bytes()) + } +} + +impl Ipv6Addr { + /// Parse an IPv6 address from a slice of bytes. + /// + /// ``` + /// #![feature(addr_parse_ascii)] + /// + /// use std::net::Ipv6Addr; + /// + /// let localhost = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1); + /// + /// assert_eq!(Ipv6Addr::parse_ascii(b"::1"), Ok(localhost)); + /// ``` + #[unstable(feature = "addr_parse_ascii", issue = "101035")] + pub fn parse_ascii(b: &[u8]) -> Result { + Parser::new(b).parse_with(|p| p.read_ipv6_addr(), AddrKind::Ipv6) } } @@ -298,7 +354,25 @@ impl FromStr for Ipv4Addr { impl FromStr for Ipv6Addr { type Err = AddrParseError; fn from_str(s: &str) -> Result { - Parser::new(s).parse_with(|p| p.read_ipv6_addr(), AddrKind::Ipv6) + Self::parse_ascii(s.as_bytes()) + } +} + +impl SocketAddrV4 { + /// Parse an IPv4 socket address from a slice of bytes. + /// + /// ``` + /// #![feature(addr_parse_ascii)] + /// + /// use std::net::{Ipv4Addr, SocketAddrV4}; + /// + /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080); + /// + /// assert_eq!(SocketAddrV4::parse_ascii(b"127.0.0.1:8080"), Ok(socket)); + /// ``` + #[unstable(feature = "addr_parse_ascii", issue = "101035")] + pub fn parse_ascii(b: &[u8]) -> Result { + Parser::new(b).parse_with(|p| p.read_socket_addr_v4(), AddrKind::SocketV4) } } @@ -306,7 +380,25 @@ impl FromStr for Ipv6Addr { impl FromStr for SocketAddrV4 { type Err = AddrParseError; fn from_str(s: &str) -> Result { - Parser::new(s).parse_with(|p| p.read_socket_addr_v4(), AddrKind::SocketV4) + Self::parse_ascii(s.as_bytes()) + } +} + +impl SocketAddrV6 { + /// Parse an IPv6 socket address from a slice of bytes. + /// + /// ``` + /// #![feature(addr_parse_ascii)] + /// + /// use std::net::{Ipv6Addr, SocketAddrV6}; + /// + /// let socket = SocketAddrV6::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0); + /// + /// assert_eq!(SocketAddrV6::parse_ascii(b"[2001:db8::1]:8080"), Ok(socket)); + /// ``` + #[unstable(feature = "addr_parse_ascii", issue = "101035")] + pub fn parse_ascii(b: &[u8]) -> Result { + Parser::new(b).parse_with(|p| p.read_socket_addr_v6(), AddrKind::SocketV6) } } @@ -314,7 +406,27 @@ impl FromStr for SocketAddrV4 { impl FromStr for SocketAddrV6 { type Err = AddrParseError; fn from_str(s: &str) -> Result { - Parser::new(s).parse_with(|p| p.read_socket_addr_v6(), AddrKind::SocketV6) + Self::parse_ascii(s.as_bytes()) + } +} + +impl SocketAddr { + /// Parse a socket address from a slice of bytes. + /// + /// ``` + /// #![feature(addr_parse_ascii)] + /// + /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; + /// + /// let socket_v4 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); + /// let socket_v6 = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 8080); + /// + /// assert_eq!(SocketAddr::parse_ascii(b"127.0.0.1:8080"), Ok(socket_v4)); + /// assert_eq!(SocketAddr::parse_ascii(b"[::1]:8080"), Ok(socket_v6)); + /// ``` + #[unstable(feature = "addr_parse_ascii", issue = "101035")] + pub fn parse_ascii(b: &[u8]) -> Result { + Parser::new(b).parse_with(|p| p.read_socket_addr(), AddrKind::Socket) } } @@ -322,7 +434,7 @@ impl FromStr for SocketAddrV6 { impl FromStr for SocketAddr { type Err = AddrParseError; fn from_str(s: &str) -> Result { - Parser::new(s).parse_with(|p| p.read_socket_addr(), AddrKind::Socket) + Self::parse_ascii(s.as_bytes()) } } From b48870b451dd9d3f3f827aa54d9becdfdd811ba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 5 Jul 2022 00:00:00 +0000 Subject: [PATCH 19/21] Replace `Body::basic_blocks()` with field access --- .../rustc_borrowck/src/constraint_generation.rs | 2 +- compiler/rustc_borrowck/src/dataflow.rs | 2 +- .../src/diagnostics/explain_borrow.rs | 6 +++--- .../src/diagnostics/move_errors.rs | 2 +- compiler/rustc_borrowck/src/location.rs | 2 +- .../rustc_borrowck/src/region_infer/values.rs | 4 ++-- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- compiler/rustc_codegen_cranelift/src/analyze.rs | 2 +- compiler/rustc_codegen_cranelift/src/base.rs | 4 ++-- compiler/rustc_codegen_cranelift/src/constant.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/analyze.rs | 6 +++--- compiler/rustc_codegen_ssa/src/mir/mod.rs | 8 ++++---- .../src/interpret/eval_context.rs | 2 +- .../src/interpret/intrinsics/caller_location.rs | 2 +- compiler/rustc_const_eval/src/interpret/step.rs | 2 +- .../src/transform/check_consts/check.rs | 2 +- .../src/transform/promote_consts.rs | 6 +++--- .../rustc_const_eval/src/transform/validate.rs | 8 ++++---- compiler/rustc_middle/src/mir/generic_graph.rs | 4 ++-- compiler/rustc_middle/src/mir/mod.rs | 7 +------ compiler/rustc_middle/src/mir/patch.rs | 10 +++++----- compiler/rustc_middle/src/mir/pretty.rs | 4 ++-- compiler/rustc_middle/src/mir/spanview.rs | 2 +- compiler/rustc_middle/src/mir/traversal.rs | 4 ++-- compiler/rustc_middle/src/mir/visit.rs | 2 +- compiler/rustc_mir_build/src/build/mod.rs | 2 +- .../rustc_mir_dataflow/src/framework/engine.rs | 9 ++++----- .../rustc_mir_dataflow/src/framework/graphviz.rs | 4 ++-- .../rustc_mir_dataflow/src/framework/tests.rs | 10 ++++------ .../rustc_mir_dataflow/src/move_paths/builder.rs | 2 +- .../rustc_mir_dataflow/src/move_paths/mod.rs | 2 +- compiler/rustc_mir_dataflow/src/rustc_peek.rs | 2 +- compiler/rustc_mir_dataflow/src/storage.rs | 2 +- .../src/abort_unwinding_calls.rs | 2 +- .../rustc_mir_transform/src/add_call_guards.rs | 2 +- .../src/add_moves_for_packed_drops.rs | 2 +- compiler/rustc_mir_transform/src/const_goto.rs | 4 ++-- compiler/rustc_mir_transform/src/const_prop.rs | 2 +- .../rustc_mir_transform/src/const_prop_lint.rs | 4 ++-- .../rustc_mir_transform/src/coverage/graph.rs | 4 ++-- compiler/rustc_mir_transform/src/coverage/mod.rs | 2 +- .../rustc_mir_transform/src/coverage/query.rs | 4 ++-- .../rustc_mir_transform/src/coverage/tests.rs | 6 +++--- .../src/deduplicate_blocks.rs | 5 ++--- compiler/rustc_mir_transform/src/dest_prop.rs | 6 +++--- .../src/early_otherwise_branch.rs | 6 +++--- .../rustc_mir_transform/src/elaborate_drops.rs | 12 ++++++------ .../rustc_mir_transform/src/ffi_unwind_calls.rs | 2 +- compiler/rustc_mir_transform/src/generator.rs | 14 +++++++------- compiler/rustc_mir_transform/src/inline.rs | 16 ++++++++-------- compiler/rustc_mir_transform/src/inline/cycle.rs | 2 +- .../src/multiple_return_terminators.rs | 2 +- .../src/normalize_array_len.rs | 4 ++-- compiler/rustc_mir_transform/src/nrvo.rs | 4 ++-- .../src/remove_noop_landing_pads.rs | 2 +- .../src/remove_uninit_drops.rs | 2 +- .../src/separate_const_switch.rs | 4 ++-- compiler/rustc_mir_transform/src/simplify.rs | 4 ++-- .../src/simplify_comparison_integral.rs | 2 +- compiler/rustc_mir_transform/src/simplify_try.rs | 4 ++-- .../src/uninhabited_enum_branching.rs | 6 +++--- .../rustc_monomorphize/src/partitioning/mod.rs | 2 +- compiler/rustc_ty_utils/src/ty.rs | 2 +- .../clippy/clippy_lints/src/redundant_clone.rs | 6 +++--- .../clippy_utils/src/qualify_min_const_fn.rs | 2 +- 65 files changed, 131 insertions(+), 140 deletions(-) diff --git a/compiler/rustc_borrowck/src/constraint_generation.rs b/compiler/rustc_borrowck/src/constraint_generation.rs index 5e9cec5c350..144fd15fc24 100644 --- a/compiler/rustc_borrowck/src/constraint_generation.rs +++ b/compiler/rustc_borrowck/src/constraint_generation.rs @@ -31,7 +31,7 @@ pub(super) fn generate_constraints<'cx, 'tcx>( body, }; - for (bb, data) in body.basic_blocks().iter_enumerated() { + for (bb, data) in body.basic_blocks.iter_enumerated() { cg.visit_basic_block_data(bb, data); } } diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 97d5a8d158e..816288eb50b 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -143,7 +143,7 @@ struct OutOfScopePrecomputer<'a, 'tcx> { impl<'a, 'tcx> OutOfScopePrecomputer<'a, 'tcx> { fn new(body: &'a Body<'tcx>, regioncx: &'a RegionInferenceContext<'tcx>) -> Self { OutOfScopePrecomputer { - visited: BitSet::new_empty(body.basic_blocks().len()), + visited: BitSet::new_empty(body.basic_blocks.len()), visit_stack: vec![], body, regioncx, diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 68f9a7c5007..a6b8c6057e0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -459,7 +459,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { return outmost_back_edge; } - let block = &self.body.basic_blocks()[location.block]; + let block = &self.body.basic_blocks[location.block]; if location.statement_index < block.statements.len() { let successor = location.successor_within_block(); @@ -518,7 +518,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } if loop_head.dominates(from, &self.dominators) { - let block = &self.body.basic_blocks()[from.block]; + let block = &self.body.basic_blocks[from.block]; if from.statement_index < block.statements.len() { let successor = from.successor_within_block(); @@ -568,7 +568,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { UseSpans::PatUse(span) | UseSpans::OtherUse(span) | UseSpans::FnSelfUse { var_span: span, .. } => { - let block = &self.body.basic_blocks()[location.block]; + let block = &self.body.basic_blocks[location.block]; let kind = if let Some(&Statement { kind: StatementKind::FakeRead(box (FakeReadCause::ForLet(_), _)), diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index cb3cd479ae2..16c2f9ccc6a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -88,7 +88,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if let Some(StatementKind::Assign(box ( place, Rvalue::Use(Operand::Move(move_from)), - ))) = self.body.basic_blocks()[location.block] + ))) = self.body.basic_blocks[location.block] .statements .get(location.statement_index) .map(|stmt| &stmt.kind) diff --git a/compiler/rustc_borrowck/src/location.rs b/compiler/rustc_borrowck/src/location.rs index 70a31169498..5ca3f2f4d03 100644 --- a/compiler/rustc_borrowck/src/location.rs +++ b/compiler/rustc_borrowck/src/location.rs @@ -33,7 +33,7 @@ impl LocationTable { pub(crate) fn new(body: &Body<'_>) -> Self { let mut num_points = 0; let statements_before_block = body - .basic_blocks() + .basic_blocks .iter() .map(|block_data| { let v = num_points; diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index c81ef10f7c7..de20a4bb465 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -25,7 +25,7 @@ impl RegionValueElements { pub(crate) fn new(body: &Body<'_>) -> Self { let mut num_points = 0; let statements_before_block: IndexVec = body - .basic_blocks() + .basic_blocks .iter() .map(|block_data| { let v = num_points; @@ -37,7 +37,7 @@ impl RegionValueElements { debug!("RegionValueElements: num_points={:#?}", num_points); let mut basic_blocks = IndexVec::with_capacity(num_points); - for (bb, bb_data) in body.basic_blocks().iter_enumerated() { + for (bb, bb_data) in body.basic_blocks.iter_enumerated() { basic_blocks.extend((0..=bb_data.statements.len()).map(|_| bb)); } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 293d847ec9a..c1812aa4bba 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2633,7 +2633,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.check_local(&body, local, local_decl); } - for (block, block_data) in body.basic_blocks().iter_enumerated() { + for (block, block_data) in body.basic_blocks.iter_enumerated() { let mut location = Location { block, statement_index: 0 }; for stmt in &block_data.statements { if !stmt.source_info.span.is_dummy() { diff --git a/compiler/rustc_codegen_cranelift/src/analyze.rs b/compiler/rustc_codegen_cranelift/src/analyze.rs index 35b89358b19..0cbb9f3ec2d 100644 --- a/compiler/rustc_codegen_cranelift/src/analyze.rs +++ b/compiler/rustc_codegen_cranelift/src/analyze.rs @@ -26,7 +26,7 @@ pub(crate) fn analyze(fx: &FunctionCx<'_, '_, '_>) -> IndexVec { }) .collect::>(); - for bb in fx.mir.basic_blocks().iter() { + for bb in fx.mir.basic_blocks.iter() { for stmt in bb.statements.iter() { match &stmt.kind { Assign(place_and_rval) => match &place_and_rval.1 { diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 44c34d6c8cb..3011813c703 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -73,7 +73,7 @@ pub(crate) fn codegen_fn<'tcx>( // Predefine blocks let start_block = bcx.create_block(); let block_map: IndexVec = - (0..mir.basic_blocks().len()).map(|_| bcx.create_block()).collect(); + (0..mir.basic_blocks.len()).map(|_| bcx.create_block()).collect(); // Make FunctionCx let target_config = module.target_config(); @@ -271,7 +271,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { } fx.tcx.sess.time("codegen prelude", || crate::abi::codegen_fn_prelude(fx, start_block)); - for (bb, bb_data) in fx.mir.basic_blocks().iter_enumerated() { + for (bb, bb_data) in fx.mir.basic_blocks.iter_enumerated() { let block = fx.get_block(bb); fx.bcx.switch_to_block(block); diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 7f7fd0e9c57..e2b68f24a21 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -505,7 +505,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( return None; } let mut computed_const_val = None; - for bb_data in fx.mir.basic_blocks() { + for bb_data in fx.mir.basic_blocks.iter() { for stmt in &bb_data.statements { match &stmt.kind { StatementKind::Assign(local_and_rvalue) if &local_and_rvalue.0 == place => { diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index 24da48ead63..c7617d2e464 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -266,7 +266,7 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec, mir: &mir::Body<'tcx>, ) { - for (bb, data) in mir.basic_blocks().iter_enumerated() { + for (bb, data) in mir.basic_blocks.iter_enumerated() { match data.terminator().kind { TerminatorKind::Goto { .. } | TerminatorKind::Resume @@ -296,7 +296,7 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec(result: &mut IndexVec, mir: &mir::Body<'tcx>) { - let mut funclet_succs = IndexVec::from_elem(None, mir.basic_blocks()); + let mut funclet_succs = IndexVec::from_elem(None, &mir.basic_blocks); let mut set_successor = |funclet: mir::BasicBlock, succ| match funclet_succs[funclet] { ref mut s @ None => { @@ -359,7 +359,7 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec>( let start_llbb = Bx::append_block(cx, llfn, "start"); let mut bx = Bx::build(cx, start_llbb); - if mir.basic_blocks().iter().any(|bb| bb.is_cleanup) { + if mir.basic_blocks.iter().any(|bb| bb.is_cleanup) { bx.set_personality_fn(cx.eh_personality()); } let cleanup_kinds = analyze::cleanup_kinds(&mir); let cached_llbbs: IndexVec> = mir - .basic_blocks() + .basic_blocks .indices() .map(|bb| if bb == mir::START_BLOCK { Some(start_llbb) } else { None }) .collect(); @@ -172,8 +172,8 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( unreachable_block: None, double_unwind_guard: None, cleanup_kinds, - landing_pads: IndexVec::from_elem(None, mir.basic_blocks()), - funclets: IndexVec::from_fn_n(|_| None, mir.basic_blocks().len()), + landing_pads: IndexVec::from_elem(None, &mir.basic_blocks), + funclets: IndexVec::from_fn_n(|_| None, mir.basic_blocks.len()), locals: IndexVec::new(), debug_context, per_local_var_debug_info: None, diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 150d6589b08..594bfd13f1d 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -782,7 +782,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { assert_eq!( unwinding, match self.frame().loc { - Ok(loc) => self.body().basic_blocks()[loc.block].is_cleanup, + Ok(loc) => self.body().basic_blocks[loc.block].is_cleanup, Err(_) => true, } ); diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs index 5864b921552..91f4f042517 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs @@ -28,7 +28,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let mut source_info = *frame.body.source_info(loc); // If this is a `Call` terminator, use the `fn_span` instead. - let block = &frame.body.basic_blocks()[loc.block]; + let block = &frame.body.basic_blocks[loc.block]; if loc.statement_index == block.statements.len() { debug!( "find_closest_untracked_caller_location: got terminator {:?} ({:?})", diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index fea158a9fe4..683e11ff7e0 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -53,7 +53,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.pop_stack_frame(/* unwinding */ true)?; return Ok(true); }; - let basic_block = &self.body().basic_blocks()[loc.block]; + let basic_block = &self.body().basic_blocks[loc.block]; if let Some(stmt) = basic_block.statements.get(loc.statement_index) { let old_frames = self.frame_idx(); diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 0adb88a180f..cbfdb47dd1a 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -135,7 +135,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> { // qualifs for the return type. let return_block = ccx .body - .basic_blocks() + .basic_blocks .iter_enumerated() .find(|(_, block)| matches!(block.terminator().kind, TerminatorKind::Return)) .map(|(bb, _)| bb); diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 161c89e3242..6301388d1e8 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -710,7 +710,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { } fn assign(&mut self, dest: Local, rvalue: Rvalue<'tcx>, span: Span) { - let last = self.promoted.basic_blocks().last().unwrap(); + let last = self.promoted.basic_blocks.last().unwrap(); let data = &mut self.promoted[last]; data.statements.push(Statement { source_info: SourceInfo::outermost(span), @@ -803,7 +803,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { self.visit_operand(arg, loc); } - let last = self.promoted.basic_blocks().last().unwrap(); + let last = self.promoted.basic_blocks.last().unwrap(); let new_target = self.new_block(); *self.promoted[last].terminator_mut() = Terminator { @@ -1041,7 +1041,7 @@ pub fn is_const_fn_in_array_repeat_expression<'tcx>( _ => {} } - for block in body.basic_blocks() { + for block in body.basic_blocks.iter() { if let Some(Terminator { kind: TerminatorKind::Call { func, destination, .. }, .. }) = &block.terminator { diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 1a14cd79fa0..45a94972c11 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -140,8 +140,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if bb == START_BLOCK { self.fail(location, "start block must not have predecessors") } - if let Some(bb) = self.body.basic_blocks().get(bb) { - let src = self.body.basic_blocks().get(location.block).unwrap(); + if let Some(bb) = self.body.basic_blocks.get(bb) { + let src = self.body.basic_blocks.get(location.block).unwrap(); match (src.is_cleanup, bb.is_cleanup, edge_kind) { // Non-cleanup blocks can jump to non-cleanup blocks along non-unwind edges (false, false, EdgeKind::Normal) @@ -881,13 +881,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } TerminatorKind::Resume | TerminatorKind::Abort => { let bb = location.block; - if !self.body.basic_blocks()[bb].is_cleanup { + if !self.body.basic_blocks[bb].is_cleanup { self.fail(location, "Cannot `Resume` or `Abort` from non-cleanup basic block") } } TerminatorKind::Return => { let bb = location.block; - if self.body.basic_blocks()[bb].is_cleanup { + if self.body.basic_blocks[bb].is_cleanup { self.fail(location, "Cannot `Return` from cleanup basic block") } } diff --git a/compiler/rustc_middle/src/mir/generic_graph.rs b/compiler/rustc_middle/src/mir/generic_graph.rs index f3621cd99d3..d1f3561c02c 100644 --- a/compiler/rustc_middle/src/mir/generic_graph.rs +++ b/compiler/rustc_middle/src/mir/generic_graph.rs @@ -12,14 +12,14 @@ pub fn mir_fn_to_generic_graph<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Grap // Nodes let nodes: Vec = body - .basic_blocks() + .basic_blocks .iter_enumerated() .map(|(block, _)| bb_to_graph_node(block, body, dark_mode)) .collect(); // Edges let mut edges = Vec::new(); - for (source, _) in body.basic_blocks().iter_enumerated() { + for (source, _) in body.basic_blocks.iter_enumerated() { let def_id = body.source.def_id(); let terminator = body[source].terminator(); let labels = terminator.kind.fmt_successor_labels(); diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 9da9b4e91f6..f7a1e9b2864 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -331,11 +331,6 @@ impl<'tcx> Body<'tcx> { body } - #[inline] - pub fn basic_blocks(&self) -> &IndexVec> { - &self.basic_blocks - } - #[inline] pub fn basic_blocks_mut(&mut self) -> &mut IndexVec> { self.basic_blocks.as_mut() @@ -490,7 +485,7 @@ impl<'tcx> Index for Body<'tcx> { #[inline] fn index(&self, index: BasicBlock) -> &BasicBlockData<'tcx> { - &self.basic_blocks()[index] + &self.basic_blocks[index] } } diff --git a/compiler/rustc_middle/src/mir/patch.rs b/compiler/rustc_middle/src/mir/patch.rs index 8aa761aae8d..24fe3b47256 100644 --- a/compiler/rustc_middle/src/mir/patch.rs +++ b/compiler/rustc_middle/src/mir/patch.rs @@ -19,7 +19,7 @@ pub struct MirPatch<'tcx> { impl<'tcx> MirPatch<'tcx> { pub fn new(body: &Body<'tcx>) -> Self { let mut result = MirPatch { - patch_map: IndexVec::from_elem(None, body.basic_blocks()), + patch_map: IndexVec::from_elem(None, &body.basic_blocks), new_blocks: vec![], new_statements: vec![], new_locals: vec![], @@ -29,7 +29,7 @@ impl<'tcx> MirPatch<'tcx> { }; // Check if we already have a resume block - for (bb, block) in body.basic_blocks().iter_enumerated() { + for (bb, block) in body.basic_blocks.iter_enumerated() { if let TerminatorKind::Resume = block.terminator().kind && block.statements.is_empty() { result.resume_block = Some(bb); break; @@ -61,7 +61,7 @@ impl<'tcx> MirPatch<'tcx> { } pub fn terminator_loc(&self, body: &Body<'tcx>, bb: BasicBlock) -> Location { - let offset = match bb.index().checked_sub(body.basic_blocks().len()) { + let offset = match bb.index().checked_sub(body.basic_blocks.len()) { Some(index) => self.new_blocks[index].statements.len(), None => body[bb].statements.len(), }; @@ -129,7 +129,7 @@ impl<'tcx> MirPatch<'tcx> { debug!( "MirPatch: {} new blocks, starting from index {}", self.new_blocks.len(), - body.basic_blocks().len() + body.basic_blocks.len() ); let bbs = if self.patch_map.is_empty() && self.new_blocks.is_empty() { body.basic_blocks.as_mut_preserves_cfg() @@ -173,7 +173,7 @@ impl<'tcx> MirPatch<'tcx> { } pub fn source_info_for_location(&self, body: &Body<'tcx>, loc: Location) -> SourceInfo { - let data = match loc.block.index().checked_sub(body.basic_blocks().len()) { + let data = match loc.block.index().checked_sub(body.basic_blocks.len()) { Some(new) => &self.new_blocks[new], None => &body[loc.block], }; diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 0ce41337b91..da6af89b09b 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -318,10 +318,10 @@ where F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>, { write_mir_intro(tcx, body, w)?; - for block in body.basic_blocks().indices() { + for block in body.basic_blocks.indices() { extra_data(PassWhere::BeforeBlock(block), w)?; write_basic_block(tcx, block, body, extra_data, w)?; - if block.index() + 1 != body.basic_blocks().len() { + if block.index() + 1 != body.basic_blocks.len() { writeln!(w)?; } } diff --git a/compiler/rustc_middle/src/mir/spanview.rs b/compiler/rustc_middle/src/mir/spanview.rs index 4418b848e51..6e64a3b80c1 100644 --- a/compiler/rustc_middle/src/mir/spanview.rs +++ b/compiler/rustc_middle/src/mir/spanview.rs @@ -105,7 +105,7 @@ where } let body_span = hir_body.unwrap().value.span; let mut span_viewables = Vec::new(); - for (bb, data) in body.basic_blocks().iter_enumerated() { + for (bb, data) in body.basic_blocks.iter_enumerated() { match spanview { MirSpanview::Statement => { for (i, statement) in data.statements.iter().enumerate() { diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index 627dc32f37e..55b2c592795 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -37,7 +37,7 @@ impl<'a, 'tcx> Preorder<'a, 'tcx> { Preorder { body, - visited: BitSet::new_empty(body.basic_blocks().len()), + visited: BitSet::new_empty(body.basic_blocks.len()), worklist, root_is_start_block: root == START_BLOCK, } @@ -71,7 +71,7 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> { fn size_hint(&self) -> (usize, Option) { // All the blocks, minus the number of blocks we've visited. - let upper = self.body.basic_blocks().len() - self.visited.count(); + let upper = self.body.basic_blocks.len() - self.visited.count(); let lower = if self.root_is_start_block { // We will visit all remaining blocks exactly once. diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 4a85defb1ed..7bd65f42e3f 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -951,7 +951,7 @@ macro_rules! basic_blocks { $body.basic_blocks.as_mut_preserves_cfg() }; ($body:ident,) => { - $body.basic_blocks() + $body.basic_blocks }; } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 461c837f6df..684b228e87f 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -272,7 +272,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ // by borrow checking. debug_assert!( !(body.local_decls.has_free_regions() - || body.basic_blocks().has_free_regions() + || body.basic_blocks.has_free_regions() || body.var_debug_info.has_free_regions() || body.yield_ty().has_free_regions()), "Unexpected free regions in MIR: {:?}", diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs index f374658ceb6..ecfa90371f5 100644 --- a/compiler/rustc_mir_dataflow/src/framework/engine.rs +++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs @@ -108,9 +108,9 @@ where // Otherwise, compute and store the cumulative transfer function for each block. let identity = GenKillSet::identity(analysis.bottom_value(body).domain_size()); - let mut trans_for_block = IndexVec::from_elem(identity, body.basic_blocks()); + let mut trans_for_block = IndexVec::from_elem(identity, &body.basic_blocks); - for (block, block_data) in body.basic_blocks().iter_enumerated() { + for (block, block_data) in body.basic_blocks.iter_enumerated() { let trans = &mut trans_for_block[block]; A::Direction::gen_kill_effects_in_block(&analysis, trans, block, block_data); } @@ -144,7 +144,7 @@ where apply_trans_for_block: Option>, ) -> Self { let bottom_value = analysis.bottom_value(body); - let mut entry_sets = IndexVec::from_elem(bottom_value.clone(), body.basic_blocks()); + let mut entry_sets = IndexVec::from_elem(bottom_value.clone(), &body.basic_blocks); analysis.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]); if A::Direction::IS_BACKWARD && entry_sets[mir::START_BLOCK] != bottom_value { @@ -197,8 +197,7 @@ where .. } = self; - let mut dirty_queue: WorkQueue = - WorkQueue::with_none(body.basic_blocks().len()); + let mut dirty_queue: WorkQueue = WorkQueue::with_none(body.basic_blocks.len()); if A::Direction::IS_FORWARD { for (bb, _) in traversal::reverse_postorder(body) { diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index c94198c56a8..579fe68a149 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs @@ -108,12 +108,12 @@ where type Edge = CfgEdge; fn nodes(&self) -> dot::Nodes<'_, Self::Node> { - self.body.basic_blocks().indices().collect::>().into() + self.body.basic_blocks.indices().collect::>().into() } fn edges(&self) -> dot::Edges<'_, Self::Edge> { self.body - .basic_blocks() + .basic_blocks .indices() .flat_map(|bb| dataflow_successors(self.body, bb)) .collect::>() diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs index d9461fd3abd..17102454a88 100644 --- a/compiler/rustc_mir_dataflow/src/framework/tests.rs +++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs @@ -100,9 +100,9 @@ impl MockAnalysis<'_, D> { fn mock_entry_sets(&self) -> IndexVec> { let empty = self.bottom_value(self.body); - let mut ret = IndexVec::from_elem(empty, &self.body.basic_blocks()); + let mut ret = IndexVec::from_elem(empty, &self.body.basic_blocks); - for (bb, _) in self.body.basic_blocks().iter_enumerated() { + for (bb, _) in self.body.basic_blocks.iter_enumerated() { ret[bb] = self.mock_entry_set(bb); } @@ -169,7 +169,7 @@ impl<'tcx, D: Direction> AnalysisDomain<'tcx> for MockAnalysis<'tcx, D> { const NAME: &'static str = "mock"; fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain { - BitSet::new_empty(Self::BASIC_BLOCK_OFFSET + body.basic_blocks().len()) + BitSet::new_empty(Self::BASIC_BLOCK_OFFSET + body.basic_blocks.len()) } fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) { @@ -271,9 +271,7 @@ fn test_cursor(analysis: MockAnalysis<'_, D>) { cursor.allow_unreachable(); let every_target = || { - body.basic_blocks() - .iter_enumerated() - .flat_map(|(bb, _)| SeekTarget::iter_in_block(body, bb)) + body.basic_blocks.iter_enumerated().flat_map(|(bb, _)| SeekTarget::iter_in_block(body, bb)) }; let mut seek_to_target = |targ| { diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 116e5c1f3ce..c3258386223 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -243,7 +243,7 @@ pub(super) fn gather_moves<'tcx>( builder.gather_args(); - for (bb, block) in body.basic_blocks().iter_enumerated() { + for (bb, block) in body.basic_blocks.iter_enumerated() { for (i, stmt) in block.statements.iter().enumerate() { let source = Location { block: bb, statement_index: i }; builder.gather_statement(source, stmt); diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index a951c5b0b1c..b36e268cf8b 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -217,7 +217,7 @@ where fn new(body: &Body<'_>) -> Self { LocationMap { map: body - .basic_blocks() + .basic_blocks .iter() .map(|block| vec![T::default(); block.statements.len() + 1]) .collect(), diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index f2471f37a52..382d371840f 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -97,7 +97,7 @@ pub fn sanity_check_via_rustc_peek<'tcx, A>( let mut cursor = ResultsCursor::new(body, results); - let peek_calls = body.basic_blocks().iter_enumerated().filter_map(|(bb, block_data)| { + let peek_calls = body.basic_blocks.iter_enumerated().filter_map(|(bb, block_data)| { PeekCall::from_terminator(tcx, block_data.terminator()).map(|call| (bb, block_data, call)) }); diff --git a/compiler/rustc_mir_dataflow/src/storage.rs b/compiler/rustc_mir_dataflow/src/storage.rs index c909648ea01..e5a0e1d312e 100644 --- a/compiler/rustc_mir_dataflow/src/storage.rs +++ b/compiler/rustc_mir_dataflow/src/storage.rs @@ -7,7 +7,7 @@ use rustc_middle::mir::{self, Local}; pub fn always_storage_live_locals(body: &mir::Body<'_>) -> BitSet { let mut always_live_locals = BitSet::new_filled(body.local_decls.len()); - for block in body.basic_blocks() { + for block in &*body.basic_blocks { for statement in &block.statements { use mir::StatementKind::{StorageDead, StorageLive}; if let StorageLive(l) | StorageDead(l) = statement.kind { diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs index 2502e8b603c..d8f85d2e379 100644 --- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs +++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs @@ -56,7 +56,7 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls { // example. let mut calls_to_terminate = Vec::new(); let mut cleanups_to_remove = Vec::new(); - for (id, block) in body.basic_blocks().iter_enumerated() { + for (id, block) in body.basic_blocks.iter_enumerated() { if block.is_cleanup { continue; } diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs index f12c8560c0e..30966d22e2f 100644 --- a/compiler/rustc_mir_transform/src/add_call_guards.rs +++ b/compiler/rustc_mir_transform/src/add_call_guards.rs @@ -45,7 +45,7 @@ impl AddCallGuards { // We need a place to store the new blocks generated let mut new_blocks = Vec::new(); - let cur_len = body.basic_blocks().len(); + let cur_len = body.basic_blocks.len(); for block in body.basic_blocks_mut() { match block.terminator { diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs index 8de0aad041c..ffb5d8c6d95 100644 --- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs +++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs @@ -55,7 +55,7 @@ fn add_moves_for_packed_drops_patch<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) let mut patch = MirPatch::new(body); let param_env = tcx.param_env(def_id); - for (bb, data) in body.basic_blocks().iter_enumerated() { + for (bb, data) in body.basic_blocks.iter_enumerated() { let loc = Location { block: bb, statement_index: data.statements.len() }; let terminator = data.terminator(); diff --git a/compiler/rustc_mir_transform/src/const_goto.rs b/compiler/rustc_mir_transform/src/const_goto.rs index 5acf939f06b..0a305a40209 100644 --- a/compiler/rustc_mir_transform/src/const_goto.rs +++ b/compiler/rustc_mir_transform/src/const_goto.rs @@ -61,14 +61,14 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> { let _: Option<_> = try { let target = terminator.kind.as_goto()?; // We only apply this optimization if the last statement is a const assignment - let last_statement = self.body.basic_blocks()[location.block].statements.last()?; + let last_statement = self.body.basic_blocks[location.block].statements.last()?; if let (place, Rvalue::Use(Operand::Constant(_const))) = last_statement.kind.as_assign()? { // We found a constant being assigned to `place`. // Now check that the target of this Goto switches on this place. - let target_bb = &self.body.basic_blocks()[target]; + let target_bb = &self.body.basic_blocks[target]; // The `StorageDead(..)` statement does not affect the functionality of mir. // We can move this part of the statement up to the predecessor. diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 1c087b93b49..fdcc065f112 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -131,7 +131,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp { let dummy_body = &Body::new( body.source, - body.basic_blocks().clone(), + (*body.basic_blocks).clone(), body.source_scopes.clone(), body.local_decls.clone(), Default::default(), diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index c2ea55af48a..1254aee3994 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -106,7 +106,7 @@ impl<'tcx> MirLint<'tcx> for ConstProp { let dummy_body = &Body::new( body.source, - body.basic_blocks().clone(), + (*body.basic_blocks).clone(), body.source_scopes.clone(), body.local_decls.clone(), Default::default(), @@ -524,7 +524,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { fn visit_body(&mut self, body: &Body<'tcx>) { - for (bb, data) in body.basic_blocks().iter_enumerated() { + for (bb, data) in body.basic_blocks.iter_enumerated() { self.visit_basic_block_data(bb, data); } } diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 759ea7cd328..782129be088 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -713,7 +713,7 @@ impl< ShortCircuitPreorder { body, - visited: BitSet::new_empty(body.basic_blocks().len()), + visited: BitSet::new_empty(body.basic_blocks.len()), worklist, filtered_successors, } @@ -747,7 +747,7 @@ impl< } fn size_hint(&self) -> (usize, Option) { - let size = self.body.basic_blocks().len() - self.visited.count(); + let size = self.body.basic_blocks.len() - self.visited.count(); (size, Some(size)) } } diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 2619626a567..299a8067b28 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -80,7 +80,7 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage { return; } - match mir_body.basic_blocks()[mir::START_BLOCK].terminator().kind { + match mir_body.basic_blocks[mir::START_BLOCK].terminator().kind { TerminatorKind::Unreachable => { trace!("InstrumentCoverage skipped for unreachable `START_BLOCK`"); return; diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs index 9d02f58ae65..dc1e68b253e 100644 --- a/compiler/rustc_mir_transform/src/coverage/query.rs +++ b/compiler/rustc_mir_transform/src/coverage/query.rs @@ -84,7 +84,7 @@ impl CoverageVisitor { } fn visit_body(&mut self, body: &Body<'_>) { - for bb_data in body.basic_blocks().iter() { + for bb_data in body.basic_blocks.iter() { for statement in bb_data.statements.iter() { if let StatementKind::Coverage(box ref coverage) = statement.kind { if is_inlined(body, statement) { @@ -138,7 +138,7 @@ fn coverageinfo<'tcx>(tcx: TyCtxt<'tcx>, instance_def: ty::InstanceDef<'tcx>) -> fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx CodeRegion> { let body = mir_body(tcx, def_id); - body.basic_blocks() + body.basic_blocks .iter() .flat_map(|data| { data.statements.iter().filter_map(|statement| match statement.kind { diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index 6380f03528a..9c9ed5fa510 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -176,7 +176,7 @@ fn debug_basic_blocks<'tcx>(mir_body: &Body<'tcx>) -> String { format!( "{:?}", mir_body - .basic_blocks() + .basic_blocks .iter_enumerated() .map(|(bb, data)| { let term = &data.terminator(); @@ -213,7 +213,7 @@ fn print_mir_graphviz(name: &str, mir_body: &Body<'_>) { "digraph {} {{\n{}\n}}", name, mir_body - .basic_blocks() + .basic_blocks .iter_enumerated() .map(|(bb, data)| { format!( @@ -653,7 +653,7 @@ fn test_traverse_coverage_with_loops() { fn synthesize_body_span_from_terminators(mir_body: &Body<'_>) -> Span { let mut some_span: Option = None; - for (_, data) in mir_body.basic_blocks().iter_enumerated() { + for (_, data) in mir_body.basic_blocks.iter_enumerated() { let term_span = data.terminator().source_info.span; if let Some(span) = some_span.as_mut() { *span = span.to(term_span); diff --git a/compiler/rustc_mir_transform/src/deduplicate_blocks.rs b/compiler/rustc_mir_transform/src/deduplicate_blocks.rs index d1977ed49fe..909116a77f5 100644 --- a/compiler/rustc_mir_transform/src/deduplicate_blocks.rs +++ b/compiler/rustc_mir_transform/src/deduplicate_blocks.rs @@ -58,7 +58,7 @@ fn find_duplicates(body: &Body<'_>) -> FxHashMap { let mut duplicates = FxHashMap::default(); let bbs_to_go_through = - body.basic_blocks().iter_enumerated().filter(|(_, bbd)| !bbd.is_cleanup).count(); + body.basic_blocks.iter_enumerated().filter(|(_, bbd)| !bbd.is_cleanup).count(); let mut same_hashes = FxHashMap::with_capacity_and_hasher(bbs_to_go_through, Default::default()); @@ -71,8 +71,7 @@ fn find_duplicates(body: &Body<'_>) -> FxHashMap { // When we see bb1, we see that it is a duplicate of bb3, and therefore insert it in the duplicates list // with replacement bb3. // When the duplicates are removed, we will end up with only bb3. - for (bb, bbd) in body.basic_blocks().iter_enumerated().rev().filter(|(_, bbd)| !bbd.is_cleanup) - { + for (bb, bbd) in body.basic_blocks.iter_enumerated().rev().filter(|(_, bbd)| !bbd.is_cleanup) { // Basic blocks can get really big, so to avoid checking for duplicates in basic blocks // that are unlikely to have duplicates, we stop early. The early bail number has been // found experimentally by eprintln while compiling the crates in the rustc-perf suite. diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 33572068f5c..da55510920e 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -150,7 +150,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation { def_id, body.local_decls.len(), relevant, - body.basic_blocks().len() + body.basic_blocks.len() ); if relevant > MAX_LOCALS { warn!( @@ -159,11 +159,11 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation { ); return; } - if body.basic_blocks().len() > MAX_BLOCKS { + if body.basic_blocks.len() > MAX_BLOCKS { warn!( "too many blocks in {:?} ({}, max is {}), not optimizing", def_id, - body.basic_blocks().len(), + body.basic_blocks.len(), MAX_BLOCKS ); return; diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs index dba42f7aff0..32e738bbcea 100644 --- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs +++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs @@ -104,8 +104,8 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { let mut should_cleanup = false; // Also consider newly generated bbs in the same pass - for i in 0..body.basic_blocks().len() { - let bbs = body.basic_blocks(); + for i in 0..body.basic_blocks.len() { + let bbs = &*body.basic_blocks; let parent = BasicBlock::from_usize(i); let Some(opt_data) = evaluate_candidate(tcx, body, parent) else { continue @@ -316,7 +316,7 @@ fn evaluate_candidate<'tcx>( body: &Body<'tcx>, parent: BasicBlock, ) -> Option> { - let bbs = body.basic_blocks(); + let bbs = &body.basic_blocks; let TerminatorKind::SwitchInt { targets, switch_ty: parent_ty, diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 9c1fcbaa69d..61118ecc8ed 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -89,13 +89,13 @@ fn find_dead_unwinds<'tcx>( debug!("find_dead_unwinds({:?})", body.span); // We only need to do this pass once, because unwind edges can only // reach cleanup blocks, which can't have unwind edges themselves. - let mut dead_unwinds = BitSet::new_empty(body.basic_blocks().len()); + let mut dead_unwinds = BitSet::new_empty(body.basic_blocks.len()); let mut flow_inits = MaybeInitializedPlaces::new(tcx, body, &env) .into_engine(tcx, body) .pass_name("find_dead_unwinds") .iterate_to_fixpoint() .into_results_cursor(body); - for (bb, bb_data) in body.basic_blocks().iter_enumerated() { + for (bb, bb_data) in body.basic_blocks.iter_enumerated() { let place = match bb_data.terminator().kind { TerminatorKind::Drop { ref place, unwind: Some(_), .. } | TerminatorKind::DropAndReplace { ref place, unwind: Some(_), .. } => { @@ -303,7 +303,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { } fn collect_drop_flags(&mut self) { - for (bb, data) in self.body.basic_blocks().iter_enumerated() { + for (bb, data) in self.body.basic_blocks.iter_enumerated() { let terminator = data.terminator(); let place = match terminator.kind { TerminatorKind::Drop { ref place, .. } @@ -358,7 +358,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { } fn elaborate_drops(&mut self) { - for (bb, data) in self.body.basic_blocks().iter_enumerated() { + for (bb, data) in self.body.basic_blocks.iter_enumerated() { let loc = Location { block: bb, statement_index: data.statements.len() }; let terminator = data.terminator(); @@ -515,7 +515,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { } fn drop_flags_for_fn_rets(&mut self) { - for (bb, data) in self.body.basic_blocks().iter_enumerated() { + for (bb, data) in self.body.basic_blocks.iter_enumerated() { if let TerminatorKind::Call { destination, target: Some(tgt), cleanup: Some(_), .. } = data.terminator().kind @@ -550,7 +550,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { // drop flags by themselves, to avoid the drop flags being // clobbered before they are read. - for (bb, data) in self.body.basic_blocks().iter_enumerated() { + for (bb, data) in self.body.basic_blocks.iter_enumerated() { debug!("drop_flags_for_locs({:?})", data); for i in 0..(data.statements.len() + 1) { debug!("drop_flag_for_locs: stmt {}", i); diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index 7728fdaffb0..7522a50a8c6 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -65,7 +65,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool { let mut tainted = false; - for block in body.basic_blocks() { + for block in body.basic_blocks.iter() { if block.is_cleanup { continue; } diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 5b0d9900c0f..c260611b407 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -490,12 +490,12 @@ fn locals_live_across_suspend_points<'tcx>( .iterate_to_fixpoint() .into_results_cursor(body_ref); - let mut storage_liveness_map = IndexVec::from_elem(None, body.basic_blocks()); + let mut storage_liveness_map = IndexVec::from_elem(None, &body.basic_blocks); let mut live_locals_at_suspension_points = Vec::new(); let mut source_info_at_suspension_points = Vec::new(); let mut live_locals_at_any_suspension_point = BitSet::new_empty(body.local_decls.len()); - for (block, data) in body.basic_blocks().iter_enumerated() { + for (block, data) in body.basic_blocks.iter_enumerated() { if let TerminatorKind::Yield { .. } = data.terminator().kind { let loc = Location { block, statement_index: data.statements.len() }; @@ -704,7 +704,7 @@ impl<'mir, 'tcx> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx> impl StorageConflictVisitor<'_, '_, '_> { fn apply_state(&mut self, flow_state: &BitSet, loc: Location) { // Ignore unreachable blocks. - if self.body.basic_blocks()[loc.block].terminator().kind == TerminatorKind::Unreachable { + if self.body.basic_blocks[loc.block].terminator().kind == TerminatorKind::Unreachable { return; } @@ -886,7 +886,7 @@ fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let mut elaborator = DropShimElaborator { body, patch: MirPatch::new(body), tcx, param_env }; - for (block, block_data) in body.basic_blocks().iter_enumerated() { + for (block, block_data) in body.basic_blocks.iter_enumerated() { let (target, unwind, source_info) = match block_data.terminator() { Terminator { source_info, kind: TerminatorKind::Drop { place, target, unwind } } => { if let Some(local) = place.as_local() { @@ -991,7 +991,7 @@ fn insert_panic_block<'tcx>( body: &mut Body<'tcx>, message: AssertMessage<'tcx>, ) -> BasicBlock { - let assert_block = BasicBlock::new(body.basic_blocks().len()); + let assert_block = BasicBlock::new(body.basic_blocks.len()); let term = TerminatorKind::Assert { cond: Operand::Constant(Box::new(Constant { span: body.span, @@ -1021,7 +1021,7 @@ fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, param_env: ty::ParamEn } // If there's a return terminator the function may return. - for block in body.basic_blocks() { + for block in body.basic_blocks.iter() { if let TerminatorKind::Return = block.terminator().kind { return true; } @@ -1038,7 +1038,7 @@ fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool { } // Unwinds can only start at certain terminators. - for block in body.basic_blocks() { + for block in body.basic_blocks.iter() { match block.terminator().kind { // These never unwind. TerminatorKind::Goto { .. } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index d7d29840188..ba00f16308e 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -95,7 +95,7 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { history: Vec::new(), changed: false, }; - let blocks = BasicBlock::new(0)..body.basic_blocks().next_index(); + let blocks = BasicBlock::new(0)..body.basic_blocks.next_index(); this.process_blocks(body, blocks); this.changed } @@ -217,9 +217,9 @@ impl<'tcx> Inliner<'tcx> { } } - let old_blocks = caller_body.basic_blocks().next_index(); + let old_blocks = caller_body.basic_blocks.next_index(); self.inline_call(caller_body, &callsite, callee_body); - let new_blocks = old_blocks..caller_body.basic_blocks().next_index(); + let new_blocks = old_blocks..caller_body.basic_blocks.next_index(); Ok(new_blocks) } @@ -409,14 +409,14 @@ impl<'tcx> Inliner<'tcx> { // Give a bonus functions with a small number of blocks, // We normally have two or three blocks for even // very small functions. - if callee_body.basic_blocks().len() <= 3 { + if callee_body.basic_blocks.len() <= 3 { threshold += threshold / 4; } debug!(" final inline threshold = {}", threshold); // FIXME: Give a bonus to functions with only a single caller let diverges = matches!( - callee_body.basic_blocks()[START_BLOCK].terminator().kind, + callee_body.basic_blocks[START_BLOCK].terminator().kind, TerminatorKind::Unreachable | TerminatorKind::Call { target: None, .. } ); if diverges && !matches!(callee_attrs.inline, InlineAttr::Always) { @@ -434,13 +434,13 @@ impl<'tcx> Inliner<'tcx> { // Traverse the MIR manually so we can account for the effects of inlining on the CFG. let mut work_list = vec![START_BLOCK]; - let mut visited = BitSet::new_empty(callee_body.basic_blocks().len()); + let mut visited = BitSet::new_empty(callee_body.basic_blocks.len()); while let Some(bb) = work_list.pop() { if !visited.insert(bb.index()) { continue; } - let blk = &callee_body.basic_blocks()[bb]; + let blk = &callee_body.basic_blocks[bb]; checker.visit_basic_block_data(bb, blk); let term = blk.terminator(); @@ -541,7 +541,7 @@ impl<'tcx> Inliner<'tcx> { args: &args, new_locals: Local::new(caller_body.local_decls.len()).., new_scopes: SourceScope::new(caller_body.source_scopes.len()).., - new_blocks: BasicBlock::new(caller_body.basic_blocks().len()).., + new_blocks: BasicBlock::new(caller_body.basic_blocks.len()).., destination: dest, callsite_scope: caller_body.source_scopes[callsite.source_info.scope].clone(), callsite, diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 7810218fd67..b027f94925d 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -153,7 +153,7 @@ pub(crate) fn mir_inliner_callees<'tcx>( _ => tcx.instance_mir(instance), }; let mut calls = FxIndexSet::default(); - for bb_data in body.basic_blocks() { + for bb_data in body.basic_blocks.iter() { let terminator = bb_data.terminator(); if let TerminatorKind::Call { func, .. } = &terminator.kind { let ty = func.ty(&body.local_decls, tcx); diff --git a/compiler/rustc_mir_transform/src/multiple_return_terminators.rs b/compiler/rustc_mir_transform/src/multiple_return_terminators.rs index 22b6dead99c..3957cd92c4e 100644 --- a/compiler/rustc_mir_transform/src/multiple_return_terminators.rs +++ b/compiler/rustc_mir_transform/src/multiple_return_terminators.rs @@ -15,7 +15,7 @@ impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // find basic blocks with no statement and a return terminator - let mut bbs_simple_returns = BitSet::new_empty(body.basic_blocks().len()); + let mut bbs_simple_returns = BitSet::new_empty(body.basic_blocks.len()); let def_id = body.source.def_id(); let bbs = body.basic_blocks_mut(); for idx in bbs.indices() { diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs index c0217a10541..a159e617178 100644 --- a/compiler/rustc_mir_transform/src/normalize_array_len.rs +++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs @@ -21,10 +21,10 @@ impl<'tcx> MirPass<'tcx> for NormalizeArrayLen { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // early returns for edge cases of highly unrolled functions - if body.basic_blocks().len() > MAX_NUM_BLOCKS { + if body.basic_blocks.len() > MAX_NUM_BLOCKS { return; } - if body.local_decls().len() > MAX_NUM_LOCALS { + if body.local_decls.len() > MAX_NUM_LOCALS { return; } normalize_array_len_calls(tcx, body) diff --git a/compiler/rustc_mir_transform/src/nrvo.rs b/compiler/rustc_mir_transform/src/nrvo.rs index 42d732730ec..4291e81c78c 100644 --- a/compiler/rustc_mir_transform/src/nrvo.rs +++ b/compiler/rustc_mir_transform/src/nrvo.rs @@ -89,7 +89,7 @@ fn local_eligible_for_nrvo(body: &mut mir::Body<'_>) -> Option { } let mut copied_to_return_place = None; - for block in body.basic_blocks().indices() { + for block in body.basic_blocks.indices() { // Look for blocks with a `Return` terminator. if !matches!(body[block].terminator().kind, mir::TerminatorKind::Return) { continue; @@ -122,7 +122,7 @@ fn find_local_assigned_to_return_place( body: &mut mir::Body<'_>, ) -> Option { let mut block = start; - let mut seen = HybridBitSet::new_empty(body.basic_blocks().len()); + let mut seen = HybridBitSet::new_empty(body.basic_blocks.len()); // Iterate as long as `block` has exactly one predecessor that we have not yet visited. while seen.insert(block) { diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs index 5c441c5b194..41a0bfac41a 100644 --- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs +++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs @@ -94,7 +94,7 @@ impl RemoveNoopLandingPads { let mut jumps_folded = 0; let mut landing_pads_removed = 0; - let mut nop_landing_pads = BitSet::new_empty(body.basic_blocks().len()); + let mut nop_landing_pads = BitSet::new_empty(body.basic_blocks.len()); // This is a post-order traversal, so that if A post-dominates B // then A will be visited before B. diff --git a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs index 96b715402e7..78b6f714a9b 100644 --- a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs +++ b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs @@ -35,7 +35,7 @@ impl<'tcx> MirPass<'tcx> for RemoveUninitDrops { .into_results_cursor(body); let mut to_remove = vec![]; - for (bb, block) in body.basic_blocks().iter_enumerated() { + for (bb, block) in body.basic_blocks.iter_enumerated() { let terminator = block.terminator(); let (TerminatorKind::Drop { place, .. } | TerminatorKind::DropAndReplace { place, .. }) = &terminator.kind diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs index 925eb10a1f7..190f9c1ac15 100644 --- a/compiler/rustc_mir_transform/src/separate_const_switch.rs +++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs @@ -62,7 +62,7 @@ impl<'tcx> MirPass<'tcx> for SeparateConstSwitch { pub fn separate_const_switch(body: &mut Body<'_>) -> usize { let mut new_blocks: SmallVec<[(BasicBlock, BasicBlock); 6]> = SmallVec::new(); let predecessors = body.basic_blocks.predecessors(); - 'block_iter: for (block_id, block) in body.basic_blocks().iter_enumerated() { + 'block_iter: for (block_id, block) in body.basic_blocks.iter_enumerated() { if let TerminatorKind::SwitchInt { discr: Operand::Copy(switch_place) | Operand::Move(switch_place), .. @@ -90,7 +90,7 @@ pub fn separate_const_switch(body: &mut Body<'_>) -> usize { let mut predecessors_left = predecessors[block_id].len(); 'predec_iter: for predecessor_id in predecessors[block_id].iter().copied() { - let predecessor = &body.basic_blocks()[predecessor_id]; + let predecessor = &body.basic_blocks[predecessor_id]; // First we make sure the predecessor jumps // in a reasonable way diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 7a6ca917d0f..bed48db959a 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -74,7 +74,7 @@ pub struct CfgSimplifier<'a, 'tcx> { impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { pub fn new(body: &'a mut Body<'tcx>) -> Self { - let mut pred_count = IndexVec::from_elem(0u32, body.basic_blocks()); + let mut pred_count = IndexVec::from_elem(0u32, &body.basic_blocks); // we can't use mir.predecessors() here because that counts // dead blocks, which we don't want to. @@ -263,7 +263,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let reachable = traversal::reachable_as_bitset(body); - let num_blocks = body.basic_blocks().len(); + let num_blocks = body.basic_blocks.len(); if num_blocks == reachable.count() { return; } diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index bbfaace7041..321d8c63b6e 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -151,7 +151,7 @@ struct OptimizationFinder<'a, 'tcx> { impl<'tcx> OptimizationFinder<'_, 'tcx> { fn find_optimizations(&self) -> Vec> { self.body - .basic_blocks() + .basic_blocks .iter_enumerated() .filter_map(|(bb_idx, bb)| { // find switch diff --git a/compiler/rustc_mir_transform/src/simplify_try.rs b/compiler/rustc_mir_transform/src/simplify_try.rs index d52f1261b23..baeb620ef24 100644 --- a/compiler/rustc_mir_transform/src/simplify_try.rs +++ b/compiler/rustc_mir_transform/src/simplify_try.rs @@ -596,7 +596,7 @@ struct SimplifyBranchSameOptimizationFinder<'a, 'tcx> { impl<'tcx> SimplifyBranchSameOptimizationFinder<'_, 'tcx> { fn find(&self) -> Vec { self.body - .basic_blocks() + .basic_blocks .iter_enumerated() .filter_map(|(bb_idx, bb)| { let (discr_switched_on, targets_and_values) = match &bb.terminator().kind { @@ -632,7 +632,7 @@ impl<'tcx> SimplifyBranchSameOptimizationFinder<'_, 'tcx> { let mut iter_bbs_reachable = targets_and_values .iter() - .map(|target_and_value| (target_and_value, &self.body.basic_blocks()[target_and_value.target])) + .map(|target_and_value| (target_and_value, &self.body.basic_blocks[target_and_value.target])) .filter(|(_, bb)| { // Reaching `unreachable` is UB so assume it doesn't happen. bb.terminator().kind != TerminatorKind::Unreachable diff --git a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs index 30be64f5b2f..96ea15f1b80 100644 --- a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs +++ b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs @@ -79,7 +79,7 @@ fn ensure_otherwise_unreachable<'tcx>( targets: &SwitchTargets, ) -> Option> { let otherwise = targets.otherwise(); - let bb = &body.basic_blocks()[otherwise]; + let bb = &body.basic_blocks[otherwise]; if bb.terminator().kind == TerminatorKind::Unreachable && bb.statements.iter().all(|s| matches!(&s.kind, StatementKind::StorageDead(_))) { @@ -102,10 +102,10 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { trace!("UninhabitedEnumBranching starting for {:?}", body.source); - for bb in body.basic_blocks().indices() { + for bb in body.basic_blocks.indices() { trace!("processing block {:?}", bb); - let Some(discriminant_ty) = get_switched_on_type(&body.basic_blocks()[bb], tcx, body) else { + let Some(discriminant_ty) = get_switched_on_type(&body.basic_blocks[bb], tcx, body) else { continue; }; diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs index ff2d3869328..43319dc5862 100644 --- a/compiler/rustc_monomorphize/src/partitioning/mod.rs +++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs @@ -481,7 +481,7 @@ fn codegened_and_inlined_items<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx DefIdSe continue; } let body = tcx.instance_mir(instance.def); - for block in body.basic_blocks() { + for block in body.basic_blocks.iter() { for statement in &block.statements { let mir::StatementKind::Coverage(_) = statement.kind else { continue }; let scope = statement.source_info.scope; diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index db0d45b86fc..acfeefb4d12 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -348,7 +348,7 @@ fn instance_def_size_estimate<'tcx>( match instance_def { InstanceDef::Item(..) | InstanceDef::DropGlue(..) => { let mir = tcx.instance_mir(instance_def); - mir.basic_blocks().iter().map(|bb| bb.statements.len() + 1).sum() + mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum() } // Estimate the size of other compiler-generated shims to be 1. _ => 1, diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs index eddca604575..9fd86331ec7 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs @@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone { vis.into_map(cx, maybe_storage_live_result) }; - for (bb, bbdata) in mir.basic_blocks().iter_enumerated() { + for (bb, bbdata) in mir.basic_blocks.iter_enumerated() { let terminator = bbdata.terminator(); if terminator.source_info.span.from_expansion() { @@ -186,7 +186,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone { unwrap_or_continue!(find_stmt_assigns_to(cx, mir, pred_arg, true, ps[0])); let loc = mir::Location { block: bb, - statement_index: mir.basic_blocks()[bb].statements.len(), + statement_index: mir.basic_blocks[bb].statements.len(), }; // This can be turned into `res = move local` if `arg` and `cloned` are not borrowed @@ -310,7 +310,7 @@ fn find_stmt_assigns_to<'tcx>( by_ref: bool, bb: mir::BasicBlock, ) -> Option<(mir::Local, CannotMoveOut)> { - let rvalue = mir.basic_blocks()[bb].statements.iter().rev().find_map(|stmt| { + let rvalue = mir.basic_blocks[bb].statements.iter().rev().find_map(|stmt| { if let mir::StatementKind::Assign(box (mir::Place { local, .. }, v)) = &stmt.kind { return if *local == to_local { Some(v) } else { None }; } diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 3bf75bcbee8..74c222bbcbe 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -55,7 +55,7 @@ pub fn is_min_const_fn<'a, 'tcx>(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv: body.local_decls.iter().next().unwrap().source_info.span, )?; - for bb in body.basic_blocks() { + for bb in body.basic_blocks.iter() { check_terminator(tcx, body, bb.terminator(), msrv)?; for stmt in &bb.statements { check_statement(tcx, body, def_id, stmt)?; From 1e005af31b078f584f7adbdebc505ba0cca52706 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 28 Aug 2022 10:34:19 +0200 Subject: [PATCH 20/21] Remove Attrs type alias --- src/librustdoc/clean/inline.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index f367edcbf5a..31b805f2ed7 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -24,8 +24,6 @@ use crate::clean::{ use crate::core::DocContext; use crate::formats::item_type::ItemType; -type Attrs<'hir> = &'hir [ast::Attribute]; - /// Attempt to inline a definition into this AST. /// /// This function will fetch the definition specified, and if it is @@ -46,7 +44,7 @@ pub(crate) fn try_inline( import_def_id: Option, res: Res, name: Symbol, - attrs: Option>, + attrs: Option<&[ast::Attribute]>, visited: &mut FxHashSet, ) -> Option> { let did = res.opt_def_id()?; @@ -172,7 +170,7 @@ pub(crate) fn try_inline_glob( } } -pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> Attrs<'hir> { +pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> &'hir [ast::Attribute] { cx.tcx.get_attrs_unchecked(did) } @@ -287,7 +285,7 @@ pub(crate) fn build_impls( cx: &mut DocContext<'_>, parent_module: Option, did: DefId, - attrs: Option>, + attrs: Option<&[ast::Attribute]>, ret: &mut Vec, ) { let _prof_timer = cx.tcx.sess.prof.generic_activity("build_inherent_impls"); @@ -303,8 +301,8 @@ pub(crate) fn build_impls( pub(crate) fn merge_attrs( cx: &mut DocContext<'_>, parent_module: Option, - old_attrs: Attrs<'_>, - new_attrs: Option>, + old_attrs: &[ast::Attribute], + new_attrs: Option<&[ast::Attribute]>, ) -> (clean::Attributes, Option>) { // NOTE: If we have additional attributes (from a re-export), // always insert them first. This ensure that re-export @@ -331,7 +329,7 @@ pub(crate) fn build_impl( cx: &mut DocContext<'_>, parent_module: Option, did: DefId, - attrs: Option>, + attrs: Option<&[ast::Attribute]>, ret: &mut Vec, ) { if !cx.inlined.insert(did.into()) { From cd1a42a95d1fa9b5f67eda4b17b702c9521bf1f4 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 28 Aug 2022 01:39:59 -0400 Subject: [PATCH 21/21] Use the declaration's SourceInfo for FnEntry retags, not the outermost --- compiler/rustc_mir_transform/src/add_retag.rs | 19 ++++++++----------- ...soundness.retags.DeadStoreElimination.diff | 2 +- .../inline/inline_retag.bar.Inline.after.mir | 4 ++-- ...e#0}.SimplifyCfg-elaborate-drops.after.mir | 2 +- ...-foo.SimplifyCfg-elaborate-drops.after.mir | 4 ++-- ..._shr.SimplifyCfg-elaborate-drops.after.mir | 4 ++-- 6 files changed, 16 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs index 9c5896c4e4a..036b5589849 100644 --- a/compiler/rustc_mir_transform/src/add_retag.rs +++ b/compiler/rustc_mir_transform/src/add_retag.rs @@ -66,7 +66,6 @@ impl<'tcx> MirPass<'tcx> for AddRetag { // We need an `AllCallEdges` pass before we can do any work. super::add_call_guards::AllCallEdges.run_pass(tcx, body); - let (span, arg_count) = (body.span, body.arg_count); let basic_blocks = body.basic_blocks.as_mut(); let local_decls = &body.local_decls; let needs_retag = |place: &Place<'tcx>| { @@ -90,20 +89,18 @@ impl<'tcx> MirPass<'tcx> for AddRetag { // PART 1 // Retag arguments at the beginning of the start block. { - // FIXME: Consider using just the span covering the function - // argument declaration. - let source_info = SourceInfo::outermost(span); // Gather all arguments, skip return value. - let places = local_decls - .iter_enumerated() - .skip(1) - .take(arg_count) - .map(|(local, _)| Place::from(local)) - .filter(needs_retag); + let places = local_decls.iter_enumerated().skip(1).take(body.arg_count).filter_map( + |(local, decl)| { + let place = Place::from(local); + needs_retag(&place).then_some((place, decl.source_info)) + }, + ); + // Emit their retags. basic_blocks[START_BLOCK].statements.splice( 0..0, - places.map(|place| Statement { + places.map(|(place, source_info)| Statement { source_info, kind: StatementKind::Retag(RetagKind::FnEntry, Box::new(place)), }), diff --git a/src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff b/src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff index 300f0d5dcaa..b5f98233b3d 100644 --- a/src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff +++ b/src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff @@ -6,7 +6,7 @@ let mut _0: (); // return place in scope 0 at $DIR/provenance_soundness.rs:+0:25: +0:25 bb0: { - Retag([fn entry] _1); // scope 0 at $DIR/provenance_soundness.rs:+0:1: +0:27 + Retag([fn entry] _1); // scope 0 at $DIR/provenance_soundness.rs:+0:11: +0:13 _0 = const (); // scope 0 at $DIR/provenance_soundness.rs:+0:25: +0:27 return; // scope 0 at $DIR/provenance_soundness.rs:+0:27: +0:27 } diff --git a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir index 989fe278586..d5410d3afd4 100644 --- a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir @@ -52,8 +52,8 @@ fn bar() -> bool { Retag(_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 _6 = &(*_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 Retag(_6); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 - Retag(_3); // scope 2 at $DIR/inline-retag.rs:16:1: 18:2 - Retag(_6); // scope 2 at $DIR/inline-retag.rs:16:1: 18:2 + Retag(_3); // scope 2 at $DIR/inline-retag.rs:16:8: 16:9 + Retag(_6); // scope 2 at $DIR/inline-retag.rs:16:17: 16:18 StorageLive(_11); // scope 2 at $DIR/inline-retag.rs:17:5: 17:7 _11 = (*_3); // scope 2 at $DIR/inline-retag.rs:17:5: 17:7 StorageLive(_12); // scope 2 at $DIR/inline-retag.rs:17:11: 17:13 diff --git a/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir index faaacc67ea8..d254a95e06b 100644 --- a/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir @@ -10,7 +10,7 @@ fn main::{closure#0}(_1: &[closure@main::{closure#0}], _2: &i32) -> &i32 { bb0: { Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:31: +0:48 - Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:31: +0:48 + Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:32: +0:33 StorageLive(_3); // scope 0 at $DIR/retag.rs:42:13: 42:15 _3 = _2; // scope 0 at $DIR/retag.rs:42:18: 42:19 Retag(_3); // scope 0 at $DIR/retag.rs:42:18: 42:19 diff --git a/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir index 25d400f0c9f..08fd655ae29 100644 --- a/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir @@ -7,8 +7,8 @@ fn ::foo(_1: &Test, _2: &mut i32) -> &mut i32 let mut _3: &mut i32; // in scope 0 at $DIR/retag.rs:+1:9: +1:10 bb0: { - Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:5: +2:6 - Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:5: +2:6 + Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:16: +0:21 + Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:23: +0:24 StorageLive(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10 _3 = &mut (*_2); // scope 0 at $DIR/retag.rs:+1:9: +1:10 Retag(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10 diff --git a/src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir index 84ad8afc357..f32a84e4c79 100644 --- a/src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir @@ -6,8 +6,8 @@ fn ::foo_shr(_1: &Test, _2: &i32) -> &i32 { let mut _0: &i32; // return place in scope 0 at $DIR/retag.rs:+0:42: +0:49 bb0: { - Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:5: +2:6 - Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:5: +2:6 + Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:20: +0:25 + Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:27: +0:28 _0 = _2; // scope 0 at $DIR/retag.rs:+1:9: +1:10 Retag(_0); // scope 0 at $DIR/retag.rs:+1:9: +1:10 return; // scope 0 at $DIR/retag.rs:+2:6: +2:6