diff options
787 files changed, 8973 insertions, 5939 deletions
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 8040cb22855..d23682596fd 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -18,3 +18,5 @@ b39a1d6f1a30ba29f25d7141038b9a5bf0126e36 f97fddab91fbf290ea5b691fe355d6f915220b6e # format let-else cc907f80b95c6ec530c5ee1b05b044a468f07eca +# format let-chains +b2d2184edea578109a48ec3d8decbee5948e8f35 diff --git a/.mailmap b/.mailmap index 26d6be9f0c6..c109074021d 100644 --- a/.mailmap +++ b/.mailmap @@ -346,7 +346,9 @@ Lindsey Kuper <lindsey@composition.al> <lindsey@rockstargirl.org> Lindsey Kuper <lindsey@composition.al> <lkuper@mozilla.com> Liu Dingming <liudingming@bytedance.com> Loo Maclin <loo.maclin@protonmail.com> -Loïc BRANSTETT <lolo.branstett@numericable.fr> +Urgau <urgau@numericable.fr> +Urgau <urgau@numericable.fr> <lolo.branstett@numericable.fr> +Urgau <urgau@numericable.fr> <3616612+Urgau@users.noreply.github.com> Lucy <luxx4x@protonmail.com> Lukas H. <lukaramu@users.noreply.github.com> Lukas Lueg <lukas.lueg@gmail.com> @@ -445,6 +447,8 @@ Oliver Scherer <oli-obk@users.noreply.github.com> <public.oliver.schneider@kit.e Oliver Scherer <oli-obk@users.noreply.github.com> <oliver.schneider@kit.edu> Oliver Scherer <oli-obk@users.noreply.github.com> <obk8176014uqher834@olio-obk.de> Oliver Scherer <oli-obk@users.noreply.github.com> +Onur Özkan <onurozkan.dev@outlook.com> <work@onurozkan.dev> +Onur Özkan <onurozkan.dev@outlook.com> Ömer Sinan AÄŸacan <omeragacan@gmail.com> Ophir LOJKINE <pere.jobs@gmail.com> Ožbolt Menegatti <ozbolt.menegatti@gmail.com> gareins <ozbolt.menegatti@gmail.com> diff --git a/Cargo.lock b/Cargo.lock index 8bd9b605ddf..c9d5f1744f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2150,9 +2150,9 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" dependencies = [ "rustc-std-workspace-core", ] @@ -2245,9 +2245,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.7" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "litemap" @@ -2418,9 +2418,9 @@ dependencies = [ [[package]] name = "minifier" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb022374af2f446981254e6bf9efb6e2c9e1a53176d395fca02792fd4435729" +checksum = "5394aa376422b4b2b6c02fd9cfcb657e4ec544ae98e43d7d5d785fd0d042fd6d" [[package]] name = "minimal-lexical" @@ -2971,30 +2971,6 @@ dependencies = [ ] [[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4480,6 +4456,7 @@ dependencies = [ name = "rustc_session" version = "0.0.0" dependencies = [ + "bitflags 1.3.2", "getopts", "libc", "rustc_ast", @@ -4779,9 +4756,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.14" +version = "0.38.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" +checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed" dependencies = [ "bitflags 2.4.0", "errno", @@ -5252,24 +5229,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d38d39c754ae037a9bc3ca1580a985db7371cd14f1229172d1db9093feb6739" dependencies = [ "papergrid", - "tabled_derive", "unicode-width", ] [[package]] -name = "tabled_derive" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99f688a08b54f4f02f0a3c382aefdb7884d3d69609f785bd253dc033243e3fe4" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] name = "tar" version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 45b3e76cca6..3722a0774ba 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1,5 +1,7 @@ #![cfg_attr(feature = "nightly", feature(step_trait))] #![cfg_attr(feature = "nightly", allow(internal_features))] +#![cfg_attr(all(not(bootstrap), feature = "nightly"), doc(rust_logo))] +#![cfg_attr(all(not(bootstrap), feature = "nightly"), feature(rustdoc_internals))] use std::fmt; use std::num::{NonZeroUsize, ParseIntError}; @@ -681,6 +683,7 @@ impl fmt::Display for AlignFromBytesError { impl Align { pub const ONE: Align = Align { pow2: 0 }; + // LLVM has a maximal supported alignment of 2^29, we inherit that. pub const MAX: Align = Align { pow2: 29 }; #[inline] diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 7b7078fabbb..be7d1b207bc 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -520,9 +520,7 @@ impl NestedMetaItem { I: Iterator<Item = &'a TokenTree>, { match tokens.peek() { - Some(TokenTree::Token(token, _)) - if let Some(lit) = MetaItemLit::from_token(token) => - { + Some(TokenTree::Token(token, _)) if let Some(lit) = MetaItemLit::from_token(token) => { tokens.next(); return Some(NestedMetaItem::Lit(lit)); } diff --git a/compiler/rustc_ast/src/entry.rs b/compiler/rustc_ast/src/entry.rs index 2dd5e96e513..cd8a5a66920 100644 --- a/compiler/rustc_ast/src/entry.rs +++ b/compiler/rustc_ast/src/entry.rs @@ -21,7 +21,9 @@ pub fn entry_point_type( } else if attr::contains_name(attrs, sym::rustc_main) { EntryPointType::RustcMainAttr } else { - if let Some(name) = name && name == sym::main { + if let Some(name) = name + && name == sym::main + { if at_root { // This is a top-level function so it can be `main`. EntryPointType::MainNamed diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 2de398521f5..dd879a14567 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -107,13 +107,11 @@ impl Lit { /// Keep this in sync with `Token::can_begin_literal_or_bool` excluding unary negation. pub fn from_token(token: &Token) -> Option<Lit> { match token.uninterpolate().kind { - Ident(name, false) if name.is_bool_lit() => { - Some(Lit::new(Bool, name, None)) - } + Ident(name, false) if name.is_bool_lit() => Some(Lit::new(Bool, name, None)), Literal(token_lit) => Some(token_lit), Interpolated(ref nt) if let NtExpr(expr) | NtLiteral(expr) = &**nt - && let ast::ExprKind::Lit(token_lit) = expr.kind => + && let ast::ExprKind::Lit(token_lit) = expr.kind => { Some(token_lit) } @@ -229,35 +227,61 @@ fn ident_can_begin_type(name: Symbol, span: Span, is_raw: bool) -> bool { #[derive(PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] pub enum TokenKind { /* Expression-operator symbols. */ + /// `=` Eq, + /// `<` Lt, + /// `<=` Le, + /// `==` EqEq, + /// `!=` Ne, + /// `>` Ge, + /// `>=` Gt, + /// `&&` AndAnd, + /// `||` OrOr, + /// `!` Not, + /// `~` Tilde, BinOp(BinOpToken), BinOpEq(BinOpToken), /* Structural symbols */ + /// `@` At, + /// `.` Dot, + /// `..` DotDot, + /// `...` DotDotDot, + /// `..=` DotDotEq, + /// `,` Comma, + /// `;` Semi, + /// `:` Colon, + /// `::` ModSep, + /// `->` RArrow, + /// `<-` LArrow, + /// `=>` FatArrow, + /// `#` Pound, + /// `$` Dollar, + /// `?` Question, /// Used by proc macros for representing lifetimes, not generated by lexer right now. SingleQuote, @@ -296,6 +320,7 @@ pub enum TokenKind { /// similarly to symbols in string literal tokens. DocComment(CommentKind, ast::AttrStyle, Symbol), + /// End Of File Eof, } @@ -628,7 +653,9 @@ impl Token { /// Returns `true` if the token is an interpolated path. fn is_path(&self) -> bool { - if let Interpolated(nt) = &self.kind && let NtPath(..) = **nt { + if let Interpolated(nt) = &self.kind + && let NtPath(..) = **nt + { return true; } @@ -650,7 +677,9 @@ impl Token { /// Is the token an interpolated block (`$b:block`)? pub fn is_whole_block(&self) -> bool { - if let Interpolated(nt) = &self.kind && let NtBlock(..) = **nt { + if let Interpolated(nt) = &self.kind + && let NtBlock(..) = **nt + { return true; } diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 1e18b1232de..23b8f9c12d8 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -550,7 +550,9 @@ impl TokenStream { let stream_iter = stream.0.iter().cloned(); - if let Some(first) = stream.0.first() && Self::try_glue_to_last(vec_mut, first) { + if let Some(first) = stream.0.first() + && Self::try_glue_to_last(vec_mut, first) + { // Now skip the first token tree from `stream`. vec_mut.extend(stream_iter.skip(1)); } else { diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index aaeef1ff77d..b9fe99ac72f 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -136,12 +136,6 @@ ast_lowering_template_modifier = template modifier ast_lowering_this_not_async = this is not `async` -ast_lowering_trait_fn_async = - functions in traits cannot be declared `async` - .label = `async` because of this - .note = `async` trait functions are not currently supported - .note2 = consider using the `async-trait` crate: https://crates.io/crates/async-trait - ast_lowering_underscore_expr_lhs_assign = in expressions, `_` can only be used on the left-hand side of an assignment .label = `_` not allowed here diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index a63bd4f8a02..fe0c7d101c1 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -354,17 +354,6 @@ pub struct InclusiveRangeWithNoEnd { pub span: Span, } -#[derive(Diagnostic, Clone, Copy)] -#[diag(ast_lowering_trait_fn_async, code = "E0706")] -#[note] -#[note(ast_lowering_note2)] -pub struct TraitFnAsync { - #[primary_span] - pub fn_span: Span, - #[label] - pub span: Span, -} - #[derive(Diagnostic)] pub enum BadReturnTypeNotation { #[diag(ast_lowering_bad_return_type_notation_inputs)] diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 57c54f8540c..dda23028222 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -673,12 +673,18 @@ impl<'hir> LoweringContext<'_, 'hir> { && let Some(attrs) = self.attrs.get(&outer_hir_id.local_id) && attrs.into_iter().any(|attr| attr.has_name(sym::track_caller)) { - let unstable_span = - self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone()); + let unstable_span = self.mark_span_with_reason( + DesugaringKind::Async, + span, + self.allow_gen_future.clone(), + ); self.lower_attrs( inner_hir_id, &[Attribute { - kind: AttrKind::Normal(ptr::P(NormalAttr::from_ident(Ident::new(sym::track_caller, span)))), + kind: AttrKind::Normal(ptr::P(NormalAttr::from_ident(Ident::new( + sym::track_caller, + span, + )))), id: self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id(), style: AttrStyle::Outer, span: unstable_span, @@ -1102,7 +1108,9 @@ impl<'hir> LoweringContext<'_, 'hir> { if let ExprKind::Path(qself, path) = &expr.kind { // Does the path resolve to something disallowed in a tuple struct/variant pattern? if let Some(partial_res) = self.resolver.get_partial_res(expr.id) { - if let Some(res) = partial_res.full_res() && !res.expected_in_tuple_struct_pat() { + if let Some(res) = partial_res.full_res() + && !res.expected_in_tuple_struct_pat() + { return None; } } @@ -1122,7 +1130,9 @@ impl<'hir> LoweringContext<'_, 'hir> { if let ExprKind::Path(qself, path) = &expr.kind { // Does the path resolve to something disallowed in a unit struct/variant pattern? if let Some(partial_res) = self.resolver.get_partial_res(expr.id) { - if let Some(res) = partial_res.full_res() && !res.expected_in_unit_struct_pat() { + if let Some(res) = partial_res.full_res() + && !res.expected_in_unit_struct_pat() + { return None; } } diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 45a9bebfcf6..c7d0719e71a 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -61,9 +61,12 @@ fn flatten_format_args(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> { let remaining_args = args.split_off(arg_index + 1); let old_arg_offset = args.len(); let mut fmt2 = &mut args.pop().unwrap().expr; // The inner FormatArgs. - let fmt2 = loop { // Unwrap the Expr to get to the FormatArgs. + let fmt2 = loop { + // Unwrap the Expr to get to the FormatArgs. match &mut fmt2.kind { - ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) => fmt2 = inner, + ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) => { + fmt2 = inner + } ExprKind::FormatArgs(fmt2) => break fmt2, _ => unreachable!(), } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 5bfc956aba1..b73f21433e1 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1387,10 +1387,12 @@ impl<'hir> LoweringContext<'_, 'hir> { // Desugar `~const` bound in generics into an additional `const host: bool` param // if the effects feature is enabled. This needs to be done before we lower where // clauses since where clauses need to bind to the DefId of the host param - let host_param_parts = if let Const::Yes(span) = constness && self.tcx.features().effects { - if let Some(param) = generics.params.iter().find(|x| { - x.attrs.iter().any(|x| x.has_name(sym::rustc_host)) - }) { + let host_param_parts = if let Const::Yes(span) = constness + && self.tcx.features().effects + { + if let Some(param) = + generics.params.iter().find(|x| x.attrs.iter().any(|x| x.has_name(sym::rustc_host))) + { // user has manually specified a `rustc_host` param, in this case, we set // the param id so that lowering logic can use that. But we don't create // another host param, so this gives `None`. @@ -1399,7 +1401,12 @@ impl<'hir> LoweringContext<'_, 'hir> { } else { let param_node_id = self.next_node_id(); let hir_id = self.next_id(); - let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span); + let def_id = self.create_def( + self.local_def_id(parent_node_id), + param_node_id, + DefPathData::TypeNs(sym::host), + span, + ); self.host_param_id = Some(def_id); Some((span, hir_id, def_id)) } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 7e3ada9c123..68567f97eab 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -30,6 +30,9 @@ //! get confused if the spans from leaf AST nodes occur in multiple places //! in the HIR, especially for multiple identifiers. +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] #![feature(box_patterns)] #![feature(let_chains)] #![feature(never_type)] @@ -40,7 +43,7 @@ #[macro_use] extern crate tracing; -use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait, TraitFnAsync}; +use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait}; use rustc_ast::ptr::P; use rustc_ast::visit; @@ -271,8 +274,6 @@ enum ImplTraitPosition { ClosureReturn, PointerReturn, FnTraitReturn, - TraitReturn, - ImplReturn, GenericDefault, ConstTy, StaticTy, @@ -302,8 +303,6 @@ impl std::fmt::Display for ImplTraitPosition { ImplTraitPosition::ClosureReturn => "closure return types", ImplTraitPosition::PointerReturn => "`fn` pointer return types", ImplTraitPosition::FnTraitReturn => "`Fn` trait return types", - ImplTraitPosition::TraitReturn => "trait method return types", - ImplTraitPosition::ImplReturn => "`impl` method return types", ImplTraitPosition::GenericDefault => "generic parameter defaults", ImplTraitPosition::ConstTy => "const types", ImplTraitPosition::StaticTy => "static types", @@ -334,20 +333,9 @@ impl FnDeclKind { matches!(self, FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait) } - fn return_impl_trait_allowed(&self, tcx: TyCtxt<'_>) -> bool { + fn return_impl_trait_allowed(&self) -> bool { match self { - FnDeclKind::Fn | FnDeclKind::Inherent => true, - FnDeclKind::Impl if tcx.features().return_position_impl_trait_in_trait => true, - FnDeclKind::Trait if tcx.features().return_position_impl_trait_in_trait => true, - _ => false, - } - } - - fn async_fn_allowed(&self, tcx: TyCtxt<'_>) -> bool { - match self { - FnDeclKind::Fn | FnDeclKind::Inherent => true, - FnDeclKind::Impl if tcx.features().async_fn_in_trait => true, - FnDeclKind::Trait if tcx.features().async_fn_in_trait => true, + FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => true, _ => false, } } @@ -1271,7 +1259,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &PolyTraitRef { bound_generic_params: ThinVec::new(), trait_ref: TraitRef { path: path.clone(), ref_id: t.id }, - span: t.span + span: t.span, }, itctx, ast::Const::No, @@ -1805,53 +1793,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_ty_direct(¶m.ty, &itctx) })); - let output = if let Some((ret_id, span)) = make_ret_async { - if !kind.async_fn_allowed(self.tcx) { - match kind { - FnDeclKind::Trait | FnDeclKind::Impl => { - self.tcx - .sess - .create_feature_err( - TraitFnAsync { fn_span, span }, - sym::async_fn_in_trait, - ) - .emit(); - } - _ => { - self.tcx.sess.emit_err(TraitFnAsync { fn_span, span }); - } - } - } - + let output = if let Some((ret_id, _span)) = make_ret_async { let fn_def_id = self.local_def_id(fn_node_id); self.lower_async_fn_ret_ty(&decl.output, fn_def_id, ret_id, kind, fn_span) } else { match &decl.output { FnRetTy::Ty(ty) => { - let context = if kind.return_impl_trait_allowed(self.tcx) { + let context = if kind.return_impl_trait_allowed() { let fn_def_id = self.local_def_id(fn_node_id); ImplTraitContext::ReturnPositionOpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), fn_kind: kind, } } else { - let position = match kind { - FnDeclKind::Fn | FnDeclKind::Inherent => { - unreachable!("fn should allow in-band lifetimes") + ImplTraitContext::Disallowed(match kind { + FnDeclKind::Fn + | FnDeclKind::Inherent + | FnDeclKind::Trait + | FnDeclKind::Impl => { + unreachable!("fn should allow return-position impl trait in traits") } FnDeclKind::ExternFn => ImplTraitPosition::ExternFnReturn, FnDeclKind::Closure => ImplTraitPosition::ClosureReturn, FnDeclKind::Pointer => ImplTraitPosition::PointerReturn, - FnDeclKind::Trait => ImplTraitPosition::TraitReturn, - FnDeclKind::Impl => ImplTraitPosition::ImplReturn, - }; - match kind { - FnDeclKind::Trait | FnDeclKind::Impl => ImplTraitContext::FeatureGated( - position, - sym::return_position_impl_trait_in_trait, - ), - _ => ImplTraitContext::Disallowed(position), - } + }) }; hir::FnRetTy::Return(self.lower_ty(ty, &context)) } @@ -1924,18 +1889,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let future_bound = this.lower_async_fn_output_type_to_future_bound( output, span, - if let FnDeclKind::Trait = fn_kind - && !this.tcx.features().return_position_impl_trait_in_trait - { - ImplTraitContext::FeatureGated( - ImplTraitPosition::TraitReturn, - sym::return_position_impl_trait_in_trait, - ) - } else { - ImplTraitContext::ReturnPositionOpaqueTy { - origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), - fn_kind, - } + ImplTraitContext::ReturnPositionOpaqueTy { + origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), + fn_kind, }, ); arena_vec![this; future_bound] diff --git a/compiler/rustc_ast_lowering/src/lifetime_collector.rs b/compiler/rustc_ast_lowering/src/lifetime_collector.rs index 6f75419c387..d66bba517e0 100644 --- a/compiler/rustc_ast_lowering/src/lifetime_collector.rs +++ b/compiler/rustc_ast_lowering/src/lifetime_collector.rs @@ -82,7 +82,8 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> { // We can sometimes encounter bare trait objects // which are represented in AST as paths. if let Some(partial_res) = self.resolver.get_partial_res(t.id) - && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res() + && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = + partial_res.full_res() { self.current_binders.push(t.id); visit::walk_ty(self, t); diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 743fad8e865..0477c7b2ba9 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -215,14 +215,15 @@ impl<'a> AstValidator<'a> { } fn visit_struct_field_def(&mut self, field: &'a FieldDef) { - if let Some(ident) = field.ident && - ident.name == kw::Underscore { - self.check_unnamed_field_ty(&field.ty, ident.span); - self.visit_vis(&field.vis); - self.visit_ident(ident); - self.visit_ty_common(&field.ty); - self.walk_ty(&field.ty); - walk_list!(self, visit_attribute, &field.attrs); + if let Some(ident) = field.ident + && ident.name == kw::Underscore + { + self.check_unnamed_field_ty(&field.ty, ident.span); + self.visit_vis(&field.vis); + self.visit_ident(ident); + self.visit_ty_common(&field.ty); + self.walk_ty(&field.ty); + walk_list!(self, visit_attribute, &field.attrs); } else { self.visit_field_def(field); } @@ -291,13 +292,11 @@ impl<'a> AstValidator<'a> { } fn deny_unnamed_field(&self, field: &FieldDef) { - if let Some(ident) = field.ident && - ident.name == kw::Underscore { - self.err_handler() - .emit_err(errors::InvalidUnnamedField { - span: field.span, - ident_span: ident.span - }); + if let Some(ident) = field.ident + && ident.name == kw::Underscore + { + self.err_handler() + .emit_err(errors::InvalidUnnamedField { span: field.span, ident_span: ident.span }); } } @@ -1180,28 +1179,40 @@ impl<'a> Visitor<'a> for AstValidator<'a> { (BoundKind::SuperTraits, TraitBoundModifier::Maybe) => { self.err_handler().emit_err(errors::OptionalTraitSupertrait { span: poly.span, - path_str: pprust::path_to_string(&poly.trait_ref.path) + path_str: pprust::path_to_string(&poly.trait_ref.path), }); } (BoundKind::TraitObject, TraitBoundModifier::Maybe) => { - self.err_handler().emit_err(errors::OptionalTraitObject {span: poly.span}); + self.err_handler().emit_err(errors::OptionalTraitObject { span: poly.span }); } - (_, TraitBoundModifier::MaybeConst) if let Some(reason) = &self.disallow_tilde_const => { + (_, TraitBoundModifier::MaybeConst) + if let Some(reason) = &self.disallow_tilde_const => + { let reason = match reason { - DisallowTildeConstContext::TraitObject => errors::TildeConstReason::TraitObject, - DisallowTildeConstContext::Fn(FnKind::Closure(..)) => errors::TildeConstReason::Closure, - DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => errors::TildeConstReason::Function { ident: ident.span }, + DisallowTildeConstContext::TraitObject => { + errors::TildeConstReason::TraitObject + } + DisallowTildeConstContext::Fn(FnKind::Closure(..)) => { + errors::TildeConstReason::Closure + } + DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => { + errors::TildeConstReason::Function { ident: ident.span } + } }; - self.err_handler().emit_err(errors::TildeConstDisallowed { - span: bound.span(), - reason - }); + self.err_handler() + .emit_err(errors::TildeConstDisallowed { span: bound.span(), reason }); } (_, TraitBoundModifier::MaybeConstMaybe) => { - self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span(), modifier: "?" }); + self.err_handler().emit_err(errors::OptionalConstExclusive { + span: bound.span(), + modifier: "?", + }); } (_, TraitBoundModifier::MaybeConstNegative) => { - self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span(), modifier: "!" }); + self.err_handler().emit_err(errors::OptionalConstExclusive { + span: bound.span(), + modifier: "!", + }); } _ => {} } @@ -1214,7 +1225,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { { for arg in &args.args { if let ast::AngleBracketedArg::Constraint(constraint) = arg { - self.err_handler().emit_err(errors::ConstraintOnNegativeBound { span: constraint.span }); + self.err_handler() + .emit_err(errors::ConstraintOnNegativeBound { span: constraint.span }); } } } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 5d279943f1e..9328b83e8f3 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -658,7 +658,7 @@ fn check_incompatible_features(sess: &Session, features: &Features) { for (f1, f2) in rustc_feature::INCOMPATIBLE_FEATURES .iter() - .filter(|&&(f1, f2)| features.enabled(f1) && features.enabled(f2)) + .filter(|&&(f1, f2)| features.active(f1) && features.active(f2)) { if let Some((f1_name, f1_span)) = declared_features.clone().find(|(name, _)| name == f1) { if let Some((f2_name, f2_span)) = declared_features.clone().find(|(name, _)| name == f2) diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index 7db413c5bbd..5147e672f5f 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -4,6 +4,9 @@ //! //! The crate also contains other misc AST visitors, e.g. `node_count` and `show_span`. +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(iter_is_partitioned)] diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs index bf094af5f7b..475bdb02378 100644 --- a/compiler/rustc_ast_pretty/src/lib.rs +++ b/compiler/rustc_ast_pretty/src/lib.rs @@ -1,3 +1,6 @@ +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] #![feature(associated_type_bounds)] diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 1142d492160..269cb8f2380 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -684,8 +684,8 @@ pub fn reconstruct_format_args_template_string(pieces: &[FormatArgsPiece]) -> St for piece in pieces { match piece { FormatArgsPiece::Literal(s) => { - for c in s.as_str().escape_debug() { - template.push(c); + for c in s.as_str().chars() { + template.extend(c.escape_debug()); if let '{' | '}' = c { template.push(c); } diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 76659458dad..46683d2d258 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -405,7 +405,9 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit } } - if let Some(s) = since && s.as_str() == VERSION_PLACEHOLDER { + if let Some(s) = since + && s.as_str() == VERSION_PLACEHOLDER + { since = Some(rust_version_symbol()); } @@ -694,13 +696,16 @@ pub fn eval_condition( !eval_condition(mis[0].meta_item().unwrap(), sess, features, eval) } sym::target => { - if let Some(features) = features && !features.cfg_target_compact { + if let Some(features) = features + && !features.cfg_target_compact + { feature_err( sess, sym::cfg_target_compact, cfg.span, - "compact `cfg(target(..))` is experimental and subject to change" - ).emit(); + "compact `cfg(target(..))` is experimental and subject to change", + ) + .emit(); } mis.iter().fold(true, |res, mi| { diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs index cfed2acfb3a..53e3eaaab37 100644 --- a/compiler/rustc_attr/src/lib.rs +++ b/compiler/rustc_attr/src/lib.rs @@ -4,6 +4,9 @@ //! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax` //! to this crate. +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] #![feature(let_chains)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] diff --git a/compiler/rustc_baked_icu_data/src/lib.rs b/compiler/rustc_baked_icu_data/src/lib.rs index 4651e03f771..ae8c062d25d 100644 --- a/compiler/rustc_baked_icu_data/src/lib.rs +++ b/compiler/rustc_baked_icu_data/src/lib.rs @@ -19,6 +19,10 @@ //! -k list/and@1 fallback/likelysubtags@1 fallback/parents@1 fallback/supplement/co@1 \ //! --cldr-tag latest --icuexport-tag latest -o src/data //! ``` + +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] #![allow(elided_lifetimes_in_paths)] mod data { diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index ec9bb215f3f..20a4402f6f6 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -351,7 +351,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } // Check if we are in a situation of `ident @ ident` where we want to suggest // `ref ident @ ref ident` or `ref ident @ Struct { ref ident }`. - if let Some(subpat) = sub && self.pat.is_none() { + if let Some(subpat) = sub + && self.pat.is_none() + { self.visit_pat(subpat); if self.pat.is_some() { self.parent_pat = Some(p); @@ -370,7 +372,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let mut finder = ExpressionFinder { expr_span: move_span, expr: None, pat: None, parent_pat: None }; finder.visit_expr(expr); - if let Some(span) = span && let Some(expr) = finder.expr { + if let Some(span) = span + && let Some(expr) = finder.expr + { for (_, expr) in hir.parent_iter(expr.hir_id) { if let hir::Node::Expr(expr) = expr { if expr.span.contains(span) { @@ -425,10 +429,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { Some(hir::intravisit::FnKind::Method(..)) => "method", Some(hir::intravisit::FnKind::Closure) => "closure", }; - span.push_span_label( - ident.span, - format!("in this {descr}"), - ); + span.push_span_label(ident.span, format!("in this {descr}")); err.span_note( span, format!( @@ -441,15 +442,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let ty = place.ty(self.body, self.infcx.tcx).ty; if let hir::Node::Expr(parent_expr) = parent && let hir::ExprKind::Call(call_expr, _) = parent_expr.kind - && let hir::ExprKind::Path( - hir::QPath::LangItem(LangItem::IntoIterIntoIter, _, _) - ) = call_expr.kind + && let hir::ExprKind::Path(hir::QPath::LangItem( + LangItem::IntoIterIntoIter, + _, + _, + )) = call_expr.kind { // Do not suggest `.clone()` in a `for` loop, we already suggest borrowing. - } else if let UseSpans::FnSelfUse { - kind: CallKind::Normal { .. }, - .. - } = move_spans { + } else if let UseSpans::FnSelfUse { kind: CallKind::Normal { .. }, .. } = + move_spans + { // We already suggest cloning for these cases in `explain_captures`. } else { self.suggest_cloning(err, ty, expr, move_span); @@ -602,10 +604,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if self.sugg_span.is_some() { return; } - if let hir::StmtKind::Local(hir::Local { - span, ty, init: None, .. - }) = &ex.kind && span.contains(self.decl_span) { - self.sugg_span = ty.map_or(Some(self.decl_span), |ty| Some(ty.span)); + if let hir::StmtKind::Local(hir::Local { span, ty, init: None, .. }) = &ex.kind + && span.contains(self.decl_span) + { + self.sugg_span = ty.map_or(Some(self.decl_span), |ty| Some(ty.span)); } hir::intravisit::walk_stmt(self, ex); } @@ -743,19 +745,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ".clone()".to_owned() }; if let Some(clone_trait_def) = tcx.lang_items().clone_trait() - && self.infcx - .type_implements_trait( - clone_trait_def, - [ty], - self.param_env, - ) + && self + .infcx + .type_implements_trait(clone_trait_def, [ty], self.param_env) .must_apply_modulo_regions() { let msg = if let ty::Adt(def, _) = ty.kind() - && [ - tcx.get_diagnostic_item(sym::Arc), - tcx.get_diagnostic_item(sym::Rc), - ].contains(&Some(def.did())) + && [tcx.get_diagnostic_item(sym::Arc), tcx.get_diagnostic_item(sym::Rc)] + .contains(&Some(def.did())) { "clone the value to increment its reference count" } else { @@ -1350,9 +1347,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // }; // corresponding to the desugaring of a for loop `for <pat> in <head> { <body> }`. if let hir::ExprKind::Call(path, [arg]) = ex.kind - && let hir::ExprKind::Path( - hir::QPath::LangItem(LangItem::IntoIterIntoIter, _, _), - ) = path.kind + && let hir::ExprKind::Path(hir::QPath::LangItem( + LangItem::IntoIterIntoIter, + _, + _, + )) = path.kind && arg.span.contains(self.issue_span) { // Find `IntoIterator::into_iter(<head>)` @@ -1370,18 +1369,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .. }) = stmt.kind && let hir::ExprKind::Call(path, _args) = call.kind - && let hir::ExprKind::Path( - hir::QPath::LangItem(LangItem::IteratorNext, _, _), - ) = path.kind + && let hir::ExprKind::Path(hir::QPath::LangItem(LangItem::IteratorNext, _, _)) = + path.kind && let hir::PatKind::Struct(path, [field, ..], _) = bind.pat.kind && let hir::QPath::LangItem(LangItem::OptionSome, pat_span, _) = path && call.span.contains(self.issue_span) { // Find `<pat>` and the span for the whole `for` loop. - if let PatField { pat: hir::Pat { - kind: hir::PatKind::Binding(_, _, ident, ..), + if let PatField { + pat: hir::Pat { kind: hir::PatKind::Binding(_, _, ident, ..), .. }, .. - }, ..} = field { + } = field + { self.loop_bind = Some(ident); } self.head_span = Some(*head_span); @@ -1441,18 +1440,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // A bare path doesn't need a `let` assignment, it's already a simple // binding access. // As a new binding wasn't added, we don't need to modify the advancing call. - sugg.push(( - loop_span.with_hi(pat_span.lo()), - format!("while let Some("), - )); + sugg.push((loop_span.with_hi(pat_span.lo()), format!("while let Some("))); sugg.push(( pat_span.shrink_to_hi().with_hi(head.span.lo()), ") = ".to_string(), )); - sugg.push(( - head.span.shrink_to_hi(), - ".next()".to_string(), - )); + sugg.push((head.span.shrink_to_hi(), ".next()".to_string())); } else { // Needs a new a `let` binding. let indent = if let Some(indent) = sm.indentation_before(loop_span) { @@ -1483,11 +1476,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { sugg.push((recv.span, "iter".to_string())); } } - err.multipart_suggestion( - msg, - sugg, - Applicability::MaybeIncorrect, - ); + err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect); } else { err.help(msg); } @@ -1666,69 +1655,80 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) { if e.span.contains(self.capture_span) { if let hir::ExprKind::Closure(&hir::Closure { - movability: None, - body, - fn_arg_span, - fn_decl: hir::FnDecl{ inputs, .. }, - .. - }) = e.kind && - let Some(hir::Node::Expr(body )) = self.hir.find(body.hir_id) { - self.suggest_arg = "this: &Self".to_string(); - if inputs.len() > 0 { - self.suggest_arg.push_str(", "); - } - self.in_closure = true; - self.closure_arg_span = fn_arg_span; - self.visit_expr(body); - self.in_closure = false; + movability: None, + body, + fn_arg_span, + fn_decl: hir::FnDecl { inputs, .. }, + .. + }) = e.kind + && let Some(hir::Node::Expr(body)) = self.hir.find(body.hir_id) + { + self.suggest_arg = "this: &Self".to_string(); + if inputs.len() > 0 { + self.suggest_arg.push_str(", "); + } + self.in_closure = true; + self.closure_arg_span = fn_arg_span; + self.visit_expr(body); + self.in_closure = false; } } if let hir::Expr { kind: hir::ExprKind::Path(path), .. } = e { - if let hir::QPath::Resolved(_, hir::Path { segments: [seg], ..}) = path && - seg.ident.name == kw::SelfLower && self.in_closure { - self.closure_change_spans.push(e.span); + if let hir::QPath::Resolved(_, hir::Path { segments: [seg], .. }) = path + && seg.ident.name == kw::SelfLower + && self.in_closure + { + self.closure_change_spans.push(e.span); } } hir::intravisit::walk_expr(self, e); } fn visit_local(&mut self, local: &'hir hir::Local<'hir>) { - if let hir::Pat { kind: hir::PatKind::Binding(_, hir_id, _ident, _), .. } = local.pat && - let Some(init) = local.init + if let hir::Pat { kind: hir::PatKind::Binding(_, hir_id, _ident, _), .. } = + local.pat + && let Some(init) = local.init { - if let hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { - movability: None, - .. - }), .. } = init && - init.span.contains(self.capture_span) { - self.closure_local_id = Some(*hir_id); + if let hir::Expr { + kind: hir::ExprKind::Closure(&hir::Closure { movability: None, .. }), + .. + } = init + && init.span.contains(self.capture_span) + { + self.closure_local_id = Some(*hir_id); } } hir::intravisit::walk_local(self, local); } fn visit_stmt(&mut self, s: &'hir hir::Stmt<'hir>) { - if let hir::StmtKind::Semi(e) = s.kind && - let hir::ExprKind::Call(hir::Expr { kind: hir::ExprKind::Path(path), ..}, args) = e.kind && - let hir::QPath::Resolved(_, hir::Path { segments: [seg], ..}) = path && - let Res::Local(hir_id) = seg.res && - Some(hir_id) == self.closure_local_id { - let (span, arg_str) = if args.len() > 0 { - (args[0].span.shrink_to_lo(), "self, ".to_string()) - } else { - let span = e.span.trim_start(seg.ident.span).unwrap_or(e.span); - (span, "(self)".to_string()) - }; - self.closure_call_changes.push((span, arg_str)); + if let hir::StmtKind::Semi(e) = s.kind + && let hir::ExprKind::Call( + hir::Expr { kind: hir::ExprKind::Path(path), .. }, + args, + ) = e.kind + && let hir::QPath::Resolved(_, hir::Path { segments: [seg], .. }) = path + && let Res::Local(hir_id) = seg.res + && Some(hir_id) == self.closure_local_id + { + let (span, arg_str) = if args.len() > 0 { + (args[0].span.shrink_to_lo(), "self, ".to_string()) + } else { + let span = e.span.trim_start(seg.ident.span).unwrap_or(e.span); + (span, "(self)".to_string()) + }; + self.closure_call_changes.push((span, arg_str)); } hir::intravisit::walk_stmt(self, s); } } - if let Some(hir::Node::ImplItem( - hir::ImplItem { kind: hir::ImplItemKind::Fn(_fn_sig, body_id), .. } - )) = hir.find(self.mir_hir_id()) && - let Some(hir::Node::Expr(expr)) = hir.find(body_id.hir_id) { + if let Some(hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Fn(_fn_sig, body_id), + .. + })) = hir.find(self.mir_hir_id()) + && let Some(hir::Node::Expr(expr)) = hir.find(body_id.hir_id) + { let mut finder = ExpressionFinder { capture_span: *capture_kind_span, closure_change_spans: vec![], @@ -2299,15 +2299,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { visitor.visit_stmt(stmt); let typeck_results = self.infcx.tcx.typeck(self.mir_def_id()); - let expr_ty: Option<Ty<'_>> = visitor.prop_expr.map(|expr| typeck_results.expr_ty(expr).peel_refs()); - - let is_format_arguments_item = - if let Some(expr_ty) = expr_ty - && let ty::Adt(adt, _) = expr_ty.kind() { - self.infcx.tcx.lang_items().get(LangItem::FormatArguments) == Some(adt.did()) - } else { - false - }; + let expr_ty: Option<Ty<'_>> = + visitor.prop_expr.map(|expr| typeck_results.expr_ty(expr).peel_refs()); + + let is_format_arguments_item = if let Some(expr_ty) = expr_ty + && let ty::Adt(adt, _) = expr_ty.kind() + { + self.infcx.tcx.lang_items().get(LangItem::FormatArguments) + == Some(adt.did()) + } else { + false + }; if visitor.found == 0 && stmt.span.contains(proper_span) diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index c66a2447356..c9514f5604c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -76,10 +76,10 @@ impl<'tcx> BorrowExplanation<'tcx> { expr_finder.visit_expr(body.value); if let Some(mut expr) = expr_finder.result { while let hir::ExprKind::AddrOf(_, _, inner) - | hir::ExprKind::Unary(hir::UnOp::Deref, inner) - | hir::ExprKind::Field(inner, _) - | hir::ExprKind::MethodCall(_, inner, _, _) - | hir::ExprKind::Index(inner, _, _) = &expr.kind + | hir::ExprKind::Unary(hir::UnOp::Deref, inner) + | hir::ExprKind::Field(inner, _) + | hir::ExprKind::MethodCall(_, inner, _, _) + | hir::ExprKind::Index(inner, _, _) = &expr.kind { expr = inner; } @@ -88,10 +88,7 @@ impl<'tcx> BorrowExplanation<'tcx> { && let hir::def::Res::Local(hir_id) = p.res && let Some(hir::Node::Pat(pat)) = tcx.hir().find(hir_id) { - err.span_label( - pat.span, - format!("binding `{ident}` declared here"), - ); + err.span_label(pat.span, format!("binding `{ident}` declared here")); } } } @@ -419,7 +416,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if self.local_names[local].is_some() && let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place && let Some(borrowed_local) = place.as_local() - && self.local_names[borrowed_local].is_some() && local != borrowed_local + && self.local_names[borrowed_local].is_some() + && local != borrowed_local { should_note_order = true; } diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index c3cf7db32b1..8f5d5e67a7a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -780,19 +780,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt); if let StatementKind::Assign(box (_, Rvalue::Aggregate(kind, places))) = &stmt.kind - && let AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) = **kind + && let AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) = + **kind { debug!("move_spans: def_id={:?} places={:?}", def_id, places); let def_id = def_id.expect_local(); if let Some((args_span, generator_kind, capture_kind_span, path_span)) = self.closure_span(def_id, moved_place, places) { - return ClosureUse { - generator_kind, - args_span, - capture_kind_span, - path_span, - }; + return ClosureUse { generator_kind, args_span, capture_kind_span, path_span }; } } @@ -1123,7 +1119,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &self.infcx.tcx.sess.parse_sess.span_diagnostic, CaptureReasonSuggest::FreshReborrow { span: move_span.shrink_to_hi(), - }); + }, + ); } if let Some(clone_trait) = tcx.lang_items().clone_trait() && let trait_ref = ty::TraitRef::new(tcx, clone_trait, [ty]) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index e6bde6a8c54..e5ffc8a1114 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -396,17 +396,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let upvar_hir_id = captured_place.get_root_variable(); if let Some(Node::Pat(pat)) = self.infcx.tcx.hir().find(upvar_hir_id) - && let hir::PatKind::Binding( - hir::BindingAnnotation::NONE, - _, - upvar_ident, - _, - ) = pat.kind + && let hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, upvar_ident, _) = + pat.kind { if upvar_ident.name == kw::SelfLower { for (_, node) in self.infcx.tcx.hir().parent_iter(upvar_hir_id) { if let Some(fn_decl) = node.fn_decl() { - if !matches!(fn_decl.implicit_self, hir::ImplicitSelfKind::ImmRef | hir::ImplicitSelfKind::MutRef) { + if !matches!( + fn_decl.implicit_self, + hir::ImplicitSelfKind::ImmRef | hir::ImplicitSelfKind::MutRef + ) { err.span_suggestion( upvar_ident.span, "consider changing this to be mutable", @@ -573,7 +572,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { self.ty, ), vec![ - vec![ // val.insert(index, rv); + vec![ + // val.insert(index, rv); ( val.span.shrink_to_hi().with_hi(index.span.lo()), ".insert(".to_string(), @@ -584,7 +584,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ), (rv.span.shrink_to_hi(), ")".to_string()), ], - vec![ // val.get_mut(index).map(|v| { *v = rv; }); + vec![ + // val.get_mut(index).map(|v| { *v = rv; }); ( val.span.shrink_to_hi().with_hi(index.span.lo()), ".get_mut(".to_string(), @@ -593,12 +594,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { index.span.shrink_to_hi().with_hi(place.span.hi()), ").map(|val| { *val".to_string(), ), - ( - rv.span.shrink_to_hi(), - "; })".to_string(), - ), + (rv.span.shrink_to_hi(), "; })".to_string()), ], - vec![ // let x = val.entry(index).or_insert(rv); + vec![ + // let x = val.entry(index).or_insert(rv); (val.span.shrink_to_lo(), "let val = ".to_string()), ( val.span.shrink_to_hi().with_hi(index.span.lo()), @@ -747,10 +746,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { && let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id) { let body = hir_map.body(body_id); - let mut v = BindingFinder { - span: pat_span, - hir_id: None, - }; + let mut v = BindingFinder { span: pat_span, hir_id: None }; v.visit_body(body); v.hir_id } else { @@ -766,7 +762,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. }, .. })) = hir_map.find(hir_id) - && let Ok(name) = self.infcx.tcx.sess.source_map().span_to_snippet(local_decl.source_info.span) + && let Ok(name) = + self.infcx.tcx.sess.source_map().span_to_snippet(local_decl.source_info.span) { err.span_suggestion( pat_span, @@ -879,12 +876,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // `span` corresponds to the expression being iterated, find the `for`-loop desugared // expression with that span in order to identify potential fixes when encountering a // read-only iterator that should be mutable. - let mut v = Finder { - span, - expr: None, - }; + let mut v = Finder { span, expr: None }; v.visit_block(block); - if let Some(expr) = v.expr && let Call(_, [expr]) = expr.kind { + if let Some(expr) = v.expr + && let Call(_, [expr]) = expr.kind + { match expr.kind { MethodCall(path_segment, _, _, span) => { // We have `for _ in iter.read_only_iter()`, try to @@ -1032,38 +1028,42 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let source = self.body.source; let hir = self.infcx.tcx.hir(); if let InstanceDef::Item(def_id) = source.instance - && let Some(Node::Expr(hir::Expr { hir_id, kind, ..})) = hir.get_if_local(def_id) - && let ExprKind::Closure(closure) = kind && closure.movability == None - && let Some(Node::Expr(expr)) = hir.find_parent(*hir_id) { - let mut cur_expr = expr; - while let ExprKind::MethodCall(path_segment, recv, _, _) = cur_expr.kind { - if path_segment.ident.name == sym::iter { - // check `_ty` has `iter_mut` method - let res = self - .infcx - .tcx - .typeck(path_segment.hir_id.owner.def_id) - .type_dependent_def_id(cur_expr.hir_id) - .and_then(|def_id| self.infcx.tcx.impl_of_method(def_id)) - .map(|def_id| self.infcx.tcx.associated_items(def_id)) - .map(|assoc_items| { - assoc_items.filter_by_name_unhygienic(sym::iter_mut).peekable() - }); - - if let Some(mut res) = res && res.peek().is_some() { - err.span_suggestion_verbose( - path_segment.ident.span, - "you may want to use `iter_mut` here", - "iter_mut", - Applicability::MaybeIncorrect, - ); - } - break; - } else { - cur_expr = recv; + && let Some(Node::Expr(hir::Expr { hir_id, kind, .. })) = hir.get_if_local(def_id) + && let ExprKind::Closure(closure) = kind + && closure.movability == None + && let Some(Node::Expr(expr)) = hir.find_parent(*hir_id) + { + let mut cur_expr = expr; + while let ExprKind::MethodCall(path_segment, recv, _, _) = cur_expr.kind { + if path_segment.ident.name == sym::iter { + // check `_ty` has `iter_mut` method + let res = self + .infcx + .tcx + .typeck(path_segment.hir_id.owner.def_id) + .type_dependent_def_id(cur_expr.hir_id) + .and_then(|def_id| self.infcx.tcx.impl_of_method(def_id)) + .map(|def_id| self.infcx.tcx.associated_items(def_id)) + .map(|assoc_items| { + assoc_items.filter_by_name_unhygienic(sym::iter_mut).peekable() + }); + + if let Some(mut res) = res + && res.peek().is_some() + { + err.span_suggestion_verbose( + path_segment.ident.span, + "you may want to use `iter_mut` here", + "iter_mut", + Applicability::MaybeIncorrect, + ); } + break; + } else { + cur_expr = recv; } } + } } fn suggest_make_local_mut( @@ -1200,14 +1200,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } let hir_map = self.infcx.tcx.hir(); let def_id = self.body.source.def_id(); - let hir_id = if let Some(local_def_id) = def_id.as_local() && - let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id) + let hir_id = if let Some(local_def_id) = def_id.as_local() + && let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id) { let body = hir_map.body(body_id); - let mut v = BindingFinder { - span: err_label_span, - hir_id: None, - }; + let mut v = BindingFinder { span: err_label_span, hir_id: None }; v.visit_body(body); v.hir_id } else { @@ -1215,15 +1212,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }; if let Some(hir_id) = hir_id - && let Some(hir::Node::Local(local)) = hir_map.find(hir_id) + && let Some(hir::Node::Local(local)) = hir_map.find(hir_id) { let (changing, span, sugg) = match local.ty { Some(ty) => ("changing", ty.span, message), - None => ( - "specifying", - local.pat.span.shrink_to_hi(), - format!(": {message}"), - ), + None => { + ("specifying", local.pat.span.shrink_to_hi(), format!(": {message}")) + } }; err.span_suggestion_verbose( span, @@ -1234,9 +1229,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } else { err.span_label( err_label_span, - format!( - "consider changing this binding's type to be: `{message}`" - ), + format!("consider changing this binding's type to be: `{message}`"), ); } } @@ -1380,11 +1373,7 @@ fn suggest_ampmut<'tcx>( let ty_mut = decl_ty.builtin_deref(true).unwrap(); assert_eq!(ty_mut.mutbl, hir::Mutability::Not); - ( - false, - span, - format!("{}mut {}", if decl_ty.is_ref() {"&"} else {"*"}, ty_mut.ty) - ) + (false, span, format!("{}mut {}", if decl_ty.is_ref() { "&" } else { "*" }, ty_mut.ty)) } } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 55d581b3ab1..f8883c53d57 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -942,9 +942,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ty::ClauseKind::Projection(data) if data.projection_ty.self_ty() == ty => {} _ => return false, } - tcx.any_free_region_meets(pred, |r| { - *r == ty::ReEarlyBound(region) - }) + tcx.any_free_region_meets(pred, |r| *r == ty::ReEarlyBound(region)) }) } else { false diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 9c77767e7a7..d274a3eea6c 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1,5 +1,8 @@ //! This query borrow-checks the MIR to (further) ensure it is not broken. +#![allow(internal_features)] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] #![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(let_chains)] @@ -11,7 +14,6 @@ #![feature(trusted_step)] #![feature(try_blocks)] #![recursion_limit = "256"] -#![allow(internal_features)] #[macro_use] extern crate rustc_middle; @@ -173,7 +175,9 @@ fn do_mir_borrowck<'tcx>( for var_debug_info in &input_body.var_debug_info { if let VarDebugInfoContents::Place(place) = var_debug_info.value { if let Some(local) = place.as_local() { - if let Some(prev_name) = local_names[local] && var_debug_info.name != prev_name { + if let Some(prev_name) = local_names[local] + && var_debug_info.name != prev_name + { span_bug!( var_debug_info.source_info.span, "local {:?} has many names (`{}` vs `{}`)", diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index ff04b0237c2..ee554370305 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -1,5 +1,6 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::ErrorGuaranteed; +use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_hir::OpaqueTyOrigin; use rustc_infer::infer::InferCtxt; @@ -308,20 +309,19 @@ fn check_opaque_type_well_formed<'tcx>( return Ok(definition_ty); }; let param_env = tcx.param_env(def_id); - // HACK This bubble is required for this tests to pass: - // nested-return-type2-tait2.rs - // nested-return-type2-tait3.rs + + let mut parent_def_id = def_id; + while tcx.def_kind(parent_def_id) == DefKind::OpaqueTy { + parent_def_id = tcx.local_parent(parent_def_id); + } + // FIXME(-Ztrait-solver=next): We probably should use `DefiningAnchor::Error` // and prepopulate this `InferCtxt` with known opaque values, rather than // using the `Bind` anchor here. For now it's fine. let infcx = tcx .infer_ctxt() .with_next_trait_solver(next_trait_solver) - .with_opaque_type_inference(if next_trait_solver { - DefiningAnchor::Bind(def_id) - } else { - DefiningAnchor::Bubble - }) + .with_opaque_type_inference(DefiningAnchor::Bind(parent_def_id)) .build(); let ocx = ObligationCtxt::new(&infcx); let identity_args = GenericArgs::identity_for_item(tcx, def_id); diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index b7adc314f07..fc600af1b76 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -49,7 +49,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // If the query has created new universes and errors are going to be emitted, register the // cause of these new universes for improved diagnostics. let universe = self.infcx.universe(); - if old_universe != universe && let Some(error_info) = error_info { + if old_universe != universe + && let Some(error_info) = error_info + { let universe_info = error_info.to_universe_info(old_universe); for u in (old_universe + 1)..=universe { self.borrowck_context.constraints.universe_causes.insert(u, universe_info.clone()); diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index 82bae9157e7..070d50708ff 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -21,20 +21,22 @@ pub fn expand( // Allow using `#[alloc_error_handler]` on an item statement // FIXME - if we get deref patterns, use them to reduce duplication here - let (item, is_stmt, sig_span) = - if let Annotatable::Item(item) = &item - && let ItemKind::Fn(fn_kind) = &item.kind - { - (item, false, ecx.with_def_site_ctxt(fn_kind.sig.span)) - } else if let Annotatable::Stmt(stmt) = &item - && let StmtKind::Item(item) = &stmt.kind - && let ItemKind::Fn(fn_kind) = &item.kind - { - (item, true, ecx.with_def_site_ctxt(fn_kind.sig.span)) - } else { - ecx.sess.parse_sess.span_diagnostic.emit_err(errors::AllocErrorMustBeFn {span: item.span() }); - return vec![orig_item]; - }; + let (item, is_stmt, sig_span) = if let Annotatable::Item(item) = &item + && let ItemKind::Fn(fn_kind) = &item.kind + { + (item, false, ecx.with_def_site_ctxt(fn_kind.sig.span)) + } else if let Annotatable::Stmt(stmt) = &item + && let StmtKind::Item(item) = &stmt.kind + && let ItemKind::Fn(fn_kind) = &item.kind + { + (item, true, ecx.with_def_site_ctxt(fn_kind.sig.span)) + } else { + ecx.sess + .parse_sess + .span_diagnostic + .emit_err(errors::AllocErrorMustBeFn { span: item.span() }); + return vec![orig_item]; + }; // Generate a bunch of new items using the AllocFnFactory let span = ecx.with_def_site_ctxt(item.span); diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index 0682d48aca6..6733b9e56ad 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -193,10 +193,9 @@ impl<'cx, 'a> Context<'cx, 'a> { fn manage_cond_expr(&mut self, expr: &mut P<Expr>) { match &mut expr.kind { ExprKind::AddrOf(_, mutability, local_expr) => { - self.with_is_consumed_management( - matches!(mutability, Mutability::Mut), - |this| this.manage_cond_expr(local_expr) - ); + self.with_is_consumed_management(matches!(mutability, Mutability::Mut), |this| { + this.manage_cond_expr(local_expr) + }); } ExprKind::Array(local_exprs) => { for local_expr in local_exprs { @@ -223,7 +222,7 @@ impl<'cx, 'a> Context<'cx, 'a> { |this| { this.manage_cond_expr(lhs); this.manage_cond_expr(rhs); - } + }, ); } ExprKind::Call(_, local_exprs) => { @@ -285,10 +284,9 @@ impl<'cx, 'a> Context<'cx, 'a> { } } ExprKind::Unary(un_op, local_expr) => { - self.with_is_consumed_management( - matches!(un_op, UnOp::Neg | UnOp::Not), - |this| this.manage_cond_expr(local_expr) - ); + self.with_is_consumed_management(matches!(un_op, UnOp::Neg | UnOp::Not), |this| { + this.manage_cond_expr(local_expr) + }); } // Expressions that are not worth or can not be captured. // diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs index 9695fb4fee1..6b8330bfdaf 100644 --- a/compiler/rustc_builtin_macros/src/concat.rs +++ b/compiler/rustc_builtin_macros/src/concat.rs @@ -33,7 +33,7 @@ pub fn expand_concat( accumulator.push_str(&b.to_string()); } Ok(ast::LitKind::CStr(..)) => { - cx.emit_err(errors::ConcatCStrLit{ span: e.span}); + cx.emit_err(errors::ConcatCStrLit { span: e.span }); has_errors = true; } Ok(ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..)) => { @@ -49,7 +49,9 @@ pub fn expand_concat( } }, // We also want to allow negative numeric literals. - ast::ExprKind::Unary(ast::UnOp::Neg, ref expr) if let ast::ExprKind::Lit(token_lit) = expr.kind => { + ast::ExprKind::Unary(ast::UnOp::Neg, ref expr) + if let ast::ExprKind::Lit(token_lit) = expr.kind => + { match ast::LitKind::from_token_lit(token_lit) { Ok(ast::LitKind::Int(i, _)) => accumulator.push_str(&format!("-{i}")), Ok(ast::LitKind::Float(f, _)) => accumulator.push_str(&format!("-{f}")), diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs index 6a1586f071c..c4f5af384c1 100644 --- a/compiler/rustc_builtin_macros/src/concat_bytes.rs +++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs @@ -140,8 +140,8 @@ pub fn expand_concat_bytes( } ast::ExprKind::Repeat(expr, count) => { if let ast::ExprKind::Lit(token_lit) = count.value.kind - && let Ok(ast::LitKind::Int(count_val, _)) = - ast::LitKind::from_token_lit(token_lit) + && let Ok(ast::LitKind::Int(count_val, _)) = + ast::LitKind::from_token_lit(token_lit) { if let Some(elem) = handle_array_element(cx, &mut has_errors, &mut missing_literals, expr) @@ -151,7 +151,7 @@ pub fn expand_concat_bytes( } } } else { - cx.emit_err(errors::ConcatBytesBadRepeat {span: count.value.span }); + cx.emit_err(errors::ConcatBytesBadRepeat { span: count.value.span }); } } &ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) { diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index b468abe3249..1649cc76c8d 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -106,7 +106,9 @@ fn cs_clone_simple( // This basic redundancy checking only prevents duplication of // assertions like `AssertParamIsClone<Foo>` where the type is a // simple name. That's enough to get a lot of cases, though. - if let Some(name) = field.ty.kind.is_simple_path() && !seen_type_names.insert(name) { + if let Some(name) = field.ty.kind.is_simple_path() + && !seen_type_names.insert(name) + { // Already produced an assertion for this type. } else { // let _: AssertParamIsClone<FieldTy>; diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index a000e4895d1..8a6d219379f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs @@ -73,7 +73,9 @@ fn cs_total_eq_assert( // This basic redundancy checking only prevents duplication of // assertions like `AssertParamIsEq<Foo>` where the type is a // simple name. That's enough to get a lot of cases, though. - if let Some(name) = field.ty.kind.is_simple_path() && !seen_type_names.insert(name) { + if let Some(name) = field.ty.kind.is_simple_path() + && !seen_type_names.insert(name) + { // Already produced an assertion for this type. } else { // let _: AssertParamIsEq<FieldTy>; diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs index a5b3a504e38..f3164bd2c2a 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs @@ -21,25 +21,26 @@ pub fn expand_deriving_partial_ord( // Order in which to perform matching let tag_then_data = if let Annotatable::Item(item) = item - && let ItemKind::Enum(def, _) = &item.kind { - let dataful: Vec<bool> = def.variants.iter().map(|v| !v.data.fields().is_empty()).collect(); - match dataful.iter().filter(|&&b| b).count() { - // No data, placing the tag check first makes codegen simpler - 0 => true, - 1..=2 => false, - _ => { - (0..dataful.len()-1).any(|i| { - if dataful[i] && let Some(idx) = dataful[i+1..].iter().position(|v| *v) { - idx >= 2 - } else { - false - } - }) + && let ItemKind::Enum(def, _) = &item.kind + { + let dataful: Vec<bool> = def.variants.iter().map(|v| !v.data.fields().is_empty()).collect(); + match dataful.iter().filter(|&&b| b).count() { + // No data, placing the tag check first makes codegen simpler + 0 => true, + 1..=2 => false, + _ => (0..dataful.len() - 1).any(|i| { + if dataful[i] + && let Some(idx) = dataful[i + 1..].iter().position(|v| *v) + { + idx >= 2 + } else { + false } - } - } else { - true - }; + }), + } + } else { + true + }; let partial_cmp_def = MethodDef { name: sym::partial_cmp, generics: Bounds::empty(), @@ -133,12 +134,16 @@ fn cs_partial_cmp( if !tag_then_data && let ExprKind::Match(_, arms) = &mut expr1.kind && let Some(last) = arms.last_mut() - && let PatKind::Wild = last.pat.kind { - last.body = expr2; - expr1 + && let PatKind::Wild = last.pat.kind + { + last.body = expr2; + expr1 } else { - let eq_arm = - cx.arm(span, cx.pat_some(span, cx.pat_path(span, equal_path.clone())), expr1); + let eq_arm = cx.arm( + span, + cx.pat_some(span, cx.pat_path(span, equal_path.clone())), + expr1, + ); let neq_arm = cx.arm(span, cx.pat_ident(span, test_id), cx.expr_ident(span, test_id)); cx.expr_match(span, expr2, thin_vec![eq_arm, neq_arm]) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 8397b5e4221..4b5c777f4ad 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -73,7 +73,9 @@ fn parse_args<'a>(ecx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult< let first_token = &p.token; - let fmtstr = if let token::Literal(lit) = first_token.kind && matches!(lit.kind, token::Str | token::StrRaw(_)) { + let fmtstr = if let token::Literal(lit) = first_token.kind + && matches!(lit.kind, token::Str | token::StrRaw(_)) + { // This allows us to properly handle cases when the first comma // after the format string is mistakenly replaced with any operator, // which cause the expression parser to eat too much tokens. @@ -176,7 +178,7 @@ fn make_format_args( && block.stmts.len() == 1 && let StmtKind::Expr(expr) = &block.stmts[0].kind && let ExprKind::Path(None, path) = &expr.kind - && path.is_potential_trivial_const_arg() + && path.is_potential_trivial_const_arg() { err.multipart_suggestion( "quote your inlined format argument to use as string literal", @@ -184,7 +186,7 @@ fn make_format_args( (unexpanded_fmt_span.shrink_to_hi(), "\"".to_string()), (unexpanded_fmt_span.shrink_to_lo(), "\"".to_string()), ], - Applicability::MaybeIncorrect, + Applicability::MaybeIncorrect, ); } else { let sugg_fmt = match args.explicit_args().len() { @@ -257,8 +259,13 @@ fn make_format_args( if let Some(note) = err.note { e.note_ = Some(errors::InvalidFormatStringNote { note }); } - if let Some((label, span)) = err.secondary_label && is_source_literal { - e.label_ = Some(errors::InvalidFormatStringLabel { span: fmt_span.from_inner(InnerSpan::new(span.start, span.end)), label } ); + if let Some((label, span)) = err.secondary_label + && is_source_literal + { + e.label_ = Some(errors::InvalidFormatStringLabel { + span: fmt_span.from_inner(InnerSpan::new(span.start, span.end)), + label, + }); } match err.suggestion { parse::Suggestion::None => {} diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 1bec00add55..33392edf060 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -24,20 +24,22 @@ pub fn expand( // Allow using `#[global_allocator]` on an item statement // FIXME - if we get deref patterns, use them to reduce duplication here - let (item, is_stmt, ty_span) = - if let Annotatable::Item(item) = &item - && let ItemKind::Static(box ast::StaticItem { ty, ..}) = &item.kind - { - (item, false, ecx.with_def_site_ctxt(ty.span)) - } else if let Annotatable::Stmt(stmt) = &item - && let StmtKind::Item(item) = &stmt.kind - && let ItemKind::Static(box ast::StaticItem { ty, ..}) = &item.kind - { - (item, true, ecx.with_def_site_ctxt(ty.span)) - } else { - ecx.sess.parse_sess.span_diagnostic.emit_err(errors::AllocMustStatics{span: item.span()}); - return vec![orig_item]; - }; + let (item, is_stmt, ty_span) = if let Annotatable::Item(item) = &item + && let ItemKind::Static(box ast::StaticItem { ty, .. }) = &item.kind + { + (item, false, ecx.with_def_site_ctxt(ty.span)) + } else if let Annotatable::Stmt(stmt) = &item + && let StmtKind::Item(item) = &stmt.kind + && let ItemKind::Static(box ast::StaticItem { ty, .. }) = &item.kind + { + (item, true, ecx.with_def_site_ctxt(ty.span)) + } else { + ecx.sess + .parse_sess + .span_diagnostic + .emit_err(errors::AllocMustStatics { span: item.span() }); + return vec![orig_item]; + }; // Generate a bunch of new items using the AllocFnFactory let span = ecx.with_def_site_ctxt(item.span); diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index ebf1448f55c..d84742c9b82 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -1,6 +1,9 @@ //! This crate contains implementations of built-in macros and other code generating facilities //! injecting code into the crate before it is lowered to HIR. +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(array_windows)] #![feature(box_patterns)] @@ -71,33 +74,35 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { } register_bang! { + // tidy-alphabetical-start asm: asm::expand_asm, assert: assert::expand_assert, cfg: cfg::expand_cfg, column: source_util::expand_column, compile_error: compile_error::expand_compile_error, + concat: concat::expand_concat, concat_bytes: concat_bytes::expand_concat_bytes, concat_idents: concat_idents::expand_concat_idents, - concat: concat::expand_concat, + const_format_args: format::expand_format_args, + core_panic: edition_panic::expand_panic, env: env::expand_env, file: source_util::expand_file, - format_args_nl: format::expand_format_args_nl, format_args: format::expand_format_args, - const_format_args: format::expand_format_args, + format_args_nl: format::expand_format_args_nl, global_asm: asm::expand_global_asm, + include: source_util::expand_include, include_bytes: source_util::expand_include_bytes, include_str: source_util::expand_include_str, - include: source_util::expand_include, line: source_util::expand_line, log_syntax: log_syntax::expand_log_syntax, module_path: source_util::expand_mod, option_env: env::expand_option_env, - core_panic: edition_panic::expand_panic, std_panic: edition_panic::expand_panic, - unreachable: edition_panic::expand_unreachable, stringify: source_util::expand_stringify, trace_macros: trace_macros::expand_trace_macros, type_ascribe: type_ascribe::expand_type_ascribe, + unreachable: edition_panic::expand_unreachable, + // tidy-alphabetical-end } register_attr! { diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index 953d957a4ac..f7bafa2856e 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -61,9 +61,14 @@ pub fn expand_file( let topmost = cx.expansion_cause().unwrap_or(sp); let loc = cx.source_map().lookup_char_pos(topmost.lo()); - base::MacEager::expr( - cx.expr_str(topmost, Symbol::intern(&loc.file.name.prefer_remapped().to_string_lossy())), - ) + + use rustc_session::{config::RemapPathScopeComponents, RemapFileNameExt}; + base::MacEager::expr(cx.expr_str( + topmost, + Symbol::intern( + &loc.file.name.for_scope(cx.sess, RemapPathScopeComponents::MACRO).to_string_lossy(), + ), + )) } pub fn expand_stringify( diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 1580a6f6dd3..6d55603c708 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -35,11 +35,13 @@ pub fn expand_test_case( let sp = ecx.with_def_site_ctxt(attr_sp); let (mut item, is_stmt) = match anno_item { Annotatable::Item(item) => (item, false), - Annotatable::Stmt(stmt) if let ast::StmtKind::Item(_) = stmt.kind => if let ast::StmtKind::Item(i) = stmt.into_inner().kind { - (i, true) - } else { - unreachable!() - }, + Annotatable::Stmt(stmt) if let ast::StmtKind::Item(_) = stmt.kind => { + if let ast::StmtKind::Item(i) = stmt.into_inner().kind { + (i, true) + } else { + unreachable!() + } + } _ => { ecx.emit_err(errors::TestCaseNonItem { span: anno_item.span() }); return vec![]; diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index 8958369267e..7a3ae6ebf52 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -414,11 +414,12 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { // Note: must be kept in sync with get_caller_location from cg_ssa pub(crate) fn get_caller_location(&mut self, mut source_info: mir::SourceInfo) -> CValue<'tcx> { let span_to_caller_location = |fx: &mut FunctionCx<'_, '_, 'tcx>, span: Span| { + use rustc_session::RemapFileNameExt; let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span); let caller = fx.tcx.sess.source_map().lookup_char_pos(topmost.lo()); let const_loc = fx.tcx.const_caller_location(( rustc_span::symbol::Symbol::intern( - &caller.file.name.prefer_remapped().to_string_lossy(), + &caller.file.name.for_codegen(&fx.tcx.sess).to_string_lossy(), ), caller.line as u32, caller.col_display as u32 + 1, diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs index d00d19f9a80..6230ca15d6e 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs @@ -95,7 +95,11 @@ impl DebugContext { match &source_file.name { FileName::Real(path) => { let (dir_path, file_name) = - split_path_dir_and_file(path.remapped_path_if_available()); + split_path_dir_and_file(if self.should_remap_filepaths { + path.remapped_path_if_available() + } else { + path.local_path_if_available() + }); let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str()); let file_name = osstr_as_utf8_bytes(file_name); @@ -116,7 +120,14 @@ impl DebugContext { filename => { let dir_id = line_program.default_directory(); let dummy_file_name = LineString::new( - filename.prefer_remapped().to_string().into_bytes(), + filename + .display(if self.should_remap_filepaths { + FileNameDisplayPreference::Remapped + } else { + FileNameDisplayPreference::Local + }) + .to_string() + .into_bytes(), line_program.encoding(), line_strings, ); diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs index 9e78cc259ce..84bfe15c13f 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs @@ -31,6 +31,8 @@ pub(crate) struct DebugContext { dwarf: DwarfUnit, unit_range_list: RangeList, + + should_remap_filepaths: bool, } pub(crate) struct FunctionDebugContext { @@ -63,12 +65,18 @@ impl DebugContext { let mut dwarf = DwarfUnit::new(encoding); + let should_remap_filepaths = tcx.sess.should_prefer_remapped_for_codegen(); + let producer = producer(); let comp_dir = tcx .sess .opts .working_dir - .to_string_lossy(FileNameDisplayPreference::Remapped) + .to_string_lossy(if should_remap_filepaths { + FileNameDisplayPreference::Remapped + } else { + FileNameDisplayPreference::Local + }) .into_owned(); let (name, file_info) = match tcx.sess.local_crate_source_file() { Some(path) => { @@ -102,7 +110,12 @@ impl DebugContext { root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0))); } - DebugContext { endian, dwarf, unit_range_list: RangeList(Vec::new()) } + DebugContext { + endian, + dwarf, + unit_range_list: RangeList(Vec::new()), + should_remap_filepaths, + } } pub(crate) fn define_function( diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 522fe7e425b..8992de5a923 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -1,3 +1,6 @@ +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] #![feature(rustc_private)] // Note: please avoid adding other feature gates where possible #![warn(rust_2018_idioms)] diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 9c18fc4a0dc..6aa5b6bd1ff 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -12,6 +12,8 @@ * TODO(antoyo): remove the patches. */ +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature( rustc_private, decl_macro, diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index c778a6e017f..9d5204034de 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -259,9 +259,17 @@ pub fn target_machine_factory( }; let debuginfo_compression = SmallCStr::new(&debuginfo_compression); + let should_prefer_remapped_for_split_debuginfo_paths = + sess.should_prefer_remapped_for_split_debuginfo_paths(); + Arc::new(move |config: TargetMachineFactoryConfig| { let path_to_cstring_helper = |path: Option<PathBuf>| -> CString { - let path = path_mapping.map_prefix(path.unwrap_or_default()).0; + let path = path.unwrap_or_default(); + let path = if should_prefer_remapped_for_split_debuginfo_paths { + path_mapping.map_prefix(path).0 + } else { + path.into() + }; CString::new(path.to_str().unwrap()).unwrap() }; diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 4f9b86ec20a..7b259055d40 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1521,8 +1521,13 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { llfn: &'ll Value, ) { let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) }; - if self.tcx.sess.is_sanitizer_cfi_enabled() && let Some(fn_abi) = fn_abi && is_indirect_call { - if let Some(fn_attrs) = fn_attrs && fn_attrs.no_sanitize.contains(SanitizerSet::CFI) { + if self.tcx.sess.is_sanitizer_cfi_enabled() + && let Some(fn_abi) = fn_abi + && is_indirect_call + { + if let Some(fn_attrs) = fn_attrs + && fn_attrs.no_sanitize.contains(SanitizerSet::CFI) + { return; } @@ -1559,25 +1564,29 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { llfn: &'ll Value, ) -> Option<llvm::OperandBundleDef<'ll>> { let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) }; - let kcfi_bundle = - if self.tcx.sess.is_sanitizer_kcfi_enabled() && let Some(fn_abi) = fn_abi && is_indirect_call { - if let Some(fn_attrs) = fn_attrs && fn_attrs.no_sanitize.contains(SanitizerSet::KCFI) { - return None; - } + let kcfi_bundle = if self.tcx.sess.is_sanitizer_kcfi_enabled() + && let Some(fn_abi) = fn_abi + && is_indirect_call + { + if let Some(fn_attrs) = fn_attrs + && fn_attrs.no_sanitize.contains(SanitizerSet::KCFI) + { + return None; + } - let mut options = TypeIdOptions::empty(); - if self.tcx.sess.is_sanitizer_cfi_generalize_pointers_enabled() { - options.insert(TypeIdOptions::GENERALIZE_POINTERS); - } - if self.tcx.sess.is_sanitizer_cfi_normalize_integers_enabled() { - options.insert(TypeIdOptions::NORMALIZE_INTEGERS); - } + let mut options = TypeIdOptions::empty(); + if self.tcx.sess.is_sanitizer_cfi_generalize_pointers_enabled() { + options.insert(TypeIdOptions::GENERALIZE_POINTERS); + } + if self.tcx.sess.is_sanitizer_cfi_normalize_integers_enabled() { + options.insert(TypeIdOptions::NORMALIZE_INTEGERS); + } - let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options); - Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)])) - } else { - None - }; + let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options); + Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)])) + } else { + None + }; kcfi_bundle } } diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index 5254c3f9c9a..d5778757caa 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -46,8 +46,8 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> llfn } else { let instance_def_id = instance.def_id(); - let llfn = if tcx.sess.target.arch == "x86" && - let Some(dllimport) = common::get_dllimport(tcx, instance_def_id, sym) + let llfn = if tcx.sess.target.arch == "x86" + && let Some(dllimport) = common::get_dllimport(tcx, instance_def_id, sym) { // Fix for https://github.com/rust-lang/rust/issues/104453 // On x86 Windows, LLVM uses 'L' as the prefix for any private @@ -60,8 +60,18 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> // LLVM will prefix the name with `__imp_`. Ideally, we'd like the // existing logic below to set the Storage Class, but it has an // exemption for MinGW for backwards compatability. - let llfn = cx.declare_fn(&common::i686_decorated_name(&dllimport, common::is_mingw_gnu_toolchain(&tcx.sess.target), true), fn_abi, Some(instance)); - unsafe { llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); } + let llfn = cx.declare_fn( + &common::i686_decorated_name( + &dllimport, + common::is_mingw_gnu_toolchain(&tcx.sess.target), + true, + ), + fn_abi, + Some(instance), + ); + unsafe { + llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); + } llfn } else { cx.declare_fn(sym, fn_abi, Some(instance)) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 95af2f8ef4a..73821b1685d 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -182,10 +182,17 @@ fn check_and_apply_linkage<'ll, 'tcx>( llvm::LLVMSetInitializer(g2, g1); g2 } - } else if cx.tcx.sess.target.arch == "x86" && - let Some(dllimport) = common::get_dllimport(cx.tcx, def_id, sym) + } else if cx.tcx.sess.target.arch == "x86" + && let Some(dllimport) = common::get_dllimport(cx.tcx, def_id, sym) { - cx.declare_global(&common::i686_decorated_name(&dllimport, common::is_mingw_gnu_toolchain(&cx.tcx.sess.target), true), llty) + cx.declare_global( + &common::i686_decorated_name( + &dllimport, + common::is_mingw_gnu_toolchain(&cx.tcx.sess.target), + true, + ), + llty, + ) } else { // Generate an external declaration. // FIXME(nagisa): investigate whether it can be changed into define_global diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index d4e77525698..d58e95fcd36 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -126,9 +126,9 @@ impl GlobalFileTable { // Since rustc generates coverage maps with relative paths, the // compilation directory can be combined with the relative paths // to get absolute paths, if needed. - let working_dir = Symbol::intern( - &tcx.sess.opts.working_dir.remapped_path_if_available().to_string_lossy(), - ); + use rustc_session::RemapFileNameExt; + let working_dir = + Symbol::intern(&tcx.sess.opts.working_dir.for_codegen(&tcx.sess).to_string_lossy()); global_file_table.insert(working_dir); Self { global_file_table } } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs index aff764f0224..6a63eda4b99 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs @@ -75,7 +75,10 @@ fn make_mir_scope<'ll, 'tcx>( return; }; - if let Some(vars) = variables && !vars.contains(scope) && scope_data.inlined.is_none() { + if let Some(vars) = variables + && !vars.contains(scope) + && scope_data.inlined.is_none() + { // Do not create a DIScope if there are no variables defined in this // MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat. debug_context.scopes[scope] = parent_scope; diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 11874898a5a..4f8ae2ddb8f 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -547,48 +547,77 @@ pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> ) -> &'ll DIFile { debug!(?source_file.name); + use rustc_session::RemapFileNameExt; let (directory, file_name) = match &source_file.name { FileName::Real(filename) => { let working_directory = &cx.sess().opts.working_dir; debug!(?working_directory); - let filename = cx - .sess() - .source_map() - .path_mapping() - .to_embeddable_absolute_path(filename.clone(), working_directory); - - // Construct the absolute path of the file - let abs_path = filename.remapped_path_if_available(); - debug!(?abs_path); - - if let Ok(rel_path) = - abs_path.strip_prefix(working_directory.remapped_path_if_available()) - { - // If the compiler's working directory (which also is the DW_AT_comp_dir of - // the compilation unit) is a prefix of the path we are about to emit, then - // only emit the part relative to the working directory. - // Because of path remapping we sometimes see strange things here: `abs_path` - // might actually look like a relative path - // (e.g. `<crate-name-and-version>/src/lib.rs`), so if we emit it without - // taking the working directory into account, downstream tooling will - // interpret it as `<working-directory>/<crate-name-and-version>/src/lib.rs`, - // which makes no sense. Usually in such cases the working directory will also - // be remapped to `<crate-name-and-version>` or some other prefix of the path - // we are remapping, so we end up with - // `<crate-name-and-version>/<crate-name-and-version>/src/lib.rs`. - // By moving the working directory portion into the `directory` part of the - // DIFile, we allow LLVM to emit just the relative path for DWARF, while - // still emitting the correct absolute path for CodeView. - ( - working_directory.to_string_lossy(FileNameDisplayPreference::Remapped), - rel_path.to_string_lossy().into_owned(), - ) + if cx.sess().should_prefer_remapped_for_codegen() { + let filename = cx + .sess() + .source_map() + .path_mapping() + .to_embeddable_absolute_path(filename.clone(), working_directory); + + // Construct the absolute path of the file + let abs_path = filename.remapped_path_if_available(); + debug!(?abs_path); + + if let Ok(rel_path) = + abs_path.strip_prefix(working_directory.remapped_path_if_available()) + { + // If the compiler's working directory (which also is the DW_AT_comp_dir of + // the compilation unit) is a prefix of the path we are about to emit, then + // only emit the part relative to the working directory. + // Because of path remapping we sometimes see strange things here: `abs_path` + // might actually look like a relative path + // (e.g. `<crate-name-and-version>/src/lib.rs`), so if we emit it without + // taking the working directory into account, downstream tooling will + // interpret it as `<working-directory>/<crate-name-and-version>/src/lib.rs`, + // which makes no sense. Usually in such cases the working directory will also + // be remapped to `<crate-name-and-version>` or some other prefix of the path + // we are remapping, so we end up with + // `<crate-name-and-version>/<crate-name-and-version>/src/lib.rs`. + // By moving the working directory portion into the `directory` part of the + // DIFile, we allow LLVM to emit just the relative path for DWARF, while + // still emitting the correct absolute path for CodeView. + ( + working_directory.to_string_lossy(FileNameDisplayPreference::Remapped), + rel_path.to_string_lossy().into_owned(), + ) + } else { + ("".into(), abs_path.to_string_lossy().into_owned()) + } } else { - ("".into(), abs_path.to_string_lossy().into_owned()) + let working_directory = working_directory.local_path_if_available(); + let filename = filename.local_path_if_available(); + + debug!(?working_directory, ?filename); + + let abs_path: Cow<'_, Path> = if filename.is_absolute() { + filename.into() + } else { + let mut p = PathBuf::new(); + p.push(working_directory); + p.push(filename); + p.into() + }; + + if let Ok(rel_path) = abs_path.strip_prefix(working_directory) { + ( + working_directory.to_string_lossy().into(), + rel_path.to_string_lossy().into_owned(), + ) + } else { + ("".into(), abs_path.to_string_lossy().into_owned()) + } } } - other => ("".into(), other.prefer_remapped().to_string_lossy().into_owned()), + other => { + debug!(?other); + ("".into(), other.for_codegen(cx.sess()).to_string_lossy().into_owned()) + } }; let hash_kind = match source_file.src_hash.kind { @@ -822,8 +851,9 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>( // FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice. let producer = format!("clang LLVM ({rustc_producer})"); + use rustc_session::RemapFileNameExt; let name_in_debuginfo = name_in_debuginfo.to_string_lossy(); - let work_dir = tcx.sess.opts.working_dir.to_string_lossy(FileNameDisplayPreference::Remapped); + let work_dir = tcx.sess.opts.working_dir.for_codegen(&tcx.sess).to_string_lossy(); let flags = "\0"; let output_filenames = tcx.output_filenames(()); let split_name = if tcx.sess.target_can_use_split_dwarf() { @@ -834,7 +864,13 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>( Some(codegen_unit_name), ) // We get a path relative to the working directory from split_dwarf_path - .map(|f| tcx.sess.source_map().path_mapping().map_prefix(f).0) + .map(|f| { + if tcx.sess.should_prefer_remapped_for_split_debuginfo_paths() { + tcx.sess.source_map().path_mapping().map_prefix(f).0 + } else { + f.into() + } + }) } else { None } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 30cc9ea9b82..d874b3ab99d 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -537,7 +537,9 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { // Only "class" methods are generally understood by LLVM, // so avoid methods on other types (e.g., `<*mut T>::null`). - if let ty::Adt(def, ..) = impl_self_ty.kind() && !def.is_box() { + if let ty::Adt(def, ..) = impl_self_ty.kind() + && !def.is_box() + { // Again, only create type information if full debuginfo is enabled if cx.sess().opts.debuginfo == DebugInfo::Full && !impl_self_ty.has_param() { diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 59d1ea05d8a..7a390d35a2b 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -4,6 +4,9 @@ //! //! This API is completely unstable and subject to change. +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(extern_types)] #![feature(hash_raw_entry)] diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 28a51711b93..f16fe372a92 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -368,17 +368,25 @@ fn link_rlib<'a>( let NativeLibKind::Static { bundle: None | Some(true), .. } = lib.kind else { continue; }; - if flavor == RlibFlavor::Normal && let Some(filename) = lib.filename { + if flavor == RlibFlavor::Normal + && let Some(filename) = lib.filename + { let path = find_native_static_library(filename.as_str(), true, &lib_search_paths, sess); - let src = read(path).map_err(|e| sess.emit_fatal(errors::ReadFileError {message: e }))?; + let src = + read(path).map_err(|e| sess.emit_fatal(errors::ReadFileError { message: e }))?; let (data, _) = create_wrapper_file(sess, b".bundled_lib".to_vec(), &src); let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str()); packed_bundled_libs.push(wrapper_file); } else { - let path = - find_native_static_library(lib.name.as_str(), lib.verbatim, &lib_search_paths, sess); + let path = find_native_static_library( + lib.name.as_str(), + lib.verbatim, + &lib_search_paths, + sess, + ); ab.add_archive(&path, Box::new(|_| false)).unwrap_or_else(|error| { - sess.emit_fatal(errors::AddNativeLibrary { library_path: path, error })}); + sess.emit_fatal(errors::AddNativeLibrary { library_path: path, error }) + }); } } diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 11afe0fbc3c..09434513e31 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -626,6 +626,15 @@ impl<'a> Linker for GccLinker<'a> { self.linker_arg("--strip-all"); } } + match self.sess.opts.unstable_opts.debuginfo_compression { + config::DebugInfoCompression::None => {} + config::DebugInfoCompression::Zlib => { + self.linker_arg("--compress-debug-sections=zlib"); + } + config::DebugInfoCompression::Zstd => { + self.linker_arg("--compress-debug-sections=zstd"); + } + } } fn no_crt_objects(&mut self) { diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 59efe4cd3cc..2e0840f2d1b 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -238,8 +238,13 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { && let Some(fn_sig) = fn_sig() && fn_sig.skip_binder().abi() != abi::Abi::Rust { - struct_span_err!(tcx.sess, attr.span, E0737, "`#[track_caller]` requires Rust ABI") - .emit(); + struct_span_err!( + tcx.sess, + attr.span, + E0737, + "`#[track_caller]` requires Rust ABI" + ) + .emit(); } if is_closure && !tcx.features().closure_track_caller @@ -435,17 +440,18 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { && let [item] = items.as_slice() && let Some((sym::align, literal)) = item.name_value_literal() { - rustc_attr::parse_alignment(&literal.kind).map_err(|msg| { - struct_span_err!( - tcx.sess.diagnostic(), - attr.span, - E0589, - "invalid `repr(align)` attribute: {}", - msg - ) - .emit(); - }) - .ok() + rustc_attr::parse_alignment(&literal.kind) + .map_err(|msg| { + struct_span_err!( + tcx.sess.diagnostic(), + attr.span, + E0589, + "invalid `repr(align)` attribute: {}", + msg + ) + .emit(); + }) + .ok() } else { None }; @@ -626,10 +632,7 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool { && let ty::AssocItemContainer::ImplContainer = impl_item.container && let Some(trait_item) = impl_item.trait_item_def_id { - return tcx - .codegen_fn_attrs(trait_item) - .flags - .intersects(CodegenFnAttrFlags::TRACK_CALLER); + return tcx.codegen_fn_attrs(trait_item).flags.intersects(CodegenFnAttrFlags::TRACK_CALLER); } false diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index a0cb97d51a0..68f22aaf990 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1454,10 +1454,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let tcx = bx.tcx(); let mut span_to_caller_location = |span: Span| { + use rustc_session::RemapFileNameExt; let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span); let caller = tcx.sess.source_map().lookup_char_pos(topmost.lo()); let const_loc = tcx.const_caller_location(( - Symbol::intern(&caller.file.name.prefer_remapped().to_string_lossy()), + Symbol::intern(&caller.file.name.for_codegen(self.cx.sess()).to_string_lossy()), caller.line as u32, caller.col_display as u32 + 1, )); @@ -1555,7 +1556,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } fn terminate_block(&mut self, reason: UnwindTerminateReason) -> Bx::BasicBlock { - if let Some((cached_bb, cached_reason)) = self.terminate_block && reason == cached_reason { + if let Some((cached_bb, cached_reason)) = self.terminate_block + && reason == cached_reason + { return cached_bb; } diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 8efef440522..136d06d561a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -117,9 +117,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { sym::vtable_size => { let size_bound = bx.data_layout().ptr_sized_integer().signed_max() as u128; bx.range_metadata(value, WrappingRange { start: 0, end: size_bound }); - }, + } // Alignment is always nonzero. - sym::vtable_align => bx.range_metadata(value, WrappingRange { start: 1, end: !0 }), + sym::vtable_align => { + bx.range_metadata(value, WrappingRange { start: 1, end: !0 }) + } _ => {} } value @@ -220,9 +222,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } else { bx.exactudiv(args[0].immediate(), args[1].immediate()) } - }, + } None => { - bx.tcx().sess.emit_err(InvalidMonomorphization::BasicIntegerType { span, name, ty }); + bx.tcx().sess.emit_err(InvalidMonomorphization::BasicIntegerType { + span, + name, + ty, + }); return; } } @@ -238,7 +244,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => bug!(), }, None => { - bx.tcx().sess.emit_err(InvalidMonomorphization::BasicFloatType { span, name, ty: arg_tys[0] }); + bx.tcx().sess.emit_err(InvalidMonomorphization::BasicFloatType { + span, + name, + ty: arg_tys[0], + }); return; } } @@ -246,11 +256,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { sym::float_to_int_unchecked => { if float_type_width(arg_tys[0]).is_none() { - bx.tcx().sess.emit_err(InvalidMonomorphization::FloatToIntUnchecked { span, ty: arg_tys[0] }); + bx.tcx().sess.emit_err(InvalidMonomorphization::FloatToIntUnchecked { + span, + ty: arg_tys[0], + }); return; } let Some((_width, signed)) = int_type_width_signed(ret_ty, bx.tcx()) else { - bx.tcx().sess.emit_err(InvalidMonomorphization::FloatToIntUnchecked { span, ty: ret_ty }); + bx.tcx().sess.emit_err(InvalidMonomorphization::FloatToIntUnchecked { + span, + ty: ret_ty, + }); return; }; if signed { @@ -299,7 +315,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; let invalid_monomorphization = |ty| { - bx.tcx().sess.emit_err(InvalidMonomorphization::BasicIntegerType { span, name, ty }); + bx.tcx().sess.emit_err(InvalidMonomorphization::BasicIntegerType { + span, + name, + ty, + }); }; match instruction { @@ -319,7 +339,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { cmp = bx.ptrtoint(cmp, bx.type_isize()); src = bx.ptrtoint(src, bx.type_isize()); } - let pair = bx.atomic_cmpxchg(dst, cmp, src, parse_ordering(bx, success), parse_ordering(bx, failure), weak); + let pair = bx.atomic_cmpxchg( + dst, + cmp, + src, + parse_ordering(bx, success), + parse_ordering(bx, failure), + weak, + ); let val = bx.extract_value(pair, 0); let success = bx.extract_value(pair, 1); let val = bx.from_immediate(val); @@ -345,11 +372,21 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Some platforms do not support atomic operations on pointers, // so we cast to integer first... let llty = bx.type_isize(); - let result = bx.atomic_load(llty, source, parse_ordering(bx, ordering), size); + let result = bx.atomic_load( + llty, + source, + parse_ordering(bx, ordering), + size, + ); // ... and then cast the result back to a pointer bx.inttoptr(result, bx.backend_type(layout)) } else { - bx.atomic_load(bx.backend_type(layout), source, parse_ordering(bx, ordering), size) + bx.atomic_load( + bx.backend_type(layout), + source, + parse_ordering(bx, ordering), + size, + ) } } else { return invalid_monomorphization(ty); @@ -375,12 +412,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } "fence" => { - bx.atomic_fence(parse_ordering(bx, ordering), SynchronizationScope::CrossThread); + bx.atomic_fence( + parse_ordering(bx, ordering), + SynchronizationScope::CrossThread, + ); return; } "singlethreadfence" => { - bx.atomic_fence(parse_ordering(bx, ordering), SynchronizationScope::SingleThread); + bx.atomic_fence( + parse_ordering(bx, ordering), + SynchronizationScope::SingleThread, + ); return; } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index fc8d3389102..f591afaaaf4 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -239,17 +239,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; if let OperandValueKind::Immediate(out_scalar) = cast_kind && in_scalar.size(self.cx) == out_scalar.size(self.cx) - { - let operand_bty = bx.backend_type(operand.layout); - let cast_bty = bx.backend_type(cast); - Some(OperandValue::Immediate(self.transmute_immediate( - bx, - imm, - in_scalar, - operand_bty, - out_scalar, - cast_bty, - ))) + { + let operand_bty = bx.backend_type(operand.layout); + let cast_bty = bx.backend_type(cast); + Some(OperandValue::Immediate(self.transmute_immediate( + bx, + imm, + in_scalar, + operand_bty, + out_scalar, + cast_bty, + ))) } else { None } diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index d23e2a9f3e4..f926da464e1 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -1,11 +1,15 @@ const_eval_address_space_full = there are no more free addresses in the address space -const_eval_align_check_failed = accessing memory with alignment {$has}, but alignment {$required} is required + const_eval_align_offset_invalid_align = `align_offset` called with non-power-of-two align: {$target_align} const_eval_alignment_check_failed = - accessing memory with alignment {$has}, but alignment {$required} is required + {$msg -> + [AccessedPtr] accessing memory + *[other] accessing memory based on pointer + } with alignment {$has}, but alignment {$required} is required + const_eval_already_reported = an error has already been reported elsewhere (this should not usually be printed) const_eval_assume_false = @@ -61,7 +65,6 @@ const_eval_deref_coercion_non_const = .target_note = deref defined here const_eval_deref_function_pointer = accessing {$allocation} which contains a function -const_eval_deref_test = dereferencing pointer failed const_eval_deref_vtable_pointer = accessing {$allocation} which contains a vtable const_eval_different_allocations = diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 4adfbe336af..6b612c34837 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -1,3 +1,5 @@ +use std::mem; + use either::{Left, Right}; use rustc_hir::def::DefKind; @@ -73,9 +75,9 @@ fn eval_body_using_ecx<'mir, 'tcx>( None => InternKind::Constant, } }; - ecx.machine.check_alignment = CheckAlignment::No; // interning doesn't need to respect alignment + let check_alignment = mem::replace(&mut ecx.machine.check_alignment, CheckAlignment::No); // interning doesn't need to respect alignment intern_const_alloc_recursive(ecx, intern_kind, &ret)?; - // we leave alignment checks off, since this `ecx` will not be used for further evaluation anyway + ecx.machine.check_alignment = check_alignment; debug!("eval_body_using_ecx done: {:?}", ret); Ok(ret) diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index 4ee4ebbb9e4..9e992637f46 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -39,8 +39,13 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { hir::Node::Ctor(_) | hir::Node::AnonConst(_) | hir::Node::ConstBlock(_) - | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => hir::Constness::Const, - hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => tcx.generics_of(def_id).host_effect_index.map_or(hir::Constness::NotConst, |_| hir::Constness::Const), + | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => { + hir::Constness::Const + } + hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => tcx + .generics_of(def_id) + .host_effect_index + .map_or(hir::Constness::NotConst, |_| hir::Constness::Const), hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => { // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other // foreign items cannot be evaluated at compile-time. diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index b1599dd6894..cc8f3387238 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -5,8 +5,9 @@ use rustc_errors::{ use rustc_hir::ConstContext; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::mir::interpret::{ - CheckInAllocMsg, ExpectedKind, InterpError, InvalidMetaKind, InvalidProgramInfo, PointerKind, - ResourceExhaustionInfo, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo, + CheckInAllocMsg, ExpectedKind, InterpError, InvalidMetaKind, InvalidProgramInfo, Misalignment, + PointerKind, ResourceExhaustionInfo, UndefinedBehaviorInfo, UnsupportedOpInfo, + ValidationErrorInfo, }; use rustc_middle::ty::{self, Ty}; use rustc_span::Span; @@ -389,15 +390,6 @@ pub struct LiveDrop<'tcx> { pub dropped_at: Option<Span>, } -#[derive(LintDiagnostic)] -#[diag(const_eval_align_check_failed)] -pub struct AlignmentCheckFailed { - pub has: u64, - pub required: u64, - #[subdiagnostic] - pub frames: Vec<FrameNote>, -} - #[derive(Diagnostic)] #[diag(const_eval_error, code = "E0080")] pub struct ConstEvalError { @@ -459,7 +451,6 @@ fn bad_pointer_message(msg: CheckInAllocMsg, handler: &Handler) -> String { use crate::fluent_generated::*; let msg = match msg { - CheckInAllocMsg::DerefTest => const_eval_deref_test, CheckInAllocMsg::MemoryAccessTest => const_eval_memory_access_test, CheckInAllocMsg::PointerArithmeticTest => const_eval_pointer_arithmetic_test, CheckInAllocMsg::OffsetFromTest => const_eval_offset_from_test, @@ -568,9 +559,10 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> { builder.set_arg("bad_pointer_message", bad_pointer_message(msg, handler)); } - AlignmentCheckFailed { required, has } => { + AlignmentCheckFailed(Misalignment { required, has }, msg) => { builder.set_arg("required", required.bytes()); builder.set_arg("has", has.bytes()); + builder.set_arg("msg", format!("{msg:?}")); } WriteToReadOnly(alloc) | DerefFunctionPointer(alloc) | DerefVTablePointer(alloc) => { builder.set_arg("allocation", alloc); diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 8c0009cfdfd..fd89e34204f 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -161,7 +161,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory #[inline(always)] fn ecx(&self) -> &InterpCx<'mir, 'tcx, M> { - &self.ecx + self.ecx } fn visit_value(&mut self, mplace: &MPlaceTy<'tcx>) -> InterpResult<'tcx> { @@ -259,7 +259,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory // to avoid could be expensive: on the potentially larger types, arrays and slices, // rather than on all aggregates unconditionally. if matches!(mplace.layout.ty.kind(), ty::Array(..) | ty::Slice(..)) { - let Some((size, align)) = self.ecx.size_and_align_of_mplace(&mplace)? else { + let Some((size, _align)) = self.ecx.size_and_align_of_mplace(&mplace)? else { // We do the walk if we can't determine the size of the mplace: we may be // dealing with extern types here in the future. return Ok(true); @@ -267,7 +267,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory // If there is no provenance in this allocation, it does not contain references // that point to another allocation, and we can avoid the interning walk. - if let Some(alloc) = self.ecx.get_ptr_alloc(mplace.ptr(), size, align)? { + if let Some(alloc) = self.ecx.get_ptr_alloc(mplace.ptr(), size)? { if !alloc.has_provenance() { return Ok(false); } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 1891d286a3c..b7106c37c7b 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::layout::{LayoutOf as _, ValidityRequirement}; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{Ty, TyCtxt}; use rustc_span::symbol::{sym, Symbol}; -use rustc_target::abi::{Abi, Align, Primitive, Size}; +use rustc_target::abi::{Abi, Primitive, Size}; use super::{ util::ensure_monomorphic_enough, CheckInAllocMsg, ImmTy, InterpCx, Machine, OpTy, PlaceTy, @@ -349,10 +349,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Check that the range between them is dereferenceable ("in-bounds or one past the // end of the same allocation"). This is like the check in ptr_offset_inbounds. let min_ptr = if dist >= 0 { b } else { a }; - self.check_ptr_access_align( + self.check_ptr_access( min_ptr, Size::from_bytes(dist.unsigned_abs()), - Align::ONE, CheckInAllocMsg::OffsetFromTest, )?; @@ -571,16 +570,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn ptr_offset_inbounds( &self, ptr: Pointer<Option<M::Provenance>>, - pointee_ty: Ty<'tcx>, - offset_count: i64, + offset_bytes: i64, ) -> InterpResult<'tcx, Pointer<Option<M::Provenance>>> { - // We cannot overflow i64 as a type's size must be <= isize::MAX. - let pointee_size = i64::try_from(self.layout_of(pointee_ty)?.size.bytes()).unwrap(); - // The computed offset, in bytes, must not overflow an isize. - // `checked_mul` enforces a too small bound, but no actual allocation can be big enough for - // the difference to be noticeable. - let offset_bytes = - offset_count.checked_mul(pointee_size).ok_or(err_ub!(PointerArithOverflow))?; // The offset being in bounds cannot rely on "wrapping around" the address space. // So, first rule out overflows in the pointer arithmetic. let offset_ptr = ptr.signed_offset(offset_bytes, self)?; @@ -589,10 +580,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // pointers to be properly aligned (unlike a read/write operation). let min_ptr = if offset_bytes >= 0 { ptr } else { offset_ptr }; // This call handles checking for integer/null pointers. - self.check_ptr_access_align( + self.check_ptr_access( min_ptr, Size::from_bytes(offset_bytes.unsigned_abs()), - Align::ONE, CheckInAllocMsg::PointerArithmeticTest, )?; Ok(offset_ptr) @@ -621,7 +611,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let src = self.read_pointer(src)?; let dst = self.read_pointer(dst)?; - self.mem_copy(src, align, dst, align, size, nonoverlapping) + self.check_ptr_align(src, align)?; + self.check_ptr_align(dst, align)?; + + self.mem_copy(src, dst, size, nonoverlapping) } pub(crate) fn write_bytes_intrinsic( @@ -677,7 +670,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { size| -> InterpResult<'tcx, &[u8]> { let ptr = this.read_pointer(op)?; - let Some(alloc_ref) = self.get_ptr_alloc(ptr, size, Align::ONE)? else { + let Some(alloc_ref) = self.get_ptr_alloc(ptr, size)? else { // zero-sized access return Ok(&[]); }; 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 948bec7464a..16b7decf9c4 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs @@ -114,8 +114,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub(crate) fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) { let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span); let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo()); + + use rustc_session::{config::RemapPathScopeComponents, RemapFileNameExt}; ( - Symbol::intern(&caller.file.name.prefer_remapped().to_string_lossy()), + Symbol::intern( + &caller + .file + .name + .for_scope(&self.tcx.sess, RemapPathScopeComponents::DIAGNOSTICS) + .to_string_lossy(), + ), u32::try_from(caller.line).unwrap(), u32::try_from(caller.col_display).unwrap().checked_add(1).unwrap(), ) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 9b4f9906599..61fe9151d8b 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -436,6 +436,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { place: &PlaceTy<'tcx, Self::Provenance>, ) -> InterpResult<'tcx> { // Without an aliasing model, all we can do is put `Uninit` into the place. + // Conveniently this also ensures that the place actually points to suitable memory. ecx.write_uninit(place) } diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index edd8c540226..5b31738e4e1 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -21,9 +21,9 @@ use rustc_target::abi::{Align, HasDataLayout, Size}; use crate::fluent_generated as fluent; use super::{ - alloc_range, AllocBytes, AllocId, AllocMap, AllocRange, Allocation, CheckInAllocMsg, - GlobalAlloc, InterpCx, InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Provenance, - Scalar, + alloc_range, AllocBytes, AllocId, AllocMap, AllocRange, Allocation, CheckAlignMsg, + CheckInAllocMsg, GlobalAlloc, InterpCx, InterpResult, Machine, MayLeak, Misalignment, Pointer, + PointerArithmetic, Provenance, Scalar, }; #[derive(Debug, PartialEq, Copy, Clone)] @@ -258,14 +258,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { None => self.get_alloc_raw(alloc_id)?.size(), }; // This will also call the access hooks. - self.mem_copy( - ptr, - Align::ONE, - new_ptr.into(), - Align::ONE, - old_size.min(new_size), - /*nonoverlapping*/ true, - )?; + self.mem_copy(ptr, new_ptr.into(), old_size.min(new_size), /*nonoverlapping*/ true)?; self.deallocate_ptr(ptr, old_size_and_align, kind)?; Ok(new_ptr) @@ -367,12 +360,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &self, ptr: Pointer<Option<M::Provenance>>, size: Size, - align: Align, ) -> InterpResult<'tcx, Option<(AllocId, Size, M::ProvenanceExtra)>> { self.check_and_deref_ptr( ptr, size, - M::enforce_alignment(self).then_some(align), CheckInAllocMsg::MemoryAccessTest, |alloc_id, offset, prov| { let (size, align) = self @@ -382,18 +373,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) } - /// Check if the given pointer points to live memory of given `size` and `align` - /// (ignoring `M::enforce_alignment`). The caller can control the error message for the - /// out-of-bounds case. + /// Check if the given pointer points to live memory of the given `size`. + /// The caller can control the error message for the out-of-bounds case. #[inline(always)] - pub fn check_ptr_access_align( + pub fn check_ptr_access( &self, ptr: Pointer<Option<M::Provenance>>, size: Size, - align: Align, msg: CheckInAllocMsg, ) -> InterpResult<'tcx> { - self.check_and_deref_ptr(ptr, size, Some(align), msg, |alloc_id, _, _| { + self.check_and_deref_ptr(ptr, size, msg, |alloc_id, _, _| { let (size, align) = self.get_live_alloc_size_and_align(alloc_id, msg)?; Ok((size, align, ())) })?; @@ -402,15 +391,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Low-level helper function to check if a ptr is in-bounds and potentially return a reference /// to the allocation it points to. Supports both shared and mutable references, as the actual - /// checking is offloaded to a helper closure. `align` defines whether and which alignment check - /// is done. + /// checking is offloaded to a helper closure. /// /// If this returns `None`, the size is 0; it can however return `Some` even for size 0. fn check_and_deref_ptr<T>( &self, ptr: Pointer<Option<M::Provenance>>, size: Size, - align: Option<Align>, msg: CheckInAllocMsg, alloc_size: impl FnOnce( AllocId, @@ -425,14 +412,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if size.bytes() > 0 || addr == 0 { throw_ub!(DanglingIntPointer(addr, msg)); } - // Must be aligned. - if let Some(align) = align { - self.check_offset_align(addr, align)?; - } None } Ok((alloc_id, offset, prov)) => { - let (alloc_size, alloc_align, ret_val) = alloc_size(alloc_id, offset, prov)?; + let (alloc_size, _alloc_align, ret_val) = alloc_size(alloc_id, offset, prov)?; // Test bounds. This also ensures non-null. // It is sufficient to check this for the end pointer. Also check for overflow! if offset.checked_add(size, &self.tcx).map_or(true, |end| end > alloc_size) { @@ -448,20 +431,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if M::Provenance::OFFSET_IS_ADDR { assert_ne!(ptr.addr(), Size::ZERO); } - // Test align. Check this last; if both bounds and alignment are violated - // we want the error to be about the bounds. - if let Some(align) = align { - if M::use_addr_for_alignment_check(self) { - // `use_addr_for_alignment_check` can only be true if `OFFSET_IS_ADDR` is true. - self.check_offset_align(ptr.addr().bytes(), align)?; - } else { - // Check allocation alignment and offset alignment. - if alloc_align.bytes() < align.bytes() { - throw_ub!(AlignmentCheckFailed { has: alloc_align, required: align }); - } - self.check_offset_align(offset.bytes(), align)?; - } - } // We can still be zero-sized in this branch, in which case we have to // return `None`. @@ -470,18 +439,66 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }) } - fn check_offset_align(&self, offset: u64, align: Align) -> InterpResult<'tcx> { - if offset % align.bytes() == 0 { - Ok(()) - } else { - // The biggest power of two through which `offset` is divisible. - let offset_pow2 = 1 << offset.trailing_zeros(); - throw_ub!(AlignmentCheckFailed { - has: Align::from_bytes(offset_pow2).unwrap(), - required: align - }); + pub(super) fn check_misalign( + &self, + misaligned: Option<Misalignment>, + msg: CheckAlignMsg, + ) -> InterpResult<'tcx> { + if let Some(misaligned) = misaligned { + throw_ub!(AlignmentCheckFailed(misaligned, msg)) + } + Ok(()) + } + + pub(super) fn is_ptr_misaligned( + &self, + ptr: Pointer<Option<M::Provenance>>, + align: Align, + ) -> Option<Misalignment> { + if !M::enforce_alignment(self) || align.bytes() == 1 { + return None; + } + + #[inline] + fn offset_misalignment(offset: u64, align: Align) -> Option<Misalignment> { + if offset % align.bytes() == 0 { + None + } else { + // The biggest power of two through which `offset` is divisible. + let offset_pow2 = 1 << offset.trailing_zeros(); + Some(Misalignment { has: Align::from_bytes(offset_pow2).unwrap(), required: align }) + } + } + + match self.ptr_try_get_alloc_id(ptr) { + Err(addr) => offset_misalignment(addr, align), + Ok((alloc_id, offset, _prov)) => { + let (_size, alloc_align, _kind) = self.get_alloc_info(alloc_id); + if M::use_addr_for_alignment_check(self) { + // `use_addr_for_alignment_check` can only be true if `OFFSET_IS_ADDR` is true. + offset_misalignment(ptr.addr().bytes(), align) + } else { + // Check allocation alignment and offset alignment. + if alloc_align.bytes() < align.bytes() { + Some(Misalignment { has: alloc_align, required: align }) + } else { + offset_misalignment(offset.bytes(), align) + } + } + } } } + + /// Checks a pointer for misalignment. + /// + /// The error assumes this is checking the pointer used directly for an access. + pub fn check_ptr_align( + &self, + ptr: Pointer<Option<M::Provenance>>, + align: Align, + ) -> InterpResult<'tcx> { + self.check_misalign(self.is_ptr_misaligned(ptr, align), CheckAlignMsg::AccessedPtr) + } } /// Allocation accessors @@ -538,17 +555,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) } - /// Get the base address for the bytes in an `Allocation` specified by the - /// `AllocID` passed in; error if no such allocation exists. - /// - /// It is up to the caller to take sufficient care when using this address: - /// there could be provenance or uninit memory in there, and other memory - /// accesses could invalidate the exposed pointer. - pub fn alloc_base_addr(&self, id: AllocId) -> InterpResult<'tcx, *const u8> { - let alloc = self.get_alloc_raw(id)?; - Ok(alloc.base_addr()) - } - /// Gives raw access to the `Allocation`, without bounds or alignment checks. /// The caller is responsible for calling the access hooks! /// @@ -586,18 +592,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } - /// "Safe" (bounds and align-checked) allocation access. + /// Bounds-checked *but not align-checked* allocation access. pub fn get_ptr_alloc<'a>( &'a self, ptr: Pointer<Option<M::Provenance>>, size: Size, - align: Align, ) -> InterpResult<'tcx, Option<AllocRef<'a, 'tcx, M::Provenance, M::AllocExtra, M::Bytes>>> { let ptr_and_alloc = self.check_and_deref_ptr( ptr, size, - M::enforce_alignment(self).then_some(align), CheckInAllocMsg::MemoryAccessTest, |alloc_id, offset, prov| { let alloc = self.get_alloc_raw(alloc_id)?; @@ -658,15 +662,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok((alloc, &mut self.machine)) } - /// "Safe" (bounds and align-checked) allocation access. + /// Bounds-checked *but not align-checked* allocation access. pub fn get_ptr_alloc_mut<'a>( &'a mut self, ptr: Pointer<Option<M::Provenance>>, size: Size, - align: Align, ) -> InterpResult<'tcx, Option<AllocRefMut<'a, 'tcx, M::Provenance, M::AllocExtra, M::Bytes>>> { - let parts = self.get_ptr_access(ptr, size, align)?; + let parts = self.get_ptr_access(ptr, size)?; if let Some((alloc_id, offset, prov)) = parts { let tcx = *self.tcx; // FIXME: can we somehow avoid looking up the allocation twice here? @@ -1023,7 +1026,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ptr: Pointer<Option<M::Provenance>>, size: Size, ) -> InterpResult<'tcx, &[u8]> { - let Some(alloc_ref) = self.get_ptr_alloc(ptr, size, Align::ONE)? else { + let Some(alloc_ref) = self.get_ptr_alloc(ptr, size)? else { // zero-sized access return Ok(&[]); }; @@ -1049,7 +1052,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { assert_eq!(lower, len, "can only write iterators with a precise length"); let size = Size::from_bytes(len); - let Some(alloc_ref) = self.get_ptr_alloc_mut(ptr, size, Align::ONE)? else { + let Some(alloc_ref) = self.get_ptr_alloc_mut(ptr, size)? else { // zero-sized access assert_matches!(src.next(), None, "iterator said it was empty but returned an element"); return Ok(()); @@ -1074,29 +1077,25 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn mem_copy( &mut self, src: Pointer<Option<M::Provenance>>, - src_align: Align, dest: Pointer<Option<M::Provenance>>, - dest_align: Align, size: Size, nonoverlapping: bool, ) -> InterpResult<'tcx> { - self.mem_copy_repeatedly(src, src_align, dest, dest_align, size, 1, nonoverlapping) + self.mem_copy_repeatedly(src, dest, size, 1, nonoverlapping) } pub fn mem_copy_repeatedly( &mut self, src: Pointer<Option<M::Provenance>>, - src_align: Align, dest: Pointer<Option<M::Provenance>>, - dest_align: Align, size: Size, num_copies: u64, nonoverlapping: bool, ) -> InterpResult<'tcx> { let tcx = self.tcx; // We need to do our own bounds-checks. - let src_parts = self.get_ptr_access(src, size, src_align)?; - let dest_parts = self.get_ptr_access(dest, size * num_copies, dest_align)?; // `Size` multiplication + let src_parts = self.get_ptr_access(src, size)?; + let dest_parts = self.get_ptr_access(dest, size * num_copies)?; // `Size` multiplication // FIXME: we look up both allocations twice here, once before for the `check_ptr_access` // and once below to get the underlying `&[mut] Allocation`. diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index 69eb22028fa..13664456987 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -26,7 +26,7 @@ pub use self::machine::{compile_time_machine, AllocMap, Machine, MayLeak, StackP pub use self::memory::{AllocKind, AllocRef, AllocRefMut, FnVal, Memory, MemoryKind}; pub use self::operand::{ImmTy, Immediate, OpTy, Readable}; pub use self::place::{MPlaceTy, MemPlaceMeta, PlaceTy, Writeable}; -pub use self::projection::Projectable; +pub use self::projection::{OffsetMode, Projectable}; pub use self::terminator::FnArg; pub use self::validity::{CtfeValidationMode, RefTracking}; pub use self::visitor::ValueVisitor; diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 99dba977a43..99424518ad4 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -10,11 +10,12 @@ use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter}; use rustc_middle::ty::{ConstInt, Ty, TyCtxt}; use rustc_middle::{mir, ty}; -use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size}; +use rustc_target::abi::{self, Abi, HasDataLayout, Size}; use super::{ alloc_range, from_known_layout, mir_assign_valid_types, AllocId, Frame, InterpCx, InterpResult, - MPlaceTy, Machine, MemPlace, MemPlaceMeta, PlaceTy, Pointer, Projectable, Provenance, Scalar, + MPlaceTy, Machine, MemPlace, MemPlaceMeta, OffsetMode, PlaceTy, Pointer, Projectable, + Provenance, Scalar, }; /// An `Immediate` represents a single immediate self-contained Rust value. @@ -43,12 +44,16 @@ impl<Prov: Provenance> From<Scalar<Prov>> for Immediate<Prov> { } impl<Prov: Provenance> Immediate<Prov> { - pub fn from_pointer(ptr: Pointer<Prov>, cx: &impl HasDataLayout) -> Self { - Immediate::Scalar(Scalar::from_pointer(ptr, cx)) - } - - pub fn from_maybe_pointer(ptr: Pointer<Option<Prov>>, cx: &impl HasDataLayout) -> Self { - Immediate::Scalar(Scalar::from_maybe_pointer(ptr, cx)) + pub fn new_pointer_with_meta( + ptr: Pointer<Option<Prov>>, + meta: MemPlaceMeta<Prov>, + cx: &impl HasDataLayout, + ) -> Self { + let ptr = Scalar::from_maybe_pointer(ptr, cx); + match meta { + MemPlaceMeta::None => Immediate::from(ptr), + MemPlaceMeta::Meta(meta) => Immediate::ScalarPair(ptr, meta), + } } pub fn new_slice(ptr: Pointer<Option<Prov>>, len: u64, cx: &impl HasDataLayout) -> Self { @@ -219,6 +224,17 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { /// given layout. // Not called `offset` to avoid confusion with the trait method. fn offset_(&self, offset: Size, layout: TyAndLayout<'tcx>, cx: &impl HasDataLayout) -> Self { + debug_assert!(layout.is_sized(), "unsized immediates are not a thing"); + // `ImmTy` have already been checked to be in-bounds, so we can just check directly if this + // remains in-bounds. This cannot actually be violated since projections are type-checked + // and bounds-checked. + assert!( + offset + layout.size <= self.layout.size, + "attempting to project to field at offset {} with size {} into immediate with layout {:#?}", + offset.bytes(), + layout.size.bytes(), + self.layout, + ); // This makes several assumptions about what layouts we will encounter; we match what // codegen does as good as we can (see `extract_field` in `rustc_codegen_ssa/src/mir/operand.rs`). let inner_val: Immediate<_> = match (**self, self.layout.abi) { @@ -286,6 +302,7 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for ImmTy<'tcx, Prov> { fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, offset: Size, + _mode: OffsetMode, meta: MemPlaceMeta<Prov>, layout: TyAndLayout<'tcx>, ecx: &InterpCx<'mir, 'tcx, M>, @@ -315,14 +332,6 @@ pub(super) enum Operand<Prov: Provenance = AllocId> { pub struct OpTy<'tcx, Prov: Provenance = AllocId> { op: Operand<Prov>, // Keep this private; it helps enforce invariants. pub layout: TyAndLayout<'tcx>, - /// rustc does not have a proper way to represent the type of a field of a `repr(packed)` struct: - /// it needs to have a different alignment than the field type would usually have. - /// So we represent this here with a separate field that "overwrites" `layout.align`. - /// This means `layout.align` should never be used for an `OpTy`! - /// `None` means "alignment does not matter since this is a by-value operand" - /// (`Operand::Immediate`); this field is only relevant for `Operand::Indirect`. - /// Also CTFE ignores alignment anyway, so this is for Miri only. - pub align: Option<Align>, } impl<Prov: Provenance> std::fmt::Debug for OpTy<'_, Prov> { @@ -338,18 +347,14 @@ impl<Prov: Provenance> std::fmt::Debug for OpTy<'_, Prov> { impl<'tcx, Prov: Provenance> From<ImmTy<'tcx, Prov>> for OpTy<'tcx, Prov> { #[inline(always)] fn from(val: ImmTy<'tcx, Prov>) -> Self { - OpTy { op: Operand::Immediate(val.imm), layout: val.layout, align: None } + OpTy { op: Operand::Immediate(val.imm), layout: val.layout } } } impl<'tcx, Prov: Provenance> From<MPlaceTy<'tcx, Prov>> for OpTy<'tcx, Prov> { #[inline(always)] fn from(mplace: MPlaceTy<'tcx, Prov>) -> Self { - OpTy { - op: Operand::Indirect(*mplace.mplace()), - layout: mplace.layout, - align: Some(mplace.align), - } + OpTy { op: Operand::Indirect(*mplace.mplace()), layout: mplace.layout } } } @@ -380,14 +385,14 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for OpTy<'tcx, Prov> { fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, offset: Size, + mode: OffsetMode, meta: MemPlaceMeta<Prov>, layout: TyAndLayout<'tcx>, ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, Self> { match self.as_mplace_or_imm() { - Left(mplace) => Ok(mplace.offset_with_meta(offset, meta, layout, ecx)?.into()), + Left(mplace) => Ok(mplace.offset_with_meta(offset, mode, meta, layout, ecx)?.into()), Right(imm) => { - debug_assert!(layout.is_sized(), "unsized immediates are not a thing"); assert_matches!(meta, MemPlaceMeta::None); // no place to store metadata here // Every part of an uninit is uninit. Ok(imm.offset_(offset, layout, ecx).into()) @@ -622,7 +627,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { throw_inval!(ConstPropNonsense); } } - Ok(OpTy { op, layout, align: Some(layout.align.abi) }) + Ok(OpTy { op, layout }) } /// Every place can be read from, so we can turn them into an operand. @@ -637,16 +642,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Right((frame, local, offset)) => { debug_assert!(place.layout.is_sized()); // only sized locals can ever be `Place::Local`. let base = self.local_to_op(&self.stack()[frame], local, None)?; - let mut field = match offset { + Ok(match offset { Some(offset) => base.offset(offset, place.layout, self)?, None => { // In the common case this hasn't been projected. debug_assert_eq!(place.layout, base.layout); base } - }; - field.align = Some(place.align); - Ok(field) + }) } } } @@ -734,27 +737,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }) }; let layout = from_known_layout(self.tcx, self.param_env, layout, || self.layout_of(ty))?; - let op = match val_val { + let imm = match val_val { mir::ConstValue::Indirect { alloc_id, offset } => { // We rely on mutability being set correctly in that allocation to prevent writes // where none should happen. let ptr = self.global_base_pointer(Pointer::new(alloc_id, offset))?; - Operand::Indirect(MemPlace::from_ptr(ptr.into())) + return Ok(self.ptr_to_mplace(ptr.into(), layout).into()); } - mir::ConstValue::Scalar(x) => Operand::Immediate(adjust_scalar(x)?.into()), - mir::ConstValue::ZeroSized => Operand::Immediate(Immediate::Uninit), + mir::ConstValue::Scalar(x) => adjust_scalar(x)?.into(), + mir::ConstValue::ZeroSized => Immediate::Uninit, mir::ConstValue::Slice { data, meta } => { // We rely on mutability being set correctly in `data` to prevent writes // where none should happen. let ptr = Pointer::new(self.tcx.reserve_and_set_memory_alloc(data), Size::ZERO); - Operand::Immediate(Immediate::new_slice( - self.global_base_pointer(ptr)?.into(), - meta, - self, - )) + Immediate::new_slice(self.global_base_pointer(ptr)?.into(), meta, self) } }; - Ok(OpTy { op, layout, align: Some(layout.align.abi) }) + Ok(OpTy { op: Operand::Immediate(imm), layout }) } } @@ -767,6 +766,6 @@ mod size_asserts { static_assert_size!(Immediate, 48); static_assert_size!(ImmTy<'_>, 64); static_assert_size!(Operand, 56); - static_assert_size!(OpTy<'_>, 80); + static_assert_size!(OpTy<'_>, 72); // tidy-alphabetical-end } diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 53e1756d897..a3ba9530f9d 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -1,7 +1,7 @@ use rustc_apfloat::{Float, FloatConvert}; use rustc_middle::mir; use rustc_middle::mir::interpret::{InterpResult, Scalar}; -use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, Ty}; use rustc_span::symbol::sym; use rustc_target::abi::Abi; @@ -337,7 +337,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let offset_count = right.to_scalar().to_target_isize(self)?; let pointee_ty = left.layout.ty.builtin_deref(true).unwrap().ty; - let offset_ptr = self.ptr_offset_inbounds(ptr, pointee_ty, offset_count)?; + // We cannot overflow i64 as a type's size must be <= isize::MAX. + let pointee_size = i64::try_from(self.layout_of(pointee_ty)?.size.bytes()).unwrap(); + // The computed offset, in bytes, must not overflow an isize. + // `checked_mul` enforces a too small bound, but no actual allocation can be big enough for + // the difference to be noticeable. + let offset_bytes = + offset_count.checked_mul(pointee_size).ok_or(err_ub!(PointerArithOverflow))?; + + let offset_ptr = self.ptr_offset_inbounds(ptr, offset_bytes)?; Ok(( ImmTy::from_scalar(Scalar::from_maybe_pointer(offset_ptr, self), left.layout), false, diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 9f95d2a3246..09ffdec7de7 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -15,9 +15,9 @@ use rustc_middle::ty::Ty; use rustc_target::abi::{Abi, Align, FieldIdx, HasDataLayout, Size, FIRST_VARIANT}; use super::{ - alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg, ImmTy, - Immediate, InterpCx, InterpResult, Machine, MemoryKind, OpTy, Operand, Pointer, - PointerArithmetic, Projectable, Provenance, Readable, Scalar, + alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckAlignMsg, ImmTy, + Immediate, InterpCx, InterpResult, Machine, MemoryKind, Misalignment, OffsetMode, OpTy, + Operand, Pointer, PointerArithmetic, Projectable, Provenance, Readable, Scalar, }; #[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] @@ -57,19 +57,11 @@ pub(super) struct MemPlace<Prov: Provenance = AllocId> { /// Must not be present for sized types, but can be missing for unsized types /// (e.g., `extern type`). pub meta: MemPlaceMeta<Prov>, + /// Stores whether this place was created based on a sufficiently aligned pointer. + misaligned: Option<Misalignment>, } impl<Prov: Provenance> MemPlace<Prov> { - #[inline(always)] - pub fn from_ptr(ptr: Pointer<Option<Prov>>) -> Self { - MemPlace { ptr, meta: MemPlaceMeta::None } - } - - #[inline(always)] - pub fn from_ptr_with_meta(ptr: Pointer<Option<Prov>>, meta: MemPlaceMeta<Prov>) -> Self { - MemPlace { ptr, meta } - } - /// Adjust the provenance of the main pointer (metadata is unaffected). pub fn map_provenance(self, f: impl FnOnce(Option<Prov>) -> Option<Prov>) -> Self { MemPlace { ptr: self.ptr.map_provenance(f), ..self } @@ -78,27 +70,32 @@ impl<Prov: Provenance> MemPlace<Prov> { /// Turn a mplace into a (thin or wide) pointer, as a reference, pointing to the same space. #[inline] pub fn to_ref(self, cx: &impl HasDataLayout) -> Immediate<Prov> { - match self.meta { - MemPlaceMeta::None => Immediate::from(Scalar::from_maybe_pointer(self.ptr, cx)), - MemPlaceMeta::Meta(meta) => { - Immediate::ScalarPair(Scalar::from_maybe_pointer(self.ptr, cx), meta) - } - } + Immediate::new_pointer_with_meta(self.ptr, self.meta, cx) } #[inline] // Not called `offset_with_meta` to avoid confusion with the trait method. - fn offset_with_meta_<'tcx>( + fn offset_with_meta_<'mir, 'tcx, M: Machine<'mir, 'tcx, Provenance = Prov>>( self, offset: Size, + mode: OffsetMode, meta: MemPlaceMeta<Prov>, - cx: &impl HasDataLayout, + ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, Self> { debug_assert!( !meta.has_meta() || self.meta.has_meta(), "cannot use `offset_with_meta` to add metadata to a place" ); - Ok(MemPlace { ptr: self.ptr.offset(offset, cx)?, meta }) + if offset > ecx.data_layout().max_size_of_val() { + throw_ub!(PointerArithOverflow); + } + let ptr = match mode { + OffsetMode::Inbounds => { + ecx.ptr_offset_inbounds(self.ptr, offset.bytes().try_into().unwrap())? + } + OffsetMode::Wrapping => self.ptr.wrapping_offset(offset, ecx), + }; + Ok(MemPlace { ptr, meta, misaligned: self.misaligned }) } } @@ -107,11 +104,6 @@ impl<Prov: Provenance> MemPlace<Prov> { pub struct MPlaceTy<'tcx, Prov: Provenance = AllocId> { mplace: MemPlace<Prov>, pub layout: TyAndLayout<'tcx>, - /// rustc does not have a proper way to represent the type of a field of a `repr(packed)` struct: - /// it needs to have a different alignment than the field type would usually have. - /// So we represent this here with a separate field that "overwrites" `layout.align`. - /// This means `layout.align` should never be used for a `MPlaceTy`! - pub align: Align, } impl<Prov: Provenance> std::fmt::Debug for MPlaceTy<'_, Prov> { @@ -133,25 +125,7 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> { assert!(layout.is_zst()); let align = layout.align.abi; let ptr = Pointer::from_addr_invalid(align.bytes()); // no provenance, absolute address - MPlaceTy { mplace: MemPlace { ptr, meta: MemPlaceMeta::None }, layout, align } - } - - #[inline] - pub fn from_aligned_ptr(ptr: Pointer<Option<Prov>>, layout: TyAndLayout<'tcx>) -> Self { - MPlaceTy { mplace: MemPlace::from_ptr(ptr), layout, align: layout.align.abi } - } - - #[inline] - pub fn from_aligned_ptr_with_meta( - ptr: Pointer<Option<Prov>>, - layout: TyAndLayout<'tcx>, - meta: MemPlaceMeta<Prov>, - ) -> Self { - MPlaceTy { - mplace: MemPlace::from_ptr_with_meta(ptr, meta), - layout, - align: layout.align.abi, - } + MPlaceTy { mplace: MemPlace { ptr, meta: MemPlaceMeta::None, misaligned: None }, layout } } /// Adjust the provenance of the main pointer (metadata is unaffected). @@ -189,15 +163,12 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for MPlaceTy<'tcx, Prov> { fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, offset: Size, + mode: OffsetMode, meta: MemPlaceMeta<Prov>, layout: TyAndLayout<'tcx>, ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, Self> { - Ok(MPlaceTy { - mplace: self.mplace.offset_with_meta_(offset, meta, ecx)?, - align: self.align.restrict_for_offset(offset), - layout, - }) + Ok(MPlaceTy { mplace: self.mplace.offset_with_meta_(offset, mode, meta, ecx)?, layout }) } fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( @@ -228,11 +199,6 @@ pub(super) enum Place<Prov: Provenance = AllocId> { pub struct PlaceTy<'tcx, Prov: Provenance = AllocId> { place: Place<Prov>, // Keep this private; it helps enforce invariants. pub layout: TyAndLayout<'tcx>, - /// rustc does not have a proper way to represent the type of a field of a `repr(packed)` struct: - /// it needs to have a different alignment than the field type would usually have. - /// So we represent this here with a separate field that "overwrites" `layout.align`. - /// This means `layout.align` should never be used for a `PlaceTy`! - pub align: Align, } impl<Prov: Provenance> std::fmt::Debug for PlaceTy<'_, Prov> { @@ -248,7 +214,7 @@ impl<Prov: Provenance> std::fmt::Debug for PlaceTy<'_, Prov> { impl<'tcx, Prov: Provenance> From<MPlaceTy<'tcx, Prov>> for PlaceTy<'tcx, Prov> { #[inline(always)] fn from(mplace: MPlaceTy<'tcx, Prov>) -> Self { - PlaceTy { place: Place::Ptr(mplace.mplace), layout: mplace.layout, align: mplace.align } + PlaceTy { place: Place::Ptr(mplace.mplace), layout: mplace.layout } } } @@ -264,7 +230,7 @@ impl<'tcx, Prov: Provenance> PlaceTy<'tcx, Prov> { &self, ) -> Either<MPlaceTy<'tcx, Prov>, (usize, mir::Local, Option<Size>)> { match self.place { - Place::Ptr(mplace) => Left(MPlaceTy { mplace, layout: self.layout, align: self.align }), + Place::Ptr(mplace) => Left(MPlaceTy { mplace, layout: self.layout }), Place::Local { frame, local, offset } => Right((frame, local, offset)), } } @@ -301,27 +267,27 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for PlaceTy<'tcx, Prov> { fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, offset: Size, + mode: OffsetMode, meta: MemPlaceMeta<Prov>, layout: TyAndLayout<'tcx>, ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, Self> { Ok(match self.as_mplace_or_local() { - Left(mplace) => mplace.offset_with_meta(offset, meta, layout, ecx)?.into(), + Left(mplace) => mplace.offset_with_meta(offset, mode, meta, layout, ecx)?.into(), Right((frame, local, old_offset)) => { debug_assert!(layout.is_sized(), "unsized locals should live in memory"); assert_matches!(meta, MemPlaceMeta::None); // we couldn't store it anyway... - let new_offset = ecx - .data_layout() - .offset(old_offset.unwrap_or(Size::ZERO).bytes(), offset.bytes())?; - PlaceTy { - place: Place::Local { - frame, - local, - offset: Some(Size::from_bytes(new_offset)), - }, - align: self.align.restrict_for_offset(offset), - layout, - } + // `Place::Local` are always in-bounds of their surrounding local, so we can just + // check directly if this remains in-bounds. This cannot actually be violated since + // projections are type-checked and bounds-checked. + assert!(offset + layout.size <= self.layout.size); + + let new_offset = Size::from_bytes( + ecx.data_layout() + .offset(old_offset.unwrap_or(Size::ZERO).bytes(), offset.bytes())?, + ); + + PlaceTy { place: Place::Local { frame, local, offset: Some(new_offset) }, layout } } }) } @@ -339,9 +305,7 @@ impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> { #[inline(always)] pub fn as_mplace_or_imm(&self) -> Either<MPlaceTy<'tcx, Prov>, ImmTy<'tcx, Prov>> { match self.op() { - Operand::Indirect(mplace) => { - Left(MPlaceTy { mplace: *mplace, layout: self.layout, align: self.align.unwrap() }) - } + Operand::Indirect(mplace) => Left(MPlaceTy { mplace: *mplace, layout: self.layout }), Operand::Immediate(imm) => Right(ImmTy::from_immediate(*imm, self.layout)), } } @@ -362,7 +326,7 @@ impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> { pub trait Writeable<'tcx, Prov: Provenance>: Projectable<'tcx, Prov> { fn as_mplace_or_local( &self, - ) -> Either<MPlaceTy<'tcx, Prov>, (usize, mir::Local, Option<Size>, Align, TyAndLayout<'tcx>)>; + ) -> Either<MPlaceTy<'tcx, Prov>, (usize, mir::Local, Option<Size>, TyAndLayout<'tcx>)>; fn force_mplace<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, @@ -374,10 +338,9 @@ impl<'tcx, Prov: Provenance> Writeable<'tcx, Prov> for PlaceTy<'tcx, Prov> { #[inline(always)] fn as_mplace_or_local( &self, - ) -> Either<MPlaceTy<'tcx, Prov>, (usize, mir::Local, Option<Size>, Align, TyAndLayout<'tcx>)> - { + ) -> Either<MPlaceTy<'tcx, Prov>, (usize, mir::Local, Option<Size>, TyAndLayout<'tcx>)> { self.as_mplace_or_local() - .map_right(|(frame, local, offset)| (frame, local, offset, self.align, self.layout)) + .map_right(|(frame, local, offset)| (frame, local, offset, self.layout)) } #[inline(always)] @@ -393,8 +356,7 @@ impl<'tcx, Prov: Provenance> Writeable<'tcx, Prov> for MPlaceTy<'tcx, Prov> { #[inline(always)] fn as_mplace_or_local( &self, - ) -> Either<MPlaceTy<'tcx, Prov>, (usize, mir::Local, Option<Size>, Align, TyAndLayout<'tcx>)> - { + ) -> Either<MPlaceTy<'tcx, Prov>, (usize, mir::Local, Option<Size>, TyAndLayout<'tcx>)> { Left(self.clone()) } @@ -413,6 +375,25 @@ where Prov: Provenance, M: Machine<'mir, 'tcx, Provenance = Prov>, { + pub fn ptr_with_meta_to_mplace( + &self, + ptr: Pointer<Option<M::Provenance>>, + meta: MemPlaceMeta<M::Provenance>, + layout: TyAndLayout<'tcx>, + ) -> MPlaceTy<'tcx, M::Provenance> { + let misaligned = self.is_ptr_misaligned(ptr, layout.align.abi); + MPlaceTy { mplace: MemPlace { ptr, meta, misaligned }, layout } + } + + pub fn ptr_to_mplace( + &self, + ptr: Pointer<Option<M::Provenance>>, + layout: TyAndLayout<'tcx>, + ) -> MPlaceTy<'tcx, M::Provenance> { + assert!(layout.is_sized()); + self.ptr_with_meta_to_mplace(ptr, MemPlaceMeta::None, layout) + } + /// Take a value, which represents a (thin or wide) reference, and make it a place. /// Alignment is just based on the type. This is the inverse of `mplace_to_ref()`. /// @@ -434,7 +415,8 @@ where // `ref_to_mplace` is called on raw pointers even if they don't actually get dereferenced; // we hence can't call `size_and_align_of` since that asserts more validity than we want. - Ok(MPlaceTy::from_aligned_ptr_with_meta(ptr.to_pointer(self)?, layout, meta)) + let ptr = ptr.to_pointer(self)?; + Ok(self.ptr_with_meta_to_mplace(ptr, meta, layout)) } /// Turn a mplace into a (thin or wide) mutable raw pointer, pointing to the same space. @@ -464,7 +446,6 @@ where } let mplace = self.ref_to_mplace(&val)?; - self.check_mplace(&mplace)?; Ok(mplace) } @@ -477,8 +458,11 @@ where let (size, _align) = self .size_and_align_of_mplace(&mplace)? .unwrap_or((mplace.layout.size, mplace.layout.align.abi)); - // Due to packed places, only `mplace.align` matters. - self.get_ptr_alloc(mplace.ptr(), size, mplace.align) + // We check alignment separately, and *after* checking everything else. + // If an access is both OOB and misaligned, we want to see the bounds error. + let a = self.get_ptr_alloc(mplace.ptr(), size)?; + self.check_misalign(mplace.mplace.misaligned, CheckAlignMsg::BasedOn)?; + Ok(a) } #[inline] @@ -490,19 +474,13 @@ where let (size, _align) = self .size_and_align_of_mplace(&mplace)? .unwrap_or((mplace.layout.size, mplace.layout.align.abi)); - // Due to packed places, only `mplace.align` matters. - self.get_ptr_alloc_mut(mplace.ptr(), size, mplace.align) - } - - /// Check if this mplace is dereferenceable and sufficiently aligned. - pub fn check_mplace(&self, mplace: &MPlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> { - let (size, _align) = self - .size_and_align_of_mplace(&mplace)? - .unwrap_or((mplace.layout.size, mplace.layout.align.abi)); - // Due to packed places, only `mplace.align` matters. - let align = if M::enforce_alignment(self) { mplace.align } else { Align::ONE }; - self.check_ptr_access_align(mplace.ptr(), size, align, CheckInAllocMsg::DerefTest)?; - Ok(()) + // We check alignment separately, and raise that error *after* checking everything else. + // If an access is both OOB and misaligned, we want to see the bounds error. + // However we have to call `check_misalign` first to make the borrow checker happy. + let misalign_err = self.check_misalign(mplace.mplace.misaligned, CheckAlignMsg::BasedOn); + let a = self.get_ptr_alloc_mut(mplace.ptr(), size)?; + misalign_err?; + Ok(a) } /// Converts a repr(simd) place into a place where `place_index` accesses the SIMD elements. @@ -517,8 +495,8 @@ where let (len, e_ty) = mplace.layout.ty.simd_size_and_type(*self.tcx); let array = Ty::new_array(self.tcx.tcx, e_ty, len); let layout = self.layout_of(array)?; - assert_eq!(layout.size, mplace.layout.size); - Ok((MPlaceTy { layout, ..*mplace }, len)) + let mplace = mplace.transmute(layout, self)?; + Ok((mplace, len)) } /// Converts a repr(simd) place into a place where `place_index` accesses the SIMD elements. @@ -554,7 +532,7 @@ where Operand::Indirect(mplace) => Place::Ptr(*mplace), } }; - Ok(PlaceTy { place, layout, align: layout.align.abi }) + Ok(PlaceTy { place, layout }) } /// Computes a place. You should only use this if you intend to write into this @@ -644,7 +622,7 @@ where // See if we can avoid an allocation. This is the counterpart to `read_immediate_raw`, // but not factored as a separate function. let mplace = match dest.as_mplace_or_local() { - Right((frame, local, offset, align, layout)) => { + Right((frame, local, offset, layout)) => { if offset.is_some() { // This has been projected to a part of this local. We could have complicated // logic to still keep this local as an `Operand`... but it's much easier to @@ -685,7 +663,7 @@ where } Operand::Indirect(mplace) => { // The local is in memory, go on below. - MPlaceTy { mplace: *mplace, align, layout } + MPlaceTy { mplace: *mplace, layout } } } } @@ -694,7 +672,7 @@ where }; // This is already in memory, write there. - self.write_immediate_to_mplace_no_validate(src, mplace.layout, mplace.align, mplace.mplace) + self.write_immediate_to_mplace_no_validate(src, mplace.layout, mplace.mplace) } /// Write an immediate to memory. @@ -704,7 +682,6 @@ where &mut self, value: Immediate<M::Provenance>, layout: TyAndLayout<'tcx>, - align: Align, dest: MemPlace<M::Provenance>, ) -> InterpResult<'tcx> { // Note that it is really important that the type here is the right one, and matches the @@ -713,9 +690,7 @@ where // wrong type. let tcx = *self.tcx; - let Some(mut alloc) = - self.get_place_alloc_mut(&MPlaceTy { mplace: dest, layout, align })? - else { + let Some(mut alloc) = self.get_place_alloc_mut(&MPlaceTy { mplace: dest, layout })? else { // zero-sized access return Ok(()); }; @@ -733,9 +708,6 @@ where alloc.write_scalar(alloc_range(Size::ZERO, size), scalar) } Immediate::ScalarPair(a_val, b_val) => { - // We checked `ptr_align` above, so all fields will have the alignment they need. - // We would anyway check against `ptr_align.restrict_for_offset(b_offset)`, - // which `ptr.offset(b_offset)` cannot possibly fail to satisfy. let Abi::ScalarPair(a, b) = layout.abi else { span_bug!( self.cur_span(), @@ -764,7 +736,7 @@ where ) -> InterpResult<'tcx> { let mplace = match dest.as_mplace_or_local() { Left(mplace) => mplace, - Right((frame, local, offset, align, layout)) => { + Right((frame, local, offset, layout)) => { if offset.is_some() { // This has been projected to a part of this local. We could have complicated // logic to still keep this local as an `Operand`... but it's much easier to @@ -780,7 +752,7 @@ where } Operand::Indirect(mplace) => { // The local is in memory, go on below. - MPlaceTy { mplace: *mplace, layout, align } + MPlaceTy { mplace: *mplace, layout } } } } @@ -873,7 +845,6 @@ where self.write_immediate_to_mplace_no_validate( *src_val, src.layout(), - dest_mem.align, dest_mem.mplace, ) }; @@ -900,14 +871,12 @@ where // type does not have Scalar/ScalarPair layout. // (Or as the `Assign` docs put it, assignments "not producing primitives" must be // non-overlapping.) - self.mem_copy( - src.ptr(), - src.align, - dest.ptr(), - dest.align, - dest_size, - /*nonoverlapping*/ true, - ) + // We check alignment separately, and *after* checking everything else. + // If an access is both OOB and misaligned, we want to see the bounds error. + self.mem_copy(src.ptr(), dest.ptr(), dest_size, /*nonoverlapping*/ true)?; + self.check_misalign(src.mplace.misaligned, CheckAlignMsg::BasedOn)?; + self.check_misalign(dest.mplace.misaligned, CheckAlignMsg::BasedOn)?; + Ok(()) } /// Ensures that a place is in memory, and returns where it is. @@ -941,7 +910,6 @@ where self.write_immediate_to_mplace_no_validate( local_val, local_layout, - local_layout.align.abi, mplace.mplace, )?; } @@ -956,7 +924,13 @@ where &mut Operand::Indirect(mplace) => mplace, // this already was an indirect local }; if let Some(offset) = offset { - whole_local.offset_with_meta_(offset, MemPlaceMeta::None, self)? + // This offset is always inbounds, no need to check it again. + whole_local.offset_with_meta_( + offset, + OffsetMode::Wrapping, + MemPlaceMeta::None, + self, + )? } else { // Preserve wide place metadata, do not call `offset`. whole_local @@ -965,7 +939,7 @@ where Place::Ptr(mplace) => mplace, }; // Return with the original layout and align, so that the caller can go on - Ok(MPlaceTy { mplace, layout: place.layout, align: place.align }) + Ok(MPlaceTy { mplace, layout: place.layout }) } pub fn allocate_dyn( @@ -978,7 +952,7 @@ where span_bug!(self.cur_span(), "cannot allocate space for `extern` type, size is not known") }; let ptr = self.allocate_ptr(size, align, kind)?; - Ok(MPlaceTy::from_aligned_ptr_with_meta(ptr.into(), layout, meta)) + Ok(self.ptr_with_meta_to_mplace(ptr.into(), meta, layout)) } pub fn allocate( @@ -990,7 +964,7 @@ where self.allocate_dyn(layout, kind, MemPlaceMeta::None) } - /// Returns a wide MPlace of type `&'static [mut] str` to a new 1-aligned allocation. + /// Returns a wide MPlace of type `str` to a new 1-aligned allocation. pub fn allocate_str( &mut self, str: &str, @@ -999,15 +973,8 @@ where ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> { let ptr = self.allocate_bytes_ptr(str.as_bytes(), Align::ONE, kind, mutbl)?; let meta = Scalar::from_target_usize(u64::try_from(str.len()).unwrap(), self); - let mplace = MemPlace { ptr: ptr.into(), meta: MemPlaceMeta::Meta(meta) }; - - let ty = Ty::new_ref( - self.tcx.tcx, - self.tcx.lifetimes.re_static, - ty::TypeAndMut { ty: self.tcx.types.str_, mutbl }, - ); - let layout = self.layout_of(ty).unwrap(); - Ok(MPlaceTy { mplace, layout, align: layout.align.abi }) + let layout = self.layout_of(self.tcx.types.str_).unwrap(); + Ok(self.ptr_with_meta_to_mplace(ptr.into(), MemPlaceMeta::Meta(meta), layout)) } /// Writes the aggregate to the destination. @@ -1046,7 +1013,7 @@ where let _ = self.tcx.global_alloc(raw.alloc_id); let ptr = self.global_base_pointer(Pointer::from(raw.alloc_id))?; let layout = self.layout_of(raw.ty)?; - Ok(MPlaceTy::from_aligned_ptr(ptr.into(), layout)) + Ok(self.ptr_to_mplace(ptr.into(), layout)) } /// Turn a place with a `dyn Trait` type into a place with the actual dynamic type. @@ -1062,12 +1029,10 @@ where let vtable = mplace.meta().unwrap_meta().to_pointer(self)?; let (ty, _) = self.get_ptr_vtable(vtable)?; let layout = self.layout_of(ty)?; - - let mplace = MPlaceTy { - mplace: MemPlace { meta: MemPlaceMeta::None, ..mplace.mplace }, - layout, - align: layout.align.abi, - }; + // This is a kind of transmute, from a place with unsized type and metadata to + // a place with sized type and no metadata. + let mplace = + MPlaceTy { mplace: MemPlace { meta: MemPlaceMeta::None, ..mplace.mplace }, layout }; Ok((mplace, vtable)) } @@ -1099,10 +1064,10 @@ mod size_asserts { use super::*; use rustc_data_structures::static_assert_size; // tidy-alphabetical-start - static_assert_size!(MemPlace, 40); + static_assert_size!(MemPlace, 48); static_assert_size!(MemPlaceMeta, 24); static_assert_size!(MPlaceTy<'_>, 64); - static_assert_size!(Place, 40); + static_assert_size!(Place, 48); static_assert_size!(PlaceTy<'_>, 64); // tidy-alphabetical-end } diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 70df3d8fd78..6694c43c992 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -19,6 +19,15 @@ use rustc_target::abi::{self, VariantIdx}; use super::{InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Provenance, Scalar}; +/// Describes the constraints placed on offset-projections. +#[derive(Copy, Clone, Debug)] +pub enum OffsetMode { + /// The offset has to be inbounds, like `ptr::offset`. + Inbounds, + /// No constraints, just wrap around the edge of the address space. + Wrapping, +} + /// A thing that we can project into, and that has a layout. pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug { /// Get the layout. @@ -53,12 +62,12 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug { fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, offset: Size, + mode: OffsetMode, meta: MemPlaceMeta<Prov>, layout: TyAndLayout<'tcx>, ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, Self>; - #[inline] fn offset<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, offset: Size, @@ -66,10 +75,9 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug { ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, Self> { assert!(layout.is_sized()); - self.offset_with_meta(offset, MemPlaceMeta::None, layout, ecx) + self.offset_with_meta(offset, OffsetMode::Inbounds, MemPlaceMeta::None, layout, ecx) } - #[inline] fn transmute<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( &self, layout: TyAndLayout<'tcx>, @@ -77,7 +85,7 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug { ) -> InterpResult<'tcx, Self> { assert!(self.layout().is_sized() && layout.is_sized()); assert_eq!(self.layout().size, layout.size); - self.offset_with_meta(Size::ZERO, MemPlaceMeta::None, layout, ecx) + self.offset_with_meta(Size::ZERO, OffsetMode::Wrapping, MemPlaceMeta::None, layout, ecx) } /// Convert this to an `OpTy`. This might be an irreversible transformation, but is useful for @@ -104,7 +112,17 @@ impl<'tcx, 'a, Prov: Provenance, P: Projectable<'tcx, Prov>> ArrayIterator<'tcx, ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, Option<(u64, P)>> { let Some(idx) = self.range.next() else { return Ok(None) }; - Ok(Some((idx, self.base.offset(self.stride * idx, self.field_layout, ecx)?))) + // We use `Wrapping` here since the offset has already been checked when the iterator was created. + Ok(Some(( + idx, + self.base.offset_with_meta( + self.stride * idx, + OffsetMode::Wrapping, + MemPlaceMeta::None, + self.field_layout, + ecx, + )?, + ))) } } @@ -159,7 +177,7 @@ where (MemPlaceMeta::None, offset) }; - base.offset_with_meta(offset, meta, field_layout, self) + base.offset_with_meta(offset, OffsetMode::Inbounds, meta, field_layout, self) } /// Downcasting to an enum variant. @@ -248,6 +266,10 @@ where }; let len = base.len(self)?; let field_layout = base.layout().field(self, 0); + // Ensure that all the offsets are in-bounds once, up-front. + debug!("project_array_fields: {base:?} {len}"); + base.offset(len * stride, self.layout_of(self.tcx.types.unit).unwrap(), self)?; + // Create the iterator. Ok(ArrayIterator { base, range: 0..len, stride, field_layout, _phantom: PhantomData }) } @@ -305,7 +327,7 @@ where }; let layout = self.layout_of(ty)?; - base.offset_with_meta(from_offset, meta, layout, self) + base.offset_with_meta(from_offset, OffsetMode::Inbounds, meta, layout, self) } /// Applying a general projection diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 284e13407f7..79cbda545f1 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -206,15 +206,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let elem_size = first.layout.size; let first_ptr = first.ptr(); let rest_ptr = first_ptr.offset(elem_size, self)?; - // For the alignment of `rest_ptr`, we crucially do *not* use `first.align` as - // that place might be more aligned than its type mandates (a `u8` array could - // be 4-aligned if it sits at the right spot in a struct). We have to also factor - // in element size. + // No alignment requirement since `copy_op` above already checked it. self.mem_copy_repeatedly( first_ptr, - dest.align, rest_ptr, - dest.align.restrict_for_offset(elem_size), elem_size, length - 1, /*nonoverlapping:*/ true, @@ -268,7 +263,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { NullaryOp(ref null_op, ty) => { let ty = self.subst_from_current_frame_and_normalize_erasing_regions(ty)?; let layout = self.layout_of(ty)?; - if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op && layout.is_unsized() { + if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op + && layout.is_unsized() + { span_bug!( self.frame().current_span(), "{null_op:?} MIR operator called for unsized type {ty}", diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 578dd6622aa..59e89819880 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -1,6 +1,5 @@ use std::borrow::Cow; -use either::Either; use rustc_ast::ast::InlineAsmOptions; use rustc_middle::{ mir, @@ -729,13 +728,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { callee_ty: callee_fn_abi.ret.layout.ty }); } - // Ensure the return place is aligned and dereferenceable, and protect it for - // in-place return value passing. - if let Either::Left(mplace) = destination.as_mplace_or_local() { - self.check_mplace(&mplace)?; - } else { - // Nothing to do for locals, they are always properly allocated and aligned. - } + // Protect return place for in-place return value passing. M::protect_in_place_function_argument(self, destination)?; // Don't forget to mark "initially live" locals as live. @@ -890,11 +883,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } fn check_fn_target_features(&self, instance: ty::Instance<'tcx>) -> InterpResult<'tcx, ()> { + // Calling functions with `#[target_feature]` is not unsafe on WASM, see #84988 let attrs = self.tcx.codegen_fn_attrs(instance.def_id()); - if attrs - .target_features - .iter() - .any(|feature| !self.tcx.sess.target_features.contains(feature)) + if !self.tcx.sess.target.is_like_wasm + && attrs + .target_features + .iter() + .any(|feature| !self.tcx.sess.target_features.contains(feature)) { throw_ub_custom!( fluent::const_eval_unavailable_target_features_for_fn, diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 3e023a89648..082e5466fe2 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -13,7 +13,7 @@ use rustc_ast::Mutability; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_middle::mir::interpret::{ - ExpectedKind, InterpError, InvalidMetaKind, PointerKind, ValidationErrorInfo, + ExpectedKind, InterpError, InvalidMetaKind, Misalignment, PointerKind, ValidationErrorInfo, ValidationErrorKind, ValidationErrorKind::*, }; use rustc_middle::ty; @@ -355,7 +355,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' value: &OpTy<'tcx, M::Provenance>, ptr_kind: PointerKind, ) -> InterpResult<'tcx> { - // Not using `deref_pointer` since we do the dereferenceable check ourselves below. + // Not using `deref_pointer` since we want to use our `read_immediate` wrapper. let place = self.ecx.ref_to_mplace(&self.read_immediate(value, ptr_kind.into())?)?; // Handle wide pointers. // Check metadata early, for better diagnostics @@ -378,18 +378,12 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' .unwrap_or_else(|| (place.layout.size, place.layout.align.abi)); // Direct call to `check_ptr_access_align` checks alignment even on CTFE machines. try_validation!( - self.ecx.check_ptr_access_align( + self.ecx.check_ptr_access( place.ptr(), size, - align, CheckInAllocMsg::InboundsTest, // will anyway be replaced by validity message ), self.path, - Ub(AlignmentCheckFailed { required, has }) => UnalignedPtr { - ptr_kind, - required_bytes: required.bytes(), - found_bytes: has.bytes() - }, Ub(DanglingIntPointer(0, _)) => NullPtr { ptr_kind }, Ub(DanglingIntPointer(i, _)) => DanglingPtrNoProvenance { ptr_kind, @@ -405,6 +399,18 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' ptr_kind, }, ); + try_validation!( + self.ecx.check_ptr_align( + place.ptr(), + align, + ), + self.path, + Ub(AlignmentCheckFailed(Misalignment { required, has }, _msg)) => UnalignedPtr { + ptr_kind, + required_bytes: required.bytes(), + found_bytes: has.bytes() + }, + ); // Do not allow pointers to uninhabited types. if place.layout.abi.is_uninhabited() { let ty = place.layout.ty; @@ -645,7 +651,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> #[inline(always)] fn ecx(&self) -> &InterpCx<'mir, 'tcx, M> { - &self.ecx + self.ecx } fn read_discriminant( @@ -781,14 +787,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> // Optimization: we just check the entire range at once. // NOTE: Keep this in sync with the handling of integer and float // types above, in `visit_primitive`. - // In run-time mode, we accept pointers in here. This is actually more - // permissive than a per-element check would be, e.g., we accept - // a &[u8] that contains a pointer even though bytewise checking would - // reject it. However, that's good: We don't inherently want - // to reject those pointers, we just do not have the machinery to - // talk about parts of a pointer. - // We also accept uninit, for consistency with the slow path. - let alloc = self.ecx.get_ptr_alloc(mplace.ptr(), size, mplace.align)?.expect("we already excluded size 0"); + // No need for an alignment check here, this is not an actual memory access. + let alloc = self.ecx.get_ptr_alloc(mplace.ptr(), size)?.expect("we already excluded size 0"); match alloc.get_bytes_strip_provenance() { // In the happy case, we needn't check anything else. diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 8bb409cea08..1fd5723f277 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -4,6 +4,9 @@ Rust MIR: a lowered representation of Rust. */ +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] #![deny(rustc::untranslatable_diagnostic)] #![feature(assert_matches)] #![feature(box_patterns)] 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 f8f9bfb0470..92e7922ad3b 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -9,16 +9,17 @@ use rustc_infer::traits::{ImplSource, Obligation, ObligationCause}; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::traits::BuiltinImplSource; +use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, InstanceDef, Ty, TyCtxt}; -use rustc_middle::ty::{GenericArgKind, GenericArgs}; use rustc_middle::ty::{TraitRef, TypeVisitableExt}; use rustc_mir_dataflow::{self, Analysis}; use rustc_span::{sym, Span, Symbol}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt, SelectionContext}; +use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitor}; use std::mem; -use std::ops::Deref; +use std::ops::{ControlFlow, Deref}; use super::ops::{self, NonConstOp, Status}; use super::qualifs::{self, CustomEq, HasMutInterior, NeedsDrop}; @@ -188,6 +189,24 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> { } } +struct LocalReturnTyVisitor<'ck, 'mir, 'tcx> { + kind: LocalKind, + checker: &'ck mut Checker<'mir, 'tcx>, +} + +impl<'ck, 'mir, 'tcx> TypeVisitor<TyCtxt<'tcx>> for LocalReturnTyVisitor<'ck, 'mir, 'tcx> { + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { + match t.kind() { + ty::FnPtr(_) => ControlFlow::Continue(()), + ty::Ref(_, _, hir::Mutability::Mut) => { + self.checker.check_op(ops::ty::MutRef(self.kind)); + t.super_visit_with(self) + } + _ => t.super_visit_with(self), + } + } +} + pub struct Checker<'mir, 'tcx> { ccx: &'mir ConstCx<'mir, 'tcx>, qualifs: Qualifs<'mir, 'tcx>, @@ -304,7 +323,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { let gate = match op.status_in_item(self.ccx) { Status::Allowed => return, - Status::Unstable(gate) if self.tcx.features().enabled(gate) => { + Status::Unstable(gate) if self.tcx.features().active(gate) => { let unstable_in_stable = self.ccx.is_const_stable_const_fn() && !super::rustc_allow_const_fn_unstable(self.tcx, self.def_id(), gate); if unstable_in_stable { @@ -346,20 +365,9 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { fn check_local_or_return_ty(&mut self, ty: Ty<'tcx>, local: Local) { let kind = self.body.local_kind(local); - for ty in ty.walk() { - let ty = match ty.unpack() { - GenericArgKind::Type(ty) => ty, - - // No constraints on lifetimes or constants, except potentially - // constants' types, but `walk` will get to them as well. - GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => continue, - }; + let mut visitor = LocalReturnTyVisitor { kind, checker: self }; - match *ty.kind() { - ty::Ref(_, _, hir::Mutability::Mut) => self.check_op(ops::ty::MutRef(kind)), - _ => {} - } - } + visitor.visit_ty(ty); } fn check_mut_borrow(&mut self, local: Local, kind: hir::BorrowKind) { @@ -456,7 +464,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { Rvalue::Aggregate(kind, ..) => { if let AggregateKind::Generator(def_id, ..) = kind.as_ref() - && let Some(generator_kind @ hir::GeneratorKind::Async(..)) = self.tcx.generator_kind(def_id) + && let Some(generator_kind @ hir::GeneratorKind::Async(..)) = + self.tcx.generator_kind(def_id) { self.check_op(ops::Generator(generator_kind)); } @@ -571,8 +580,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } } - Rvalue::BinaryOp(op, box (lhs, rhs)) - | Rvalue::CheckedBinaryOp(op, box (lhs, rhs)) => { + Rvalue::BinaryOp(op, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(op, box (lhs, rhs)) => { let lhs_ty = lhs.ty(self.body, self.tcx); let rhs_ty = rhs.ty(self.body, self.tcx); @@ -580,18 +588,16 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // Int, bool, and char operations are fine. } else if lhs_ty.is_fn_ptr() || lhs_ty.is_unsafe_ptr() { assert_eq!(lhs_ty, rhs_ty); - assert!( - matches!( - op, - BinOp::Eq + assert!(matches!( + op, + BinOp::Eq | BinOp::Ne | BinOp::Le | BinOp::Lt | BinOp::Ge | BinOp::Gt | BinOp::Offset - ) - ); + )); self.check_op(ops::RawPtrComparison); } else if lhs_ty.is_floating_point() || rhs_ty.is_floating_point() { @@ -939,7 +945,9 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { if self.span.allows_unstable(gate) { return; } - if let Some(implied_by_gate) = implied_by && self.span.allows_unstable(implied_by_gate) { + if let Some(implied_by_gate) = implied_by + && self.span.allows_unstable(implied_by_gate) + { return; } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 1f3cda35c2b..e8d1d595820 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -311,10 +311,10 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { ccx.const_kind(), )); - if let Some(feature) = feature && ccx.tcx.sess.is_nightly_build() { - err.help(format!( - "add `#![feature({feature})]` to the crate attributes to enable", - )); + if let Some(feature) = feature + && ccx.tcx.sess.is_nightly_build() + { + err.help(format!("add `#![feature({feature})]` to the crate attributes to enable",)); } if let ConstContext::Static(_) = ccx.const_kind() { diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 461ec3a90ed..420f7c4f17f 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -6,6 +6,8 @@ //! //! This API is completely unstable and subject to change. +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(array_windows)] #![feature(associated_type_bounds)] diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 0cd0b51b6ad..27f08fe7eef 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1,4 +1,8 @@ // This crate is intentionally empty and a re-export of `rustc_driver_impl` to allow the code in // `rustc_driver_impl` to be compiled in parallel with other crates. +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] + pub use rustc_driver_impl::*; diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index a7b01618ade..4894312b0d2 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -6,53 +6,55 @@ edition = "2021" [lib] [dependencies] -time = { version = "0.3", default-features = false, features = ["formatting", ] } -tracing = { version = "0.1.35" } -serde_json = "1.0.59" -rustc_log = { path = "../rustc_log" } +# tidy-alphabetical-start +rustc_ast = { path = "../rustc_ast" } rustc_ast_lowering = { path = "../rustc_ast_lowering" } rustc_ast_passes = { path = "../rustc_ast_passes" } +rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr = { path = "../rustc_attr" } rustc_borrowck = { path = "../rustc_borrowck" } rustc_builtin_macros = { path = "../rustc_builtin_macros" } +rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } rustc_const_eval = { path = "../rustc_const_eval" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_error_codes = { path = "../rustc_error_codes" } rustc_error_messages = { path = "../rustc_error_messages" } +rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } -rustc_hir_typeck = { path = "../rustc_hir_typeck" } +rustc_feature = { path = "../rustc_feature" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } +rustc_hir = { path = "../rustc_hir" } +rustc_hir_analysis = { path = "../rustc_hir_analysis" } +rustc_hir_pretty = { path = "../rustc_hir_pretty" } +rustc_hir_typeck = { path = "../rustc_hir_typeck" } rustc_incremental = { path = "../rustc_incremental" } rustc_infer = { path = "../rustc_infer" } +rustc_interface = { path = "../rustc_interface" } +rustc_lint = { path = "../rustc_lint" } +rustc_log = { path = "../rustc_log" } +rustc_macros = { path = "../rustc_macros" } +rustc_metadata = { path = "../rustc_metadata" } +rustc_middle = { path = "../rustc_middle" } rustc_mir_build = { path = "../rustc_mir_build" } rustc_mir_dataflow = { path = "../rustc_mir_dataflow" } +rustc_mir_transform = { path = "../rustc_mir_transform" } rustc_monomorphize = { path = "../rustc_monomorphize" } +rustc_parse = { path = "../rustc_parse" } rustc_passes = { path = "../rustc_passes" } +rustc_plugin_impl = { path = "../rustc_plugin_impl" } rustc_privacy = { path = "../rustc_privacy" } rustc_query_system = { path = "../rustc_query_system" } rustc_resolve = { path = "../rustc_resolve" } +rustc_session = { path = "../rustc_session" } +rustc_span = { path = "../rustc_span" } rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } +rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_ty_utils = { path = "../rustc_ty_utils" } -rustc_middle = { path = "../rustc_middle" } -rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_target = { path = "../rustc_target" } -rustc_lint = { path = "../rustc_lint" } -rustc_data_structures = { path = "../rustc_data_structures" } -rustc_errors = { path = "../rustc_errors" } -rustc_feature = { path = "../rustc_feature" } -rustc_hir = { path = "../rustc_hir" } -rustc_hir_pretty = { path = "../rustc_hir_pretty" } -rustc_macros = { path = "../rustc_macros" } -rustc_metadata = { path = "../rustc_metadata" } -rustc_parse = { path = "../rustc_parse" } -rustc_plugin_impl = { path = "../rustc_plugin_impl" } -rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } -rustc_session = { path = "../rustc_session" } -rustc_error_codes = { path = "../rustc_error_codes" } -rustc_interface = { path = "../rustc_interface" } -rustc_ast = { path = "../rustc_ast" } -rustc_span = { path = "../rustc_span" } -rustc_hir_analysis = { path = "../rustc_hir_analysis" } -rustc_mir_transform = { path = "../rustc_mir_transform" } +serde_json = "1.0.59" +time = { version = "0.3", default-features = false, features = ["formatting", ] } +tracing = { version = "0.1.35" } +# tidy-alphabetical-end [target.'cfg(unix)'.dependencies] libc = "0.2" diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 7a45ac10f0b..b0c95e1bd20 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -312,6 +312,7 @@ fn run_compiler( locale_resources: DEFAULT_LOCALE_RESOURCES, lint_caps: Default::default(), parse_sess_created: None, + hash_untracked_state: None, register_lints: None, override_queries: None, make_codegen_backend, @@ -1290,7 +1291,9 @@ fn ice_path() -> &'static Option<PathBuf> { if !rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build() { return None; } - if let Some(s) = std::env::var_os("RUST_BACKTRACE") && s == "0" { + if let Some(s) = std::env::var_os("RUST_BACKTRACE") + && s == "0" + { return None; } let mut path = match std::env::var_os("RUSTC_ICE") { @@ -1357,8 +1360,7 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler)) eprintln!(); if let Some(ice_path) = ice_path() - && let Ok(mut out) = - File::options().create(true).append(true).open(&ice_path) + && let Ok(mut out) = File::options().create(true).append(true).open(&ice_path) { // The current implementation always returns `Some`. let location = info.location().unwrap(); diff --git a/compiler/rustc_error_codes/src/error_codes/E0706.md b/compiler/rustc_error_codes/src/error_codes/E0706.md index fabd855a222..a09abb59ba8 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0706.md +++ b/compiler/rustc_error_codes/src/error_codes/E0706.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + `async fn`s are not yet supported in traits in Rust. Erroneous code example: -```compile_fail,edition2018 +```ignore,edition2018 trait T { // Neither case is currently supported. async fn foo() {} @@ -13,7 +15,7 @@ trait T { `async fn`s return an `impl Future`, making the following two examples equivalent: -```edition2018,ignore (example-of-desugaring-equivalence) +```ignore,edition2018 (example-of-desugaring-equivalence) async fn foo() -> User { unimplemented!() } diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index d6b120e4dfc..81ad661286e 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -1,3 +1,6 @@ +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] #![deny(rustdoc::invalid_codeblock_attributes)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 6c29144569d..6249c1e7961 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -1,3 +1,5 @@ +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature(let_chains)] #![feature(lazy_cell)] #![feature(rustc_attrs)] diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index d322cbe9d9b..922846775f6 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -337,9 +337,7 @@ pub trait Emitter: Translate { && last_name != name { let descr = macro_kind.descr(); - format!( - " which comes from the expansion of the {descr} `{last_name}`", - ) + format!(" which comes from the expansion of the {descr} `{last_name}`",) } else { "".to_string() }; @@ -1935,7 +1933,9 @@ impl EmitterWriter { is_multiline, ) } - if let DisplaySuggestion::Add = show_code_change && is_item_attribute { + if let DisplaySuggestion::Add = show_code_change + && is_item_attribute + { // The suggestion adds an entire line of code, ending on a newline, so we'll also // print the *following* line, to provide context of what we're advising people to // do. Otherwise you would only see contextless code that can be confused for diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 63226504d37..da74ee6391a 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -507,6 +507,7 @@ pub enum StashKey { CallAssocMethod, TraitMissingMethod, OpaqueHiddenTypeMismatch, + MaybeForgetReturn, } fn default_track_diagnostic(d: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnostic)) { @@ -1673,7 +1674,11 @@ impl HandlerInner { let _ = write!( &mut out, "delayed span bug: {}\n{}\n", - bug.inner.styled_message().iter().filter_map(|(msg, _)| msg.as_str()).collect::<String>(), + bug.inner + .styled_message() + .iter() + .filter_map(|(msg, _)| msg.as_str()) + .collect::<String>(), &bug.note ); } diff --git a/compiler/rustc_errors/src/tests.rs b/compiler/rustc_errors/src/tests.rs index 0e729b71680..79a2af7f38f 100644 --- a/compiler/rustc_errors/src/tests.rs +++ b/compiler/rustc_errors/src/tests.rs @@ -151,12 +151,14 @@ fn misformed_fluent() { primary: box TranslateError::One { kind: TranslateErrorKind::PrimaryBundleMissing, .. }, fallback: box TranslateError::One { kind: TranslateErrorKind::Fluent { errs }, .. }, } = &err - && let [FluentError::ResolverError(ResolverError::Reference( - ReferenceKind::Message { id, .. } - | ReferenceKind::Variable { id, .. }, - ))] = &**errs + && let [ + FluentError::ResolverError(ResolverError::Reference( + ReferenceKind::Message { id, .. } | ReferenceKind::Variable { id, .. }, + )), + ] = &**errs && id == "name" - {} else { + { + } else { panic!("{err:#?}") }; assert_eq!( @@ -176,12 +178,14 @@ fn misformed_fluent() { primary: box TranslateError::One { kind: TranslateErrorKind::PrimaryBundleMissing, .. }, fallback: box TranslateError::One { kind: TranslateErrorKind::Fluent { errs }, .. }, } = &err - && let [FluentError::ResolverError(ResolverError::Reference( - ReferenceKind::Message { id, .. } - | ReferenceKind::Variable { id, .. }, - ))] = &**errs + && let [ + FluentError::ResolverError(ResolverError::Reference( + ReferenceKind::Message { id, .. } | ReferenceKind::Variable { id, .. }, + )), + ] = &**errs && id == "oops" - {} else { + { + } else { panic!("{err:#?}") }; assert_eq!( diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 7ad0e799f44..b73c7593381 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -14,12 +14,12 @@ use rustc_ast::{self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem use rustc_attr as attr; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_data_structures::fx::FxHashSet; -use rustc_feature::{Feature, Features, State as FeatureState}; -use rustc_feature::{ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES}; +use rustc_feature::Features; +use rustc_feature::{ACCEPTED_FEATURES, REMOVED_FEATURES, UNSTABLE_FEATURES}; use rustc_parse::validate_attr; use rustc_session::parse::feature_err; use rustc_session::Session; -use rustc_span::edition::{Edition, ALL_EDITIONS}; +use rustc_span::edition::ALL_EDITIONS; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use thin_vec::ThinVec; @@ -36,18 +36,10 @@ pub struct StripUnconfigured<'a> { } pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features { - fn active_features_up_to(edition: Edition) -> impl Iterator<Item = &'static Feature> { - ACTIVE_FEATURES.iter().filter(move |feature| { - if let Some(feature_edition) = feature.edition { - feature_edition <= edition - } else { - false - } - }) - } - fn feature_list(attr: &Attribute) -> ThinVec<ast::NestedMetaItem> { - if attr.has_name(sym::feature) && let Some(list) = attr.meta_item_list() { + if attr.has_name(sym::feature) + && let Some(list) = attr.meta_item_list() + { list } else { ThinVec::new() @@ -69,7 +61,9 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features { if mi.is_word() { let name = mi.name_or_empty(); let edition = ALL_EDITIONS.iter().find(|e| name == e.feature_name()).copied(); - if let Some(edition) = edition && edition > features_edition { + if let Some(edition) = edition + && edition > features_edition + { features_edition = edition; } } @@ -79,11 +73,13 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features { // Enable edition-dependent features based on `features_edition`. // - E.g. enable `test_2018_feature` if `features_edition` is 2018 or higher let mut edition_enabled_features = FxHashSet::default(); - for feature in active_features_up_to(features_edition) { - // FIXME(Manishearth) there is currently no way to set lib features by - // edition. - edition_enabled_features.insert(feature.name); - feature.set(&mut features); + for f in UNSTABLE_FEATURES { + if let Some(edition) = f.feature.edition && edition <= features_edition { + // FIXME(Manishearth) there is currently no way to set lib features by + // edition. + edition_enabled_features.insert(f.feature.name); + (f.set_enabled)(&mut features); + } } // Process all features declared in the code. @@ -143,19 +139,17 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features { } // If the declared feature has been removed, issue an error. - if let Some(Feature { state, .. }) = REMOVED_FEATURES.iter().find(|f| name == f.name) { - if let FeatureState::Removed { reason } = state { - sess.emit_err(FeatureRemoved { - span: mi.span(), - reason: reason.map(|reason| FeatureRemovedReason { reason }), - }); - continue; - } + if let Some(f) = REMOVED_FEATURES.iter().find(|f| name == f.feature.name) { + sess.emit_err(FeatureRemoved { + span: mi.span(), + reason: f.reason.map(|reason| FeatureRemovedReason { reason }), + }); + continue; } // If the declared feature is stable, record it. - if let Some(Feature { since, .. }) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) { - let since = Some(Symbol::intern(since)); + if let Some(f) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) { + let since = Some(Symbol::intern(f.since)); features.set_declared_lang_feature(name, mi.span(), since); continue; } @@ -171,8 +165,8 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features { } // If the declared feature is unstable, record it. - if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.name) { - f.set(&mut features); + if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name) { + (f.set_enabled)(&mut features); features.set_declared_lang_feature(name, mi.span(), None); continue; } @@ -248,7 +242,8 @@ impl<'a> StripUnconfigured<'a> { let trees: Vec<_> = stream .0 .iter() - .flat_map(|tree| match tree.clone() { + .flat_map(|tree| { + match tree.clone() { AttrTokenTree::Attributes(mut data) => { data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(&attr)); @@ -263,18 +258,17 @@ impl<'a> StripUnconfigured<'a> { } AttrTokenTree::Delimited(sp, delim, mut inner) => { inner = self.configure_tokens(&inner); - Some(AttrTokenTree::Delimited(sp, delim, inner)) - .into_iter() + Some(AttrTokenTree::Delimited(sp, delim, inner)).into_iter() } - AttrTokenTree::Token(ref token, _) if let TokenKind::Interpolated(nt) = &token.kind => { - panic!( - "Nonterminal should have been flattened at {:?}: {:?}", - token.span, nt - ); + AttrTokenTree::Token(ref token, _) + if let TokenKind::Interpolated(nt) = &token.kind => + { + panic!("Nonterminal should have been flattened at {:?}: {:?}", token.span, nt); } AttrTokenTree::Token(token, spacing) => { Some(AttrTokenTree::Token(token, spacing)).into_iter() } + } }) .collect(); AttrTokenStream::new(trees) diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 8b1fc5b90b4..5a774164a4b 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -1,3 +1,5 @@ +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature(array_windows)] #![feature(associated_type_bounds)] #![feature(associated_type_defaults)] diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index a5959d68fbc..ebdd3cb547c 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -716,18 +716,18 @@ fn has_compile_error_macro(rhs: &mbe::TokenTree) -> bool { match rhs { mbe::TokenTree::Delimited(_sp, d) => { let has_compile_error = d.tts.array_windows::<3>().any(|[ident, bang, args]| { - if let mbe::TokenTree::Token(ident) = ident && - let TokenKind::Ident(ident, _) = ident.kind && - ident == sym::compile_error && - let mbe::TokenTree::Token(bang) = bang && - let TokenKind::Not = bang.kind && - let mbe::TokenTree::Delimited(_, del) = args && - del.delim != Delimiter::Invisible - { - true - } else { - false - } + if let mbe::TokenTree::Token(ident) = ident + && let TokenKind::Ident(ident, _) = ident.kind + && ident == sym::compile_error + && let mbe::TokenTree::Token(bang) = bang + && let TokenKind::Not = bang.kind + && let mbe::TokenTree::Delimited(_, del) = args + && del.delim != Delimiter::Invisible + { + true + } else { + false + } }); if has_compile_error { true } else { d.tts.iter().any(has_compile_error_macro) } } diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs index 7c37aadc67a..7cb279a9812 100644 --- a/compiler/rustc_expand/src/mbe/metavar_expr.rs +++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs @@ -124,8 +124,7 @@ fn parse_depth<'sess>( && let Ok(n_usize) = usize::try_from(n_u128) { Ok(n_usize) - } - else { + } else { let msg = "only unsuffixes integer literals are supported in meta-variable expressions"; Err(sess.span_diagnostic.struct_span_err(span, msg)) } @@ -137,15 +136,16 @@ fn parse_ident<'sess>( sess: &'sess ParseSess, span: Span, ) -> PResult<'sess, Ident> { - if let Some(tt) = iter.next() && let TokenTree::Token(token, _) = tt { + if let Some(tt) = iter.next() + && let TokenTree::Token(token, _) = tt + { if let Some((elem, false)) = token.ident() { return Ok(elem); } let token_str = pprust::token_to_string(token); - let mut err = sess.span_diagnostic.struct_span_err( - span, - format!("expected identifier, found `{}`", &token_str) - ); + let mut err = sess + .span_diagnostic + .struct_span_err(span, format!("expected identifier, found `{}`", &token_str)); err.span_suggestion( token.span, format!("try removing `{}`", &token_str), diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index 3779af19e12..df6bdc6952b 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -91,7 +91,9 @@ pub(crate) fn mod_dir_path( inline: Inline, ) -> (PathBuf, DirOwnership) { match inline { - Inline::Yes if let Some(file_path) = mod_file_path_from_attr(sess, attrs, &module.dir_path) => { + Inline::Yes + if let Some(file_path) = mod_file_path_from_attr(sess, attrs, &module.dir_path) => + { // For inline modules file path from `#[path]` is actually the directory path // for historical reasons, so we don't pop the last segment here. (file_path, DirOwnership::Owned { relative: None }) diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 2dc9b51a37e..aa4c7a53135 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -226,9 +226,8 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre })); } - Interpolated(nt) if let NtIdent(ident, is_raw) = *nt => { - trees.push(TokenTree::Ident(Ident { sym: ident.name, is_raw, span: ident.span })) - } + Interpolated(nt) if let NtIdent(ident, is_raw) = *nt => trees + .push(TokenTree::Ident(Ident { sym: ident.name, is_raw, span: ident.span })), Interpolated(nt) => { let stream = TokenStream::from_nonterminal_ast(&nt); diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 32d8380abd3..f07022733d4 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -1,23 +1,20 @@ //! List of the accepted feature gates. -use super::{to_nonzero, Feature, State}; +use super::{to_nonzero, Feature}; use rustc_span::symbol::sym; macro_rules! declare_features { ($( $(#[doc = $doc:tt])* (accepted, $feature:ident, $ver:expr, $issue:expr, None), )+) => { - /// Those language feature has since been Accepted (it was once Active) + /// Formerly unstable features that have now been accepted (stabilized). pub const ACCEPTED_FEATURES: &[Feature] = &[ - $( - Feature { - state: State::Accepted, - name: sym::$feature, - since: $ver, - issue: to_nonzero($issue), - edition: None, - } - ),+ + $(Feature { + name: sym::$feature, + since: $ver, + issue: to_nonzero($issue), + edition: None, + }),+ ]; } } @@ -67,6 +64,8 @@ declare_features! ( (accepted, associated_types, "1.0.0", None, None), /// Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions. (accepted, async_await, "1.39.0", Some(50547), None), + /// Allows async functions to be declared, implemented, and used in traits. + (accepted, async_fn_in_trait, "CURRENT_RUSTC_VERSION", Some(91611), None), /// Allows all literals in attribute lists and values of key-value pairs. (accepted, attr_literals, "1.30.0", Some(34981), None), /// Allows overloading augmented assignment operations like `a += b`. @@ -198,7 +197,7 @@ declare_features! ( /// + `impl Debug for Foo<'_>` (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None), /// Allows referencing `Self` and projections in impl-trait. - (accepted, impl_trait_projections, "CURRENT_RUSTC_VERSION", Some(103532), None), + (accepted, impl_trait_projections, "1.74.0", Some(103532), None), /// Allows using `a..=b` and `..=b` as inclusive range syntaxes. (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), /// Allows inferring outlives requirements (RFC 2093). @@ -270,7 +269,7 @@ declare_features! ( /// Allows the use of or-patterns (e.g., `0 | 1`). (accepted, or_patterns, "1.53.0", Some(54883), None), /// Allows using `+bundle,+whole-archive` link modifiers with native libs. - (accepted, packed_bundled_libs, "CURRENT_RUSTC_VERSION", Some(108081), None), + (accepted, packed_bundled_libs, "1.74.0", Some(108081), None), /// Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`. /// This defines the behavior of panics. (accepted, panic_handler, "1.30.0", Some(44489), None), @@ -306,6 +305,8 @@ declare_features! ( (accepted, repr_packed, "1.33.0", Some(33158), None), /// Allows `#[repr(transparent)]` attribute on newtype structs. (accepted, repr_transparent, "1.28.0", Some(43036), None), + /// Allows return-position `impl Trait` in traits. + (accepted, return_position_impl_trait_in_trait, "CURRENT_RUSTC_VERSION", Some(91611), None), /// Allows code like `let x: &'static u32 = &42` to work (RFC 1414). (accepted, rvalue_static_promotion, "1.21.0", Some(38865), None), /// Allows `Self` in type definitions (RFC 2300). diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 4721bff0ec7..070234df94c 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -11,42 +11,26 @@ //! even if it is stabilized or removed, *do not remove it*. Instead, move the //! symbol to the `accepted` or `removed` modules respectively. +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] #![feature(lazy_cell)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] mod accepted; -mod active; mod builtin_attrs; mod removed; +mod unstable; #[cfg(test)] mod tests; use rustc_span::{edition::Edition, symbol::Symbol}; -use std::fmt; use std::num::NonZeroU32; -#[derive(Clone, Copy)] -pub enum State { - Accepted, - Active { set: fn(&mut Features) }, - Removed { reason: Option<&'static str> }, -} - -impl fmt::Debug for State { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - State::Accepted { .. } => write!(f, "accepted"), - State::Active { .. } => write!(f, "active"), - State::Removed { .. } => write!(f, "removed"), - } - } -} - #[derive(Debug, Clone)] pub struct Feature { - pub state: State, pub name: Symbol, pub since: &'static str, issue: Option<NonZeroU32>, @@ -63,9 +47,9 @@ pub enum Stability { #[derive(Clone, Copy, Debug, Hash)] pub enum UnstableFeatures { - /// Hard errors for unstable features are active, as on beta/stable channels. + /// Disallow use of unstable features, as on beta/stable channels. Disallow, - /// Allow features to be activated, as on nightly. + /// Allow use of unstable features, as on nightly. Allow, /// Errors are bypassed for bootstrapping. This is required any time /// during the build that feature-related lints are set to warn or above @@ -106,17 +90,16 @@ impl UnstableFeatures { fn find_lang_feature_issue(feature: Symbol) -> Option<NonZeroU32> { // Search in all the feature lists. - let found = [] - .iter() - .chain(ACTIVE_FEATURES) - .chain(ACCEPTED_FEATURES) - .chain(REMOVED_FEATURES) - .find(|t| t.name == feature); - - match found { - Some(found) => found.issue, - None => panic!("feature `{feature}` is not declared anywhere"), + if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| f.feature.name == feature) { + return f.feature.issue; + } + if let Some(f) = ACCEPTED_FEATURES.iter().find(|f| f.name == feature) { + return f.issue; + } + if let Some(f) = REMOVED_FEATURES.iter().find(|f| f.feature.name == feature) { + return f.feature.issue; } + panic!("feature `{feature}` is not declared anywhere"); } const fn to_nonzero(n: Option<u32>) -> Option<NonZeroU32> { @@ -141,7 +124,6 @@ pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option<NonZeroU3 } pub use accepted::ACCEPTED_FEATURES; -pub use active::{Features, ACTIVE_FEATURES, INCOMPATIBLE_FEATURES}; pub use builtin_attrs::AttributeDuplicates; pub use builtin_attrs::{ deprecated_attributes, find_gated_cfg, is_builtin_attr_name, is_builtin_only_local, @@ -149,3 +131,4 @@ pub use builtin_attrs::{ GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP, }; pub use removed::REMOVED_FEATURES; +pub use unstable::{Features, INCOMPATIBLE_FEATURES, UNSTABLE_FEATURES}; diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index de15deef178..339f596144c 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -1,23 +1,28 @@ //! List of the removed feature gates. -use super::{to_nonzero, Feature, State}; +use super::{to_nonzero, Feature}; use rustc_span::symbol::sym; +pub struct RemovedFeature { + pub feature: Feature, + pub reason: Option<&'static str>, +} + macro_rules! declare_features { ($( $(#[doc = $doc:tt])* (removed, $feature:ident, $ver:expr, $issue:expr, None, $reason:expr), )+) => { - /// Represents unstable features which have since been removed (it was once Active) - pub const REMOVED_FEATURES: &[Feature] = &[ - $( - Feature { - state: State::Removed { reason: $reason }, + /// Formerly unstable features that have now been removed. + pub const REMOVED_FEATURES: &[RemovedFeature] = &[ + $(RemovedFeature { + feature: Feature { name: sym::$feature, since: $ver, issue: to_nonzero($issue), edition: None, - } - ),+ + }, + reason: $reason + }),+ ]; }; } @@ -121,7 +126,7 @@ declare_features! ( (removed, negate_unsigned, "1.0.0", Some(29645), None, None), /// Allows `#[no_coverage]` on functions. /// The feature was renamed to `coverage_attribute` and the attribute to `#[coverage(on|off)]` - (removed, no_coverage, "CURRENT_RUSTC_VERSION", Some(84605), None, Some("renamed to `coverage_attribute`")), + (removed, no_coverage, "1.74.0", Some(84605), None, Some("renamed to `coverage_attribute`")), /// Allows `#[no_debug]`. (removed, no_debug, "1.43.0", Some(29721), None, Some("removed due to lack of demand")), /// Note: this feature was previously recorded in a separate diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/unstable.rs index 83961647bd4..27cdf1ba831 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -1,12 +1,17 @@ -//! List of the active feature gates. +//! List of the unstable feature gates. -use super::{to_nonzero, Feature, State}; +use super::{to_nonzero, Feature}; use rustc_data_structures::fx::FxHashSet; use rustc_span::edition::Edition; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; +pub struct UnstableFeature { + pub feature: Feature, + pub set_enabled: fn(&mut Features), +} + #[derive(PartialEq)] enum FeatureStatus { Default, @@ -15,7 +20,7 @@ enum FeatureStatus { } macro_rules! status_to_enum { - (active) => { + (unstable) => { FeatureStatus::Default }; (incomplete) => { @@ -30,23 +35,20 @@ macro_rules! declare_features { ($( $(#[doc = $doc:tt])* ($status:ident, $feature:ident, $ver:expr, $issue:expr, $edition:expr), )+) => { - /// Represents active features that are currently being implemented or - /// currently being considered for addition/removal. - pub const ACTIVE_FEATURES: - &[Feature] = - &[$( - // (sym::$feature, $ver, $issue, $edition, set!($feature)) - Feature { - state: State::Active { - // Sets this feature's corresponding bool within `features`. - set: |features| features.$feature = true, - }, + /// Unstable language features that are being implemented or being + /// considered for acceptance (stabilization) or removal. + pub const UNSTABLE_FEATURES: &[UnstableFeature] = &[ + $(UnstableFeature { + feature: Feature { name: sym::$feature, since: $ver, issue: to_nonzero($issue), edition: $edition, - } - ),+]; + }, + // Sets this feature's corresponding bool within `features`. + set_enabled: |features| features.$feature = true, + }),+ + ]; /// A set of features to be used by later passes. #[derive(Clone, Default, Debug)] @@ -57,7 +59,7 @@ macro_rules! declare_features { pub declared_lib_features: Vec<(Symbol, Span)>, /// `declared_lang_features` + `declared_lib_features`. pub declared_features: FxHashSet<Symbol>, - /// Individual features (unstable only). + /// Active state of individual features (unstable only). $( $(#[doc = $doc])* pub $feature: bool @@ -90,11 +92,11 @@ macro_rules! declare_features { self.declared_features.contains(&feature) } - /// Is the given feature enabled, i.e. declared or automatically + /// Is the given feature active, i.e. declared or automatically /// enabled due to the edition? /// /// Panics if the symbol doesn't correspond to a declared feature. - pub fn enabled(&self, feature: Symbol) -> bool { + pub fn active(&self, feature: Symbol) -> bool { match feature { $( sym::$feature => self.$feature, )* @@ -110,22 +112,21 @@ macro_rules! declare_features { $( sym::$feature => status_to_enum!($status) == FeatureStatus::Incomplete, )* - // accepted and removed features aren't in this file but are never incomplete + // Accepted/removed features aren't in this file but are never incomplete. _ if self.declared_features.contains(&feature) => false, _ => panic!("`{}` was not listed in `declare_features`", feature), } } /// Some features are internal to the compiler and standard library and should not - /// be used in normal projects. We warn the user about these - /// to alert them. + /// be used in normal projects. We warn the user about these to alert them. pub fn internal(&self, feature: Symbol) -> bool { match feature { $( sym::$feature => status_to_enum!($status) == FeatureStatus::Internal, )* - // accepted and removed features aren't in this file but are never internal - // (a removed feature might have been internal, but it doesn't matter anymore) + // Accepted/removed features aren't in this file but are never internal + // (a removed feature might have been internal, but that's now irrelevant). _ if self.declared_features.contains(&feature) => false, _ => panic!("`{}` was not listed in `declare_features`", feature), } @@ -134,16 +135,6 @@ macro_rules! declare_features { }; } -impl Feature { - /// Sets this feature in `Features`. Panics if called on a non-active feature. - pub fn set(&self, features: &mut Features) { - match self.state { - State::Active { set } => set(features), - _ => panic!("called `set` on feature `{}` which is not `active`", self.name), - } - } -} - // See https://rustc-dev-guide.rust-lang.org/feature-gates.html#feature-gates for more // documentation about handling feature gates. // @@ -153,8 +144,7 @@ impl Feature { // accepted or `removed.rs` if removed. // // The version numbers here correspond to the version in which the current status -// was set. This is most important for knowing when a particular feature became -// stable (active). +// was set. // // Note that the features are grouped into internal/user-facing and then // sorted by version inside those groups. This is enforced with tidy. @@ -170,9 +160,9 @@ declare_features! ( // no-tracking-issue-start /// Allows using the `unadjusted` ABI; perma-unstable. - (active, abi_unadjusted, "1.16.0", None, None), + (unstable, abi_unadjusted, "1.16.0", None, None), /// Allows using the `vectorcall` ABI. - (active, abi_vectorcall, "1.7.0", None, None), + (unstable, abi_vectorcall, "1.7.0", None, None), /// Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`. (internal, allocator_internals, "1.20.0", None, None), /// Allows using `#[allow_internal_unsafe]`. This is an @@ -186,21 +176,21 @@ declare_features! ( /// macros disappear). (internal, allow_internal_unstable, "1.0.0", None, None), /// Allows using anonymous lifetimes in argument-position impl-trait. - (active, anonymous_lifetime_in_impl_trait, "1.63.0", None, None), + (unstable, anonymous_lifetime_in_impl_trait, "1.63.0", None, None), /// Allows identifying the `compiler_builtins` crate. (internal, compiler_builtins, "1.13.0", None, None), /// Allows writing custom MIR (internal, custom_mir, "1.65.0", None, None), /// Outputs useful `assert!` messages - (active, generic_assert, "1.63.0", None, None), + (unstable, generic_assert, "1.63.0", None, None), /// Allows using the `rust-intrinsic`'s "ABI". (internal, intrinsics, "1.0.0", None, None), /// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic. (internal, lang_items, "1.0.0", None, None), /// Allows `#[link(..., cfg(..))]`; perma-unstable per #37406 - (active, link_cfg, "1.14.0", None, None), + (unstable, link_cfg, "1.14.0", None, None), /// Allows the `multiple_supertrait_upcastable` lint. - (active, multiple_supertrait_upcastable, "1.69.0", None, None), + (unstable, multiple_supertrait_upcastable, "1.69.0", None, None), /// Allow negative trait bounds. This is an internal-only feature for testing the trait solver! (incomplete, negative_bounds, "1.71.0", None, None), /// Allows using `#[omit_gdb_pretty_printer_section]`. @@ -222,7 +212,7 @@ declare_features! ( (internal, unsafe_pin_internals, "1.60.0", None, None), /// Use for stable + negative coherence and strict coherence depending on trait's /// rustc_strict_coherence value. - (active, with_negative_coherence, "1.60.0", None, None), + (unstable, with_negative_coherence, "1.60.0", None, None), // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! @@ -238,20 +228,20 @@ declare_features! ( /// Allows features specific to auto traits. /// Renamed from `optin_builtin_traits`. - (active, auto_traits, "1.50.0", Some(13231), None), + (unstable, auto_traits, "1.50.0", Some(13231), None), /// Allows using `box` in patterns (RFC 469). - (active, box_patterns, "1.0.0", Some(29641), None), + (unstable, box_patterns, "1.0.0", Some(29641), None), /// Allows `#[doc(notable_trait)]`. /// Renamed from `doc_spotlight`. - (active, doc_notable_trait, "1.52.0", Some(45040), None), + (unstable, doc_notable_trait, "1.52.0", Some(45040), None), /// Allows using the `may_dangle` attribute (RFC 1327). - (active, dropck_eyepatch, "1.10.0", Some(34761), None), + (unstable, dropck_eyepatch, "1.10.0", Some(34761), None), /// Allows using the `#[fundamental]` attribute. - (active, fundamental, "1.0.0", Some(29635), None), + (unstable, fundamental, "1.0.0", Some(29635), None), /// Allows using `#[link_name="llvm.*"]`. (internal, link_llvm_intrinsics, "1.0.0", Some(29602), None), /// Allows using the `#[linkage = ".."]` attribute. - (active, linkage, "1.0.0", Some(29603), None), + (unstable, linkage, "1.0.0", Some(29603), None), /// Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed. (internal, needs_panic_runtime, "1.10.0", Some(32837), None), /// Allows using the `#![panic_runtime]` attribute. @@ -263,19 +253,19 @@ declare_features! ( /// purpose as `#[allow_internal_unstable]`. (internal, rustc_allow_const_fn_unstable, "1.49.0", Some(69399), None), /// Allows using compiler's own crates. - (active, rustc_private, "1.0.0", Some(27812), None), + (unstable, rustc_private, "1.0.0", Some(27812), None), /// Allows using internal rustdoc features like `doc(keyword)`. (internal, rustdoc_internals, "1.58.0", Some(90418), None), /// Allows using the `rustdoc::missing_doc_code_examples` lint - (active, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730), None), + (unstable, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730), None), /// Allows using `#[start]` on a function indicating that it is the program entrypoint. - (active, start, "1.0.0", Some(29633), None), + (unstable, start, "1.0.0", Some(29633), None), /// Allows using `#[structural_match]` which indicates that a type is structurally matchable. /// FIXME: Subsumed by trait `StructuralPartialEq`, cannot move to removed until a library /// feature with the same name exists. - (active, structural_match, "1.8.0", Some(31434), None), + (unstable, structural_match, "1.8.0", Some(31434), None), /// Allows using the `rust-call` ABI. - (active, unboxed_closures, "1.0.0", Some(29625), None), + (unstable, unboxed_closures, "1.0.0", Some(29625), None), // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! @@ -291,20 +281,20 @@ declare_features! ( // FIXME: Document these and merge with the list below. // Unstable `#[target_feature]` directives. - (active, aarch64_ver_target_feature, "1.27.0", Some(44839), None), - (active, arm_target_feature, "1.27.0", Some(44839), None), - (active, avx512_target_feature, "1.27.0", Some(44839), None), - (active, bpf_target_feature, "1.54.0", Some(44839), None), - (active, csky_target_feature, "1.73.0", Some(44839), None), - (active, ermsb_target_feature, "1.49.0", Some(44839), None), - (active, hexagon_target_feature, "1.27.0", Some(44839), None), - (active, mips_target_feature, "1.27.0", Some(44839), None), - (active, powerpc_target_feature, "1.27.0", Some(44839), None), - (active, riscv_target_feature, "1.45.0", Some(44839), None), - (active, rtm_target_feature, "1.35.0", Some(44839), None), - (active, sse4a_target_feature, "1.27.0", Some(44839), None), - (active, tbm_target_feature, "1.27.0", Some(44839), None), - (active, wasm_target_feature, "1.30.0", Some(44839), None), + (unstable, aarch64_ver_target_feature, "1.27.0", Some(44839), None), + (unstable, arm_target_feature, "1.27.0", Some(44839), None), + (unstable, avx512_target_feature, "1.27.0", Some(44839), None), + (unstable, bpf_target_feature, "1.54.0", Some(44839), None), + (unstable, csky_target_feature, "1.73.0", Some(44839), None), + (unstable, ermsb_target_feature, "1.49.0", Some(44839), None), + (unstable, hexagon_target_feature, "1.27.0", Some(44839), None), + (unstable, mips_target_feature, "1.27.0", Some(44839), None), + (unstable, powerpc_target_feature, "1.27.0", Some(44839), None), + (unstable, riscv_target_feature, "1.45.0", Some(44839), None), + (unstable, rtm_target_feature, "1.35.0", Some(44839), None), + (unstable, sse4a_target_feature, "1.27.0", Some(44839), None), + (unstable, tbm_target_feature, "1.27.0", Some(44839), None), + (unstable, wasm_target_feature, "1.30.0", Some(44839), None), // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! @@ -318,157 +308,155 @@ declare_features! ( // ------------------------------------------------------------------------- /// Allows using the `amdgpu-kernel` ABI. - (active, abi_amdgpu_kernel, "1.29.0", Some(51575), None), + (unstable, abi_amdgpu_kernel, "1.29.0", Some(51575), None), /// Allows `extern "avr-interrupt" fn()` and `extern "avr-non-blocking-interrupt" fn()`. - (active, abi_avr_interrupt, "1.45.0", Some(69664), None), + (unstable, abi_avr_interrupt, "1.45.0", Some(69664), None), /// Allows `extern "C-cmse-nonsecure-call" fn()`. - (active, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391), None), + (unstable, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391), None), /// Allows `extern "msp430-interrupt" fn()`. - (active, abi_msp430_interrupt, "1.16.0", Some(38487), None), + (unstable, abi_msp430_interrupt, "1.16.0", Some(38487), None), /// Allows `extern "ptx-*" fn()`. - (active, abi_ptx, "1.15.0", Some(38788), None), + (unstable, abi_ptx, "1.15.0", Some(38788), None), /// Allows `extern "riscv-interrupt-m" fn()` and `extern "riscv-interrupt-s" fn()`. - (active, abi_riscv_interrupt, "1.73.0", Some(111889), None), + (unstable, abi_riscv_interrupt, "1.73.0", Some(111889), None), /// Allows `extern "x86-interrupt" fn()`. - (active, abi_x86_interrupt, "1.17.0", Some(40180), None), + (unstable, abi_x86_interrupt, "1.17.0", Some(40180), None), /// Allows additional const parameter types, such as `&'static str` or user defined types (incomplete, adt_const_params, "1.56.0", Some(95174), None), /// Allows defining an `#[alloc_error_handler]`. - (active, alloc_error_handler, "1.29.0", Some(51540), None), + (unstable, alloc_error_handler, "1.29.0", Some(51540), None), /// Allows trait methods with arbitrary self types. - (active, arbitrary_self_types, "1.23.0", Some(44874), None), + (unstable, arbitrary_self_types, "1.23.0", Some(44874), None), /// Allows using `const` operands in inline assembly. - (active, asm_const, "1.58.0", Some(93332), None), + (unstable, asm_const, "1.58.0", Some(93332), None), /// Enables experimental inline assembly support for additional architectures. - (active, asm_experimental_arch, "1.58.0", Some(93335), None), + (unstable, asm_experimental_arch, "1.58.0", Some(93335), None), /// Allows the `may_unwind` option in inline assembly. - (active, asm_unwind, "1.58.0", Some(93334), None), + (unstable, asm_unwind, "1.58.0", Some(93334), None), /// Allows users to enforce equality of associated constants `TraitImpl<AssocConst=3>`. - (active, associated_const_equality, "1.58.0", Some(92827), None), + (unstable, associated_const_equality, "1.58.0", Some(92827), None), /// Allows the user of associated type bounds. - (active, associated_type_bounds, "1.34.0", Some(52662), None), + (unstable, associated_type_bounds, "1.34.0", Some(52662), None), /// Allows associated type defaults. - (active, associated_type_defaults, "1.2.0", Some(29661), None), + (unstable, associated_type_defaults, "1.2.0", Some(29661), None), /// Allows `async || body` closures. - (active, async_closure, "1.37.0", Some(62290), None), - /// Allows async functions to be declared, implemented, and used in traits. - (active, async_fn_in_trait, "1.66.0", Some(91611), None), + (unstable, async_closure, "1.37.0", Some(62290), None), /// Allows `#[track_caller]` on async functions. - (active, async_fn_track_caller, "1.73.0", Some(110011), None), + (unstable, async_fn_track_caller, "1.73.0", Some(110011), None), /// Allows builtin # foo() syntax - (active, builtin_syntax, "1.71.0", Some(110680), None), + (unstable, builtin_syntax, "1.71.0", Some(110680), None), /// Allows `c"foo"` literals. - (active, c_str_literals, "1.71.0", Some(105723), None), + (unstable, c_str_literals, "1.71.0", Some(105723), None), /// Treat `extern "C"` function as nounwind. - (active, c_unwind, "1.52.0", Some(74990), None), + (unstable, c_unwind, "1.52.0", Some(74990), None), /// Allows using C-variadics. - (active, c_variadic, "1.34.0", Some(44930), None), + (unstable, c_variadic, "1.34.0", Some(44930), None), /// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour. - (active, cfg_overflow_checks, "1.71.0", Some(111466), None), + (unstable, cfg_overflow_checks, "1.71.0", Some(111466), None), /// Provides the relocation model information as cfg entry - (active, cfg_relocation_model, "1.73.0", Some(114929), None), + (unstable, cfg_relocation_model, "1.73.0", Some(114929), None), /// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used. - (active, cfg_sanitize, "1.41.0", Some(39699), None), + (unstable, cfg_sanitize, "1.41.0", Some(39699), None), /// Allows `cfg(target_abi = "...")`. - (active, cfg_target_abi, "1.55.0", Some(80970), None), + (unstable, cfg_target_abi, "1.55.0", Some(80970), None), /// Allows `cfg(target(abi = "..."))`. - (active, cfg_target_compact, "1.63.0", Some(96901), None), + (unstable, cfg_target_compact, "1.63.0", Some(96901), None), /// Allows `cfg(target_has_atomic_load_store = "...")`. - (active, cfg_target_has_atomic, "1.60.0", Some(94039), None), + (unstable, cfg_target_has_atomic, "1.60.0", Some(94039), None), /// Allows `cfg(target_has_atomic_equal_alignment = "...")`. - (active, cfg_target_has_atomic_equal_alignment, "1.60.0", Some(93822), None), + (unstable, cfg_target_has_atomic_equal_alignment, "1.60.0", Some(93822), None), /// Allows `cfg(target_thread_local)`. - (active, cfg_target_thread_local, "1.7.0", Some(29594), None), + (unstable, cfg_target_thread_local, "1.7.0", Some(29594), None), /// Allow conditional compilation depending on rust version - (active, cfg_version, "1.45.0", Some(64796), None), + (unstable, cfg_version, "1.45.0", Some(64796), None), /// Allows to use the `#[cfi_encoding = ""]` attribute. - (active, cfi_encoding, "1.71.0", Some(89653), None), + (unstable, cfi_encoding, "1.71.0", Some(89653), None), /// Allows `for<...>` on closures and generators. - (active, closure_lifetime_binder, "1.64.0", Some(97362), None), + (unstable, closure_lifetime_binder, "1.64.0", Some(97362), None), /// Allows `#[track_caller]` on closures and generators. - (active, closure_track_caller, "1.57.0", Some(87417), None), + (unstable, closure_track_caller, "1.57.0", Some(87417), None), /// Allows to use the `#[cmse_nonsecure_entry]` attribute. - (active, cmse_nonsecure_entry, "1.48.0", Some(75835), None), + (unstable, cmse_nonsecure_entry, "1.48.0", Some(75835), None), /// Allows use of the `#[collapse_debuginfo]` attribute. - (active, collapse_debuginfo, "1.65.0", Some(100758), None), + (unstable, collapse_debuginfo, "1.65.0", Some(100758), None), /// Allows `async {}` expressions in const contexts. - (active, const_async_blocks, "1.53.0", Some(85368), None), + (unstable, const_async_blocks, "1.53.0", Some(85368), None), /// Allows `const || {}` closures in const contexts. (incomplete, const_closures, "1.68.0", Some(106003), None), /// Allows the definition of `const extern fn` and `const unsafe extern fn`. - (active, const_extern_fn, "1.40.0", Some(64926), None), + (unstable, const_extern_fn, "1.40.0", Some(64926), None), /// Allows basic arithmetic on floating point types in a `const fn`. - (active, const_fn_floating_point_arithmetic, "1.48.0", Some(57241), None), + (unstable, const_fn_floating_point_arithmetic, "1.48.0", Some(57241), None), /// Allows `for _ in _` loops in const contexts. - (active, const_for, "1.56.0", Some(87575), None), + (unstable, const_for, "1.56.0", Some(87575), None), /// Allows using `&mut` in constant functions. - (active, const_mut_refs, "1.41.0", Some(57349), None), + (unstable, const_mut_refs, "1.41.0", Some(57349), None), /// Be more precise when looking for live drops in a const context. - (active, const_precise_live_drops, "1.46.0", Some(73255), None), + (unstable, const_precise_live_drops, "1.46.0", Some(73255), None), /// Allows references to types with interior mutability within constants - (active, const_refs_to_cell, "1.51.0", Some(80384), None), + (unstable, const_refs_to_cell, "1.51.0", Some(80384), None), /// Allows `impl const Trait for T` syntax. - (active, const_trait_impl, "1.42.0", Some(67792), None), + (unstable, const_trait_impl, "1.42.0", Some(67792), None), /// Allows the `?` operator in const contexts. - (active, const_try, "1.56.0", Some(74935), None), + (unstable, const_try, "1.56.0", Some(74935), None), /// Allows function attribute `#[coverage(on/off)]`, to control coverage /// instrumentation of that function. - (active, coverage_attribute, "CURRENT_RUSTC_VERSION", Some(84605), None), + (unstable, coverage_attribute, "1.74.0", Some(84605), None), /// Allows users to provide classes for fenced code block using `class:classname`. - (active, custom_code_classes_in_docs, "CURRENT_RUSTC_VERSION", Some(79483), None), + (unstable, custom_code_classes_in_docs, "1.74.0", Some(79483), None), /// Allows non-builtin attributes in inner attribute position. - (active, custom_inner_attributes, "1.30.0", Some(54726), None), + (unstable, custom_inner_attributes, "1.30.0", Some(54726), None), /// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`. - (active, custom_test_frameworks, "1.30.0", Some(50297), None), + (unstable, custom_test_frameworks, "1.30.0", Some(50297), None), /// Allows declarative macros 2.0 (`macro`). - (active, decl_macro, "1.17.0", Some(39412), None), + (unstable, decl_macro, "1.17.0", Some(39412), None), /// Allows default type parameters to influence type inference. - (active, default_type_parameter_fallback, "1.3.0", Some(27336), None), + (unstable, default_type_parameter_fallback, "1.3.0", Some(27336), None), /// Allows using `#[deprecated_safe]` to deprecate the safeness of a function or trait - (active, deprecated_safe, "1.61.0", Some(94978), None), + (unstable, deprecated_safe, "1.61.0", Some(94978), None), /// Allows having using `suggestion` in the `#[deprecated]` attribute. - (active, deprecated_suggestion, "1.61.0", Some(94785), None), + (unstable, deprecated_suggestion, "1.61.0", Some(94785), None), /// Allows using the `#[diagnostic]` attribute tool namespace - (active, diagnostic_namespace, "1.73.0", Some(111996), None), + (unstable, diagnostic_namespace, "1.73.0", Some(111996), None), /// Controls errors in trait implementations. - (active, do_not_recommend, "1.67.0", Some(51992), None), + (unstable, do_not_recommend, "1.67.0", Some(51992), None), /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`. - (active, doc_auto_cfg, "1.58.0", Some(43781), None), + (unstable, doc_auto_cfg, "1.58.0", Some(43781), None), /// Allows `#[doc(cfg(...))]`. - (active, doc_cfg, "1.21.0", Some(43781), None), + (unstable, doc_cfg, "1.21.0", Some(43781), None), /// Allows `#[doc(cfg_hide(...))]`. - (active, doc_cfg_hide, "1.57.0", Some(43781), None), + (unstable, doc_cfg_hide, "1.57.0", Some(43781), None), /// Allows `#[doc(masked)]`. - (active, doc_masked, "1.21.0", Some(44027), None), + (unstable, doc_masked, "1.21.0", Some(44027), None), /// Allows `dyn* Trait` objects. (incomplete, dyn_star, "1.65.0", Some(102425), None), // Uses generic effect parameters for ~const bounds - (active, effects, "1.72.0", Some(102090), None), + (unstable, effects, "1.72.0", Some(102090), None), /// Allows `X..Y` patterns. - (active, exclusive_range_pattern, "1.11.0", Some(37854), None), + (unstable, exclusive_range_pattern, "1.11.0", Some(37854), None), /// Allows exhaustive pattern matching on types that contain uninhabited types. - (active, exhaustive_patterns, "1.13.0", Some(51085), None), + (unstable, exhaustive_patterns, "1.13.0", Some(51085), None), /// Allows explicit tail calls via `become` expression. (incomplete, explicit_tail_calls, "1.72.0", Some(112788), None), /// Allows using `efiapi`, `sysv64` and `win64` as calling convention /// for functions with varargs. - (active, extended_varargs_abi_support, "1.65.0", Some(100189), None), + (unstable, extended_varargs_abi_support, "1.65.0", Some(100189), None), /// Allows defining `extern type`s. - (active, extern_types, "1.23.0", Some(43467), None), + (unstable, extern_types, "1.23.0", Some(43467), None), /// Allows the use of `#[ffi_const]` on foreign functions. - (active, ffi_const, "1.45.0", Some(58328), None), + (unstable, ffi_const, "1.45.0", Some(58328), None), /// Allows the use of `#[ffi_pure]` on foreign functions. - (active, ffi_pure, "1.45.0", Some(58329), None), + (unstable, ffi_pure, "1.45.0", Some(58329), None), /// Allows using `#[ffi_returns_twice]` on foreign functions. - (active, ffi_returns_twice, "1.34.0", Some(58314), None), + (unstable, ffi_returns_twice, "1.34.0", Some(58314), None), /// Allows using `#[repr(align(...))]` on function items - (active, fn_align, "1.53.0", Some(82232), None), + (unstable, fn_align, "1.53.0", Some(82232), None), /// Allows generators to be cloned. - (active, generator_clone, "1.65.0", Some(95360), None), + (unstable, generator_clone, "1.65.0", Some(95360), None), /// Allows defining generators. - (active, generators, "1.21.0", Some(43122), None), + (unstable, generators, "1.21.0", Some(43122), None), /// Infer generic args for both consts and types. - (active, generic_arg_infer, "1.55.0", Some(85077), None), + (unstable, generic_arg_infer, "1.55.0", Some(85077), None), /// An extension to the `generic_associated_types` feature, allowing incomplete features. (incomplete, generic_associated_types_extended, "1.61.0", Some(95451), None), /// Allows non-trivial generic constants which have to have wfness manually propagated to callers @@ -476,139 +464,137 @@ declare_features! ( /// Allows generic parameters and where-clauses on free & associated const items. (incomplete, generic_const_items, "1.73.0", Some(113521), None), /// Allows using `..=X` as a patterns in slices. - (active, half_open_range_patterns_in_slices, "1.66.0", Some(67264), None), + (unstable, half_open_range_patterns_in_slices, "1.66.0", Some(67264), None), /// Allows `if let` guard in match arms. - (active, if_let_guard, "1.47.0", Some(51114), None), + (unstable, if_let_guard, "1.47.0", Some(51114), None), /// Allows `impl Trait` to be used inside associated types (RFC 2515). - (active, impl_trait_in_assoc_type, "1.70.0", Some(63063), None), + (unstable, impl_trait_in_assoc_type, "1.70.0", Some(63063), None), /// Allows `impl Trait` as output type in `Fn` traits in return position of functions. - (active, impl_trait_in_fn_trait_return, "1.64.0", Some(99697), None), + (unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697), None), /// Allows using imported `main` function - (active, imported_main, "1.53.0", Some(28937), None), + (unstable, imported_main, "1.53.0", Some(28937), None), /// Allows associated types in inherent impls. (incomplete, inherent_associated_types, "1.52.0", Some(8995), None), /// Allow anonymous constants from an inline `const` block - (active, inline_const, "1.49.0", Some(76001), None), + (unstable, inline_const, "1.49.0", Some(76001), None), /// Allow anonymous constants from an inline `const` block in pattern position (incomplete, inline_const_pat, "1.58.0", Some(76001), None), /// Allows using `pointer` and `reference` in intra-doc links - (active, intra_doc_pointers, "1.51.0", Some(80896), None), + (unstable, intra_doc_pointers, "1.51.0", Some(80896), None), // Allows setting the threshold for the `large_assignments` lint. - (active, large_assignments, "1.52.0", Some(83518), None), + (unstable, large_assignments, "1.52.0", Some(83518), None), /// Allow to have type alias types for inter-crate use. (incomplete, lazy_type_alias, "1.72.0", Some(112792), None), /// Allows `if/while p && let q = r && ...` chains. - (active, let_chains, "1.37.0", Some(53667), None), + (unstable, let_chains, "1.37.0", Some(53667), None), /// Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check. - (active, lint_reasons, "1.31.0", Some(54503), None), + (unstable, lint_reasons, "1.31.0", Some(54503), None), /// Give access to additional metadata about declarative macro meta-variables. - (active, macro_metavar_expr, "1.61.0", Some(83527), None), + (unstable, macro_metavar_expr, "1.61.0", Some(83527), None), /// Allows `#[marker]` on certain traits allowing overlapping implementations. - (active, marker_trait_attr, "1.30.0", Some(29864), None), + (unstable, marker_trait_attr, "1.30.0", Some(29864), None), /// A minimal, sound subset of specialization intended to be used by the /// standard library until the soundness issues with specialization /// are fixed. - (active, min_specialization, "1.7.0", Some(31844), None), + (unstable, min_specialization, "1.7.0", Some(31844), None), /// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns. - (active, more_qualified_paths, "1.54.0", Some(86935), None), + (unstable, more_qualified_paths, "1.54.0", Some(86935), None), /// Allows the `#[must_not_suspend]` attribute. - (active, must_not_suspend, "1.57.0", Some(83310), None), + (unstable, must_not_suspend, "1.57.0", Some(83310), None), /// Allows using `#[naked]` on functions. - (active, naked_functions, "1.9.0", Some(32408), None), + (unstable, naked_functions, "1.9.0", Some(32408), None), /// Allows specifying the as-needed link modifier - (active, native_link_modifiers_as_needed, "1.53.0", Some(81490), None), + (unstable, native_link_modifiers_as_needed, "1.53.0", Some(81490), None), /// Allow negative trait implementations. - (active, negative_impls, "1.44.0", Some(68318), None), + (unstable, negative_impls, "1.44.0", Some(68318), None), /// Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more. - (active, never_type, "1.13.0", Some(35121), None), + (unstable, never_type, "1.13.0", Some(35121), None), /// Allows diverging expressions to fall back to `!` rather than `()`. - (active, never_type_fallback, "1.41.0", Some(65992), None), + (unstable, never_type_fallback, "1.41.0", Some(65992), None), /// Allows `#![no_core]`. - (active, no_core, "1.3.0", Some(29639), None), + (unstable, no_core, "1.3.0", Some(29639), None), /// Allows the use of `no_sanitize` attribute. - (active, no_sanitize, "1.42.0", Some(39699), None), + (unstable, no_sanitize, "1.42.0", Some(39699), None), /// Allows using the `non_exhaustive_omitted_patterns` lint. - (active, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554), None), + (unstable, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554), None), /// Allows `for<T>` binders in where-clauses (incomplete, non_lifetime_binders, "1.69.0", Some(108185), None), /// Allows making `dyn Trait` well-formed even if `Trait` is not object safe. /// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and /// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden. - (active, object_safe_for_dispatch, "1.40.0", Some(43561), None), + (unstable, object_safe_for_dispatch, "1.40.0", Some(43561), None), /// Allows using `#[optimize(X)]`. - (active, optimize_attribute, "1.34.0", Some(54882), None), + (unstable, optimize_attribute, "1.34.0", Some(54882), None), /// Allows using `#![plugin(myplugin)]`. - (active, plugin, "1.0.0", Some(29597), None), + (unstable, plugin, "1.0.0", Some(29597), None), /// Allows exhaustive integer pattern matching on `usize` and `isize`. - (active, precise_pointer_size_matching, "1.32.0", Some(56354), None), + (unstable, precise_pointer_size_matching, "1.32.0", Some(56354), None), /// Allows macro attributes on expressions, statements and non-inline modules. - (active, proc_macro_hygiene, "1.30.0", Some(54727), None), + (unstable, proc_macro_hygiene, "1.30.0", Some(54727), None), /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions. - (active, raw_ref_op, "1.41.0", Some(64490), None), + (unstable, raw_ref_op, "1.41.0", Some(64490), None), /// Allows using the `#[register_tool]` attribute. - (active, register_tool, "1.41.0", Some(66079), None), + (unstable, register_tool, "1.41.0", Some(66079), None), /// Allows the `#[repr(i128)]` attribute for enums. (incomplete, repr128, "1.16.0", Some(56071), None), /// Allows `repr(simd)` and importing the various simd intrinsics. - (active, repr_simd, "1.4.0", Some(27731), None), - /// Allows return-position `impl Trait` in traits. - (active, return_position_impl_trait_in_trait, "1.65.0", Some(91611), None), + (unstable, repr_simd, "1.4.0", Some(27731), None), /// Allows bounding the return type of AFIT/RPITIT. (incomplete, return_type_notation, "1.70.0", Some(109417), None), /// Allows `extern "rust-cold"`. - (active, rust_cold_cc, "1.63.0", Some(97544), None), + (unstable, rust_cold_cc, "1.63.0", Some(97544), None), /// Allows the use of SIMD types in functions declared in `extern` blocks. - (active, simd_ffi, "1.0.0", Some(27731), None), + (unstable, simd_ffi, "1.0.0", Some(27731), None), /// Allows specialization of implementations (RFC 1210). (incomplete, specialization, "1.7.0", Some(31844), None), /// Allows attributes on expressions and non-item statements. - (active, stmt_expr_attributes, "1.6.0", Some(15701), None), + (unstable, stmt_expr_attributes, "1.6.0", Some(15701), None), /// Allows lints part of the strict provenance effort. - (active, strict_provenance, "1.61.0", Some(95228), None), + (unstable, strict_provenance, "1.61.0", Some(95228), None), /// Allows string patterns to dereference values to match them. - (active, string_deref_patterns, "1.67.0", Some(87121), None), + (unstable, string_deref_patterns, "1.67.0", Some(87121), None), /// Allows the use of `#[target_feature]` on safe functions. - (active, target_feature_11, "1.45.0", Some(69098), None), + (unstable, target_feature_11, "1.45.0", Some(69098), None), /// Allows using `#[thread_local]` on `static` items. - (active, thread_local, "1.0.0", Some(29594), None), + (unstable, thread_local, "1.0.0", Some(29594), None), /// Allows defining `trait X = A + B;` alias items. - (active, trait_alias, "1.24.0", Some(41517), None), + (unstable, trait_alias, "1.24.0", Some(41517), None), /// Allows dyn upcasting trait objects via supertraits. /// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`. - (active, trait_upcasting, "1.56.0", Some(65991), None), + (unstable, trait_upcasting, "1.56.0", Some(65991), None), /// Allows for transmuting between arrays with sizes that contain generic consts. - (active, transmute_generic_consts, "1.70.0", Some(109929), None), + (unstable, transmute_generic_consts, "1.70.0", Some(109929), None), /// Allows #[repr(transparent)] on unions (RFC 2645). - (active, transparent_unions, "1.37.0", Some(60405), None), + (unstable, transparent_unions, "1.37.0", Some(60405), None), /// Allows inconsistent bounds in where clauses. - (active, trivial_bounds, "1.28.0", Some(48214), None), + (unstable, trivial_bounds, "1.28.0", Some(48214), None), /// Allows using `try {...}` expressions. - (active, try_blocks, "1.29.0", Some(31436), None), + (unstable, try_blocks, "1.29.0", Some(31436), None), /// Allows `impl Trait` to be used inside type aliases (RFC 2515). - (active, type_alias_impl_trait, "1.38.0", Some(63063), None), + (unstable, type_alias_impl_trait, "1.38.0", Some(63063), None), /// Allows the use of type ascription in expressions. - (active, type_ascription, "1.6.0", Some(23416), None), + (unstable, type_ascription, "1.6.0", Some(23416), None), /// Allows creation of instances of a struct by moving fields that have /// not changed from prior instances of the same struct (RFC #2528) - (active, type_changing_struct_update, "1.58.0", Some(86555), None), + (unstable, type_changing_struct_update, "1.58.0", Some(86555), None), /// Allows using type privacy lints (`private_interfaces`, `private_bounds`, `unnameable_types`). - (active, type_privacy_lints, "1.72.0", Some(48054), None), + (unstable, type_privacy_lints, "1.72.0", Some(48054), None), /// Enables rustc to generate code that instructs libstd to NOT ignore SIGPIPE. - (active, unix_sigpipe, "1.65.0", Some(97889), None), + (unstable, unix_sigpipe, "1.65.0", Some(97889), None), /// Allows unnamed fields of struct and union type - (incomplete, unnamed_fields, "CURRENT_RUSTC_VERSION", Some(49804), None), + (incomplete, unnamed_fields, "1.74.0", Some(49804), None), /// Allows unsized fn parameters. - (active, unsized_fn_params, "1.49.0", Some(48055), None), + (unstable, unsized_fn_params, "1.49.0", Some(48055), None), /// Allows unsized rvalues at arguments and parameters. (incomplete, unsized_locals, "1.30.0", Some(48055), None), /// Allows unsized tuple coercion. - (active, unsized_tuple_coercion, "1.20.0", Some(42877), None), + (unstable, unsized_tuple_coercion, "1.20.0", Some(42877), None), /// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute. - (active, used_with_arg, "1.60.0", Some(93798), None), + (unstable, used_with_arg, "1.60.0", Some(93798), None), /// Allows `extern "wasm" fn` - (active, wasm_abi, "1.53.0", Some(83788), None), + (unstable, wasm_abi, "1.53.0", Some(83788), None), /// Allows `do yeet` expressions - (active, yeet_expr, "1.62.0", Some(96373), None), + (unstable, yeet_expr, "1.62.0", Some(96373), None), // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs index 21611e9c586..059dfc60450 100644 --- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs +++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs @@ -284,6 +284,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { self.one_bound_for_assoc_type( || traits::supertraits(tcx, trait_ref), trait_ref.skip_binder().print_only_trait_name(), + None, binding.item_name, path_span, match binding.kind { @@ -517,8 +518,10 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { ); if let DefKind::AssocConst = def_kind - && let Some(t) = term.ty() && (t.is_enum() || t.references_error()) - && tcx.features().associated_const_equality { + && let Some(t) = term.ty() + && (t.is_enum() || t.references_error()) + && tcx.features().associated_const_equality + { err.span_suggestion( binding.span, "if equating a const, try wrapping with braces", diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs index ed4dde419c4..9e18767a7c3 100644 --- a/compiler/rustc_hir_analysis/src/astconv/errors.rs +++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs @@ -6,10 +6,9 @@ use crate::errors::{ use rustc_data_structures::fx::FxHashMap; use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, ErrorGuaranteed}; use rustc_hir as hir; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::traits::FulfillmentError; -use rustc_middle::ty::TyCtxt; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, suggest_constraining_type_param, Ty, TyCtxt}; use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::symbol::{sym, Ident}; @@ -102,6 +101,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, all_candidates: impl Fn() -> I, ty_param_name: &str, + ty_param_def_id: Option<LocalDefId>, assoc_name: Ident, span: Span, ) -> ErrorGuaranteed @@ -190,13 +190,61 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }) .collect::<Vec<_>>()[..] { + let trait_name = self.tcx().def_path_str(*best_trait); + let an = if suggested_name != assoc_name.name { "a similarly named" } else { "an" }; err.span_label( assoc_name.span, format!( - "there is a similarly named associated type `{suggested_name}` in the trait `{}`", - self.tcx().def_path_str(*best_trait) + "there is {an} associated type `{suggested_name}` in the \ + trait `{trait_name}`", ), ); + let hir = self.tcx().hir(); + if let Some(def_id) = ty_param_def_id + && let parent = hir.get_parent_item(hir.local_def_id_to_hir_id(def_id)) + && let Some(generics) = hir.get_generics(parent.def_id) + { + if generics.bounds_for_param(def_id) + .flat_map(|pred| pred.bounds.iter()) + .any(|b| match b { + hir::GenericBound::Trait(t, ..) => { + t.trait_ref.trait_def_id().as_ref() == Some(best_trait) + } + _ => false, + }) + { + // The type param already has a bound for `trait_name`, we just need to + // change the associated type. + err.span_suggestion_verbose( + assoc_name.span, + format!( + "change the associated type name to use `{suggested_name}` from \ + `{trait_name}`", + ), + suggested_name.to_string(), + Applicability::MaybeIncorrect, + ); + } else if suggest_constraining_type_param( + self.tcx(), + generics, + &mut err, + &ty_param_name, + &trait_name, + None, + None, + ) + && suggested_name != assoc_name.name + { + // We suggested constraining a type parameter, but the associated type on it + // was also not an exact match, so we also suggest changing it. + err.span_suggestion_verbose( + assoc_name.span, + "and also change the associated type name", + suggested_name.to_string(), + Applicability::MaybeIncorrect, + ); + } + } return err.emit(); } } diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs index e3621ef933a..7f0c0b961e4 100644 --- a/compiler/rustc_hir_analysis/src/astconv/generics.rs +++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs @@ -432,9 +432,11 @@ pub(crate) fn check_generic_arg_count( let infer_lifetimes = (gen_pos != GenericArgPosition::Type || infer_args) && !gen_args.has_lifetime_params(); - if gen_pos != GenericArgPosition::Type && let Some(b) = gen_args.bindings.first() { - prohibit_assoc_ty_binding(tcx, b.span, None); - } + if gen_pos != GenericArgPosition::Type + && let Some(b) = gen_args.bindings.first() + { + prohibit_assoc_ty_binding(tcx, b.span, None); + } let explicit_late_bound = prohibit_explicit_late_bound_lifetimes(tcx, gen_params, gen_args, gen_pos); diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs index 1bd1270beaf..bc57bbcca62 100644 --- a/compiler/rustc_hir_analysis/src/astconv/lint.rs +++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs @@ -18,18 +18,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { - self_ty: impl_self_ty, of_trait: Some(of_trait_ref), generics, .. + self_ty: impl_self_ty, + of_trait: Some(of_trait_ref), + generics, + .. }), .. - }) = tcx.hir().get_by_def_id(parent_id) && self_ty.hir_id == impl_self_ty.hir_id + }) = tcx.hir().get_by_def_id(parent_id) + && self_ty.hir_id == impl_self_ty.hir_id { if !of_trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) { return; } let of_trait_span = of_trait_ref.path.span; // make sure that we are not calling unwrap to abort during the compilation - let Ok(impl_trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else { return; }; - let Ok(of_trait_name) = tcx.sess.source_map().span_to_snippet(of_trait_span) else { return; }; + let Ok(impl_trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else { + return; + }; + let Ok(of_trait_name) = tcx.sess.source_map().span_to_snippet(of_trait_span) else { + return; + }; // check if the trait has generics, to make a correct suggestion let param_name = generics.params.next_type_param_name(None); @@ -39,13 +47,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { (generics.span, format!("<{param_name}: {impl_trait_name}>")) }; diag.multipart_suggestion( - format!("alternatively use a blanket \ + format!( + "alternatively use a blanket \ implementation to implement `{of_trait_name}` for \ - all types that also implement `{impl_trait_name}`"), - vec![ - (self_ty.span, param_name), - add_generic_sugg, - ], + all types that also implement `{impl_trait_name}`" + ), + vec![(self_ty.span, param_name), add_generic_sugg], Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index a91d9231390..6bcf33a1f6d 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -567,9 +567,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ); if let ty::BoundConstness::ConstIfConst = constness - && generics.has_self && !tcx.has_attr(def_id, sym::const_trait) + && generics.has_self + && !tcx.has_attr(def_id, sym::const_trait) { - tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span } ); + tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span }); } (args, arg_count) @@ -1061,6 +1062,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) }, param_name, + Some(ty_param_def_id), assoc_name, span, None, @@ -1074,6 +1076,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, all_candidates: impl Fn() -> I, ty_param_name: impl Display, + ty_param_def_id: Option<LocalDefId>, assoc_name: Ident, span: Span, is_equality: Option<ty::Term<'tcx>>, @@ -1095,6 +1098,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let reported = self.complain_about_assoc_type_not_found( all_candidates, &ty_param_name.to_string(), + ty_param_def_id, assoc_name, span, ); @@ -1142,30 +1146,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.span_label( bound_span, format!( - "ambiguous `{}` from `{}`", - assoc_name, + "ambiguous `{assoc_name}` from `{}`", bound.print_only_trait_path(), ), ); if let Some(constraint) = &is_equality { where_bounds.push(format!( - " T: {trait}::{assoc} = {constraint}", + " T: {trait}::{assoc_name} = {constraint}", trait=bound.print_only_trait_path(), - assoc=assoc_name, - constraint=constraint, )); } else { err.span_suggestion_verbose( span.with_hi(assoc_name.span.lo()), "use fully qualified syntax to disambiguate", - format!("<{} as {}>::", ty_param_name, bound.print_only_trait_path()), + format!("<{ty_param_name} as {}>::", bound.print_only_trait_path()), Applicability::MaybeIncorrect, ); } } else { err.note(format!( - "associated type `{}` could derive from `{}`", - ty_param_name, + "associated type `{ty_param_name}` could derive from `{}`", bound.print_only_trait_path(), )); } @@ -1173,8 +1173,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if !where_bounds.is_empty() { err.help(format!( "consider introducing a new type parameter `T` and adding `where` constraints:\ - \n where\n T: {},\n{}", - ty_param_name, + \n where\n T: {ty_param_name},\n{}", where_bounds.join(",\n"), )); } @@ -1396,6 +1395,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) }, kw::SelfUpper, + None, assoc_ident, span, None, @@ -1919,9 +1919,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } else { Some(( match segment.res { - Res::PrimTy(ty) => format!("{} `{}`", segment.res.descr(), ty.name()), + Res::PrimTy(ty) => { + format!("{} `{}`", segment.res.descr(), ty.name()) + } Res::Def(_, def_id) - if let Some(name) = self.tcx().opt_item_name(def_id) => { + if let Some(name) = self.tcx().opt_item_name(def_id) => + { format!("{} `{name}`", segment.res.descr()) } Res::Err => "this type".to_string(), @@ -2251,7 +2254,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.note(msg); } for segment in path.segments { - if let Some(args) = segment.args && segment.ident.name == kw::SelfUpper { + if let Some(args) = segment.args + && segment.ident.name == kw::SelfUpper + { if generics == 0 { // FIXME(estebank): we could also verify that the arguments being // work for the `enum`, instead of just looking if it takes *any*. @@ -2633,7 +2638,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .iter() .enumerate() .map(|(i, a)| { - if let hir::TyKind::Infer = a.kind && !self.allow_ty_infer() { + if let hir::TyKind::Infer = a.kind + && !self.allow_ty_infer() + { if let Some(suggested_ty) = self.suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i)) { @@ -2662,7 +2669,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.ast_ty_to_ty(output) } } - hir::FnRetTy::DefaultReturn(..) => Ty::new_unit(tcx,), + hir::FnRetTy::DefaultReturn(..) => Ty::new_unit(tcx), }; debug!(?output_ty); diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 486aac21972..1745488dfd3 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -481,8 +481,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { fn_maybe_err(tcx, assoc_item.ident(tcx).span, abi); } ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => { - let trait_args = - GenericArgs::identity_for_item(tcx, id.owner_id); + let trait_args = GenericArgs::identity_for_item(tcx, id.owner_id); let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds( tcx, assoc_item, @@ -502,7 +501,8 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { } DefKind::OpaqueTy => { let origin = tcx.opaque_type_origin(id.owner_id.def_id); - if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin + if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) + | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin && let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id) && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn() { @@ -589,7 +589,9 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { } DefKind::GlobalAsm => { let it = tcx.hir().item(id); - let hir::ItemKind::GlobalAsm(asm) = it.kind else { span_bug!(it.span, "DefKind::GlobalAsm but got {:#?}", it) }; + let hir::ItemKind::GlobalAsm(asm) = it.kind else { + span_bug!(it.span, "DefKind::GlobalAsm but got {:#?}", it) + }; InlineAsmCtxt::new_global_asm(tcx).check_asm(asm, id.owner_id.def_id); } _ => {} @@ -783,21 +785,21 @@ fn check_impl_items_against_trait<'tcx>( let (msg, feature) = if tcx.asyncness(def_id).is_async() { ( format!("async {descr} in trait cannot be specialized"), - sym::async_fn_in_trait, + "async functions in traits", ) } else { ( format!( "{descr} with return-position `impl Trait` in trait cannot be specialized" ), - sym::return_position_impl_trait_in_trait, + "return position `impl Trait` in traits", ) }; tcx.sess .struct_span_err(tcx.def_span(def_id), msg) .note(format!( "specialization behaves in inconsistent and \ - surprising ways with `#![feature({feature})]`, \ + surprising ways with {feature}, \ and for now is disallowed" )) .emit(); @@ -873,10 +875,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) => (), // struct(u8, u8, u8, u8) is ok ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors ty::Array(t, _clen) - if matches!( - t.kind(), - ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) - ) => + if matches!(t.kind(), ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_)) => { /* struct([f32; 4]) is ok */ } _ => { struct_span_err!( @@ -899,17 +898,17 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) { for attr in tcx.get_attrs(def.did(), sym::repr) { for r in attr::parse_repr_attr(&tcx.sess, attr) { if let attr::ReprPacked(pack) = r - && let Some(repr_pack) = repr.pack - && pack as u64 != repr_pack.bytes() - { - struct_span_err!( - tcx.sess, - sp, - E0634, - "type has conflicting packed representation hints" - ) - .emit(); - } + && let Some(repr_pack) = repr.pack + && pack as u64 != repr_pack.bytes() + { + struct_span_err!( + tcx.sess, + sp, + E0634, + "type has conflicting packed representation hints" + ) + .emit(); + } } } if repr.align.is_some() { @@ -1174,7 +1173,8 @@ fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) let (span, display_discr) = match var.discr { ty::VariantDiscr::Explicit(discr_def_id) => { // In the case the discriminant is both a duplicate and overflowed, let the user know - if let hir::Node::AnonConst(expr) = tcx.hir().get_by_def_id(discr_def_id.expect_local()) + if let hir::Node::AnonConst(expr) = + tcx.hir().get_by_def_id(discr_def_id.expect_local()) && let hir::ExprKind::Lit(lit) = &tcx.hir().body(expr.body).value.kind && let rustc_ast::LitKind::Int(lit_value, _int_kind) = &lit.node && *lit_value != dis.val @@ -1303,15 +1303,9 @@ pub(super) fn check_type_params_are_used<'tcx>( && let ty::GenericParamDefKind::Type { .. } = param.kind { let span = tcx.def_span(param.def_id); - struct_span_err!( - tcx.sess, - span, - E0091, - "type parameter `{}` is unused", - param.name, - ) - .span_label(span, "unused type parameter") - .emit(); + struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name,) + .span_label(span, "unused type parameter") + .emit(); } } } @@ -1430,7 +1424,10 @@ fn opaque_type_cycle_error( let mut label_match = |ty: Ty<'_>, span| { for arg in ty.walk() { if let ty::GenericArgKind::Type(ty) = arg.unpack() - && let ty::Alias(ty::Opaque, ty::AliasTy { def_id: captured_def_id, .. }) = *ty.kind() + && let ty::Alias( + ty::Opaque, + ty::AliasTy { def_id: captured_def_id, .. }, + ) = *ty.kind() && captured_def_id == opaque_def_id.to_def_id() { err.span_label( diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index f1514ecf69c..2eb9b773b2e 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -633,8 +633,6 @@ fn compare_asyncness<'tcx>( /// For example, given the sample code: /// /// ``` -/// #![feature(return_position_impl_trait_in_trait)] -/// /// use std::ops::Deref; /// /// trait Foo { @@ -1011,7 +1009,11 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> { }); self.types.insert(proj.def_id, (infer_ty, proj.args)); // Recurse into bounds - for (pred, pred_span) in self.interner().explicit_item_bounds(proj.def_id).iter_instantiated_copied(self.interner(), proj.args) { + for (pred, pred_span) in self + .interner() + .explicit_item_bounds(proj.def_id) + .iter_instantiated_copied(self.interner(), proj.args) + { let pred = pred.fold_with(self); let pred = self.ocx.normalize( &ObligationCause::misc(self.span, self.body_id), @@ -1182,7 +1184,8 @@ fn report_trait_method_mismatch<'tcx>( if trait_sig.inputs().len() == *i { // Suggestion to change output type. We do not suggest in `async` functions // to avoid complex logic or incorrect output. - if let ImplItemKind::Fn(sig, _) = &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind + if let ImplItemKind::Fn(sig, _) = + &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind && !sig.header.asyncness.is_async() { let msg = "change the output type to match the trait"; diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 97ebd42d077..34c28bce5d8 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -314,9 +314,10 @@ fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) { /// fn into_iter<'a>(&'a self) -> Self::Iter<'a>; /// } /// ``` -fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRef]) { +fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) { // Associates every GAT's def_id to a list of possibly missing bounds detected by this lint. let mut required_bounds_by_item = FxHashMap::default(); + let associated_items = tcx.associated_items(trait_def_id); // Loop over all GATs together, because if this lint suggests adding a where-clause bound // to one GAT, it might then require us to an additional bound on another GAT. @@ -325,8 +326,8 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe // those GATs. loop { let mut should_continue = false; - for gat_item in associated_items { - let gat_def_id = gat_item.id.owner_id; + for gat_item in associated_items.in_definition_order() { + let gat_def_id = gat_item.def_id.expect_local(); let gat_item = tcx.associated_item(gat_def_id); // If this item is not an assoc ty, or has no args, then it's not a GAT if gat_item.kind != ty::AssocKind::Type { @@ -342,8 +343,8 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe // This is calculated by taking the intersection of the bounds that each item // constrains the GAT with individually. let mut new_required_bounds: Option<FxHashSet<ty::Clause<'_>>> = None; - for item in associated_items { - let item_def_id = item.id.owner_id; + for item in associated_items.in_definition_order() { + let item_def_id = item.def_id.expect_local(); // Skip our own GAT, since it does not constrain itself at all. if item_def_id == gat_def_id { continue; @@ -351,9 +352,9 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe let param_env = tcx.param_env(item_def_id); - let item_required_bounds = match item.kind { + let item_required_bounds = match tcx.associated_item(item_def_id).kind { // In our example, this corresponds to `into_iter` method - hir::AssocItemKind::Fn { .. } => { + ty::AssocKind::Fn => { // For methods, we check the function signature's return type for any GATs // to constrain. In the `into_iter` case, we see that the return type // `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from. @@ -369,12 +370,12 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe // We also assume that all of the function signature's parameter types // are well formed. &sig.inputs().iter().copied().collect(), - gat_def_id.def_id, + gat_def_id, gat_generics, ) } // In our example, this corresponds to the `Iter` and `Item` associated types - hir::AssocItemKind::Type => { + ty::AssocKind::Type => { // If our associated item is a GAT with missing bounds, add them to // the param-env here. This allows this GAT to propagate missing bounds // to other GATs. @@ -391,11 +392,11 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe .instantiate_identity_iter_copied() .collect::<Vec<_>>(), &FxIndexSet::default(), - gat_def_id.def_id, + gat_def_id, gat_generics, ) } - hir::AssocItemKind::Const => None, + ty::AssocKind::Const => None, }; if let Some(item_required_bounds) = item_required_bounds { @@ -431,7 +432,12 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe } for (gat_def_id, required_bounds) in required_bounds_by_item { - let gat_item_hir = tcx.hir().expect_trait_item(gat_def_id.def_id); + // Don't suggest adding `Self: 'a` to a GAT that can't be named + if tcx.is_impl_trait_in_trait(gat_def_id.to_def_id()) { + continue; + } + + let gat_item_hir = tcx.hir().expect_trait_item(gat_def_id); debug!(?required_bounds); let param_env = tcx.param_env(gat_def_id); @@ -441,21 +447,16 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => { !region_known_to_outlive( tcx, - gat_def_id.def_id, + gat_def_id, param_env, &FxIndexSet::default(), a, b, ) } - ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => !ty_known_to_outlive( - tcx, - gat_def_id.def_id, - param_env, - &FxIndexSet::default(), - a, - b, - ), + ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => { + !ty_known_to_outlive(tcx, gat_def_id, param_env, &FxIndexSet::default(), a, b) + } _ => bug!("Unexpected ClauseKind"), }) .map(|clause| clause.to_string()) @@ -534,7 +535,7 @@ fn augment_param_env<'tcx>( fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - item_def_id: hir::OwnerId, + item_def_id: LocalDefId, to_check: T, wf_tys: &FxIndexSet<Ty<'tcx>>, gat_def_id: LocalDefId, @@ -567,7 +568,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>( // reflected in a where clause on the GAT itself. for (ty, ty_idx) in &types { // In our example, requires that `Self: 'a` - if ty_known_to_outlive(tcx, item_def_id.def_id, param_env, &wf_tys, *ty, *region_a) { + if ty_known_to_outlive(tcx, item_def_id, param_env, &wf_tys, *ty, *region_a) { debug!(?ty_idx, ?region_a_idx); debug!("required clause: {ty} must outlive {region_a}"); // Translate into the generic parameters of the GAT. In @@ -606,14 +607,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>( if matches!(**region_b, ty::ReStatic | ty::ReError(_)) || region_a == region_b { continue; } - if region_known_to_outlive( - tcx, - item_def_id.def_id, - param_env, - &wf_tys, - *region_a, - *region_b, - ) { + if region_known_to_outlive(tcx, item_def_id, param_env, &wf_tys, *region_a, *region_b) { debug!(?region_a_idx, ?region_b_idx); debug!("required clause: {region_a} must outlive {region_b}"); // Translate into the generic parameters of the GAT. @@ -1114,8 +1108,8 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { }); // Only check traits, don't check trait aliases - if let hir::ItemKind::Trait(_, _, _, _, items) = item.kind { - check_gat_where_clauses(tcx, items); + if let hir::ItemKind::Trait(..) = item.kind { + check_gat_where_clauses(tcx, item.owner_id.def_id); } } diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index e3e724df272..8fafbc4167f 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -550,9 +550,11 @@ fn infringing_fields_error( .entry((ty.clone(), predicate.clone())) .or_default() .push(origin.span()); - if let ty::RegionKind::ReEarlyBound(ebr) = *b && ebr.has_name() { - bounds.push((b.to_string(), a.to_string(), None)); - } + if let ty::RegionKind::ReEarlyBound(ebr) = *b + && ebr.has_name() + { + bounds.push((b.to_string(), a.to_string(), None)); + } } RegionResolutionError::GenericBoundFailure(origin, a, b) => { let predicate = format!("{a}: {b}"); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 221df4e36b2..8e124d8eb1a 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -212,7 +212,9 @@ pub(crate) fn placeholder_type_error_diag<'tcx>( let mut is_fn = false; let mut is_const_or_static = false; - if let Some(hir_ty) = hir_ty && let hir::TyKind::BareFn(_) = hir_ty.kind { + if let Some(hir_ty) = hir_ty + && let hir::TyKind::BareFn(_) = hir_ty.kind + { is_fn = true; // Check if parent is const or static @@ -224,10 +226,8 @@ pub(crate) fn placeholder_type_error_diag<'tcx>( Node::Item(&hir::Item { kind: hir::ItemKind::Const(..) | hir::ItemKind::Static(..), .. - }) | Node::TraitItem(&hir::TraitItem { - kind: hir::TraitItemKind::Const(..), - .. - }) | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) + }) | Node::TraitItem(&hir::TraitItem { kind: hir::TraitItemKind::Const(..), .. }) + | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) ); } @@ -1004,10 +1004,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { && let Some(lit) = meta.name_value_literal() { if seen_attr { - tcx.sess.span_err( - meta.span, - "duplicated `implement_via_object` meta item", - ); + tcx.sess.span_err(meta.span, "duplicated `implement_via_object` meta item"); } seen_attr = true; @@ -1021,7 +1018,10 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { _ => { tcx.sess.span_err( meta.span, - format!("unknown literal passed to `implement_via_object` attribute: {}", lit.symbol), + format!( + "unknown literal passed to `implement_via_object` attribute: {}", + lit.symbol + ), ); } } @@ -1115,8 +1115,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig< ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), generics, .. }) => { // Do not try to infer the return type for a impl method coming from a trait - if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = - tcx.hir().get_parent(hir_id) + if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = tcx.hir().get_parent(hir_id) && i.of_trait.is_some() { icx.astconv().ty_of_fn( @@ -1343,7 +1342,13 @@ fn suggest_impl_trait<'tcx>( if ocx.select_where_possible().is_empty() && let item_ty = infcx.resolve_vars_if_possible(item_ty) && let Some(item_ty) = item_ty.make_suggestable(tcx, false) - && let Some(sugg) = formatter(tcx, infcx.resolve_vars_if_possible(args), trait_def_id, assoc_item_def_id, item_ty) + && let Some(sugg) = formatter( + tcx, + infcx.resolve_vars_if_possible(args), + trait_def_id, + assoc_item_def_id, + item_ty, + ) { return Some(sugg); } diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 4b7743fae53..d746e6dea75 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -169,8 +169,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTyToOpaque<'tcx> { fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { if let ty::Alias(ty::Projection, projection_ty) = ty.kind() - && let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) - = self.tcx.opt_rpitit_info(projection_ty.def_id) + && let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) = + self.tcx.opt_rpitit_info(projection_ty.def_id) && fn_def_id == self.fn_def_id { self.tcx.type_of(projection_ty.def_id).instantiate(self.tcx, projection_ty.args) diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 1298c086087..1b38f77654c 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -180,7 +180,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // // default impl Foo for Bar { .. } // - // we add a default where clause `Foo: Bar`. We do a similar thing for traits + // we add a default where clause `Bar: Foo`. We do a similar thing for traits // (see below). Recall that a default impl is not itself an impl, but rather a // set of defaults that can be incorporated into another impl. if let Some(trait_ref) = is_default_impl_trait { @@ -389,7 +389,9 @@ fn const_evaluatable_predicates_of( let node = tcx.hir().get(hir_id); let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() }; - if let hir::Node::Item(item) = node && let hir::ItemKind::Impl(impl_) = item.kind { + if let hir::Node::Item(item) = node + && let hir::ItemKind::Impl(impl_) = item.kind + { if let Some(of_trait) = &impl_.of_trait { debug!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id); collector.visit_trait_ref(of_trait); diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index eb4466449a0..ebb9e6f42d9 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1190,7 +1190,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { Scope::Root { opt_parent_item } => { if let Some(parent_item) = opt_parent_item && let parent_generics = self.tcx.generics_of(parent_item) - && parent_generics.param_def_id_to_index(self.tcx, region_def_id.to_def_id()).is_some() + && parent_generics + .param_def_id_to_index(self.tcx, region_def_id.to_def_id()) + .is_some() { break Some(ResolvedArg::EarlyBound(region_def_id.to_def_id())); } @@ -1209,13 +1211,14 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // regular fns. if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin && let hir::LifetimeName::Param(param_id) = lifetime_ref.res - && let Some(generics) = self.tcx.hir().get_generics(self.tcx.local_parent(param_id)) + && let Some(generics) = + self.tcx.hir().get_generics(self.tcx.local_parent(param_id)) && let Some(param) = generics.params.iter().find(|p| p.def_id == param_id) && param.is_elided_lifetime() && !self.tcx.asyncness(lifetime_ref.hir_id.owner.def_id).is_async() && !self.tcx.features().anonymous_lifetime_in_impl_trait { - let mut diag = rustc_session::parse::feature_err( + let mut diag = rustc_session::parse::feature_err( &self.tcx.sess.parse_sess, sym::anonymous_lifetime_in_impl_trait, lifetime_ref.ident.span, @@ -1225,25 +1228,31 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { if let Some(generics) = self.tcx.hir().get_generics(lifetime_ref.hir_id.owner.def_id) { - let new_param_sugg = if let Some(span) = - generics.span_for_lifetime_suggestion() - { - (span, "'a, ".to_owned()) - } else { - (generics.span, "<'a>".to_owned()) - }; + let new_param_sugg = + if let Some(span) = generics.span_for_lifetime_suggestion() { + (span, "'a, ".to_owned()) + } else { + (generics.span, "<'a>".to_owned()) + }; let lifetime_sugg = match lifetime_ref.suggestion_position() { - (hir::LifetimeSuggestionPosition::Normal, span) => (span, "'a".to_owned()), - (hir::LifetimeSuggestionPosition::Ampersand, span) => (span, "'a ".to_owned()), - (hir::LifetimeSuggestionPosition::ElidedPath, span) => (span, "<'a>".to_owned()), - (hir::LifetimeSuggestionPosition::ElidedPathArgument, span) => (span, "'a, ".to_owned()), - (hir::LifetimeSuggestionPosition::ObjectDefault, span) => (span, "+ 'a".to_owned()), + (hir::LifetimeSuggestionPosition::Normal, span) => { + (span, "'a".to_owned()) + } + (hir::LifetimeSuggestionPosition::Ampersand, span) => { + (span, "'a ".to_owned()) + } + (hir::LifetimeSuggestionPosition::ElidedPath, span) => { + (span, "<'a>".to_owned()) + } + (hir::LifetimeSuggestionPosition::ElidedPathArgument, span) => { + (span, "'a, ".to_owned()) + } + (hir::LifetimeSuggestionPosition::ObjectDefault, span) => { + (span, "+ 'a".to_owned()) + } }; - let suggestions = vec![ - lifetime_sugg, - new_param_sugg, - ]; + let suggestions = vec![lifetime_sugg, new_param_sugg]; diag.span_label( lifetime_ref.ident.span, @@ -1378,7 +1387,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { Scope::Root { opt_parent_item } => { if let Some(parent_item) = opt_parent_item && let parent_generics = self.tcx.generics_of(parent_item) - && parent_generics.param_def_id_to_index(self.tcx, param_def_id.to_def_id()).is_some() + && parent_generics + .param_def_id_to_index(self.tcx, param_def_id.to_def_id()) + .is_some() { break Some(ResolvedArg::EarlyBound(param_def_id.to_def_id())); } @@ -1689,14 +1700,12 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { if binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation { let bound_vars = if let Some(type_def_id) = type_def_id && self.tcx.def_kind(type_def_id) == DefKind::Trait - && let Some((mut bound_vars, assoc_fn)) = - BoundVarContext::supertrait_hrtb_vars( - self.tcx, - type_def_id, - binding.ident, - ty::AssocKind::Fn, - ) - { + && let Some((mut bound_vars, assoc_fn)) = BoundVarContext::supertrait_hrtb_vars( + self.tcx, + type_def_id, + binding.ident, + ty::AssocKind::Fn, + ) { bound_vars.extend(self.tcx.generics_of(assoc_fn.def_id).params.iter().map( |param| match param.kind { ty::GenericParamDefKind::Lifetime => ty::BoundVariableKind::Region( @@ -1708,14 +1717,14 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { ty::GenericParamDefKind::Const { .. } => ty::BoundVariableKind::Const, }, )); - bound_vars - .extend(self.tcx.fn_sig(assoc_fn.def_id).instantiate_identity().bound_vars()); + bound_vars.extend( + self.tcx.fn_sig(assoc_fn.def_id).instantiate_identity().bound_vars(), + ); bound_vars } else { - self.tcx.sess.delay_span_bug( - binding.ident.span, - "bad return type notation here", - ); + self.tcx + .sess + .delay_span_bug(binding.ident.span, "bad return type notation here"); vec![] }; self.with(scope, |this| { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index ae62119b182..47a412c2110 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -30,10 +30,10 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) if constant.hir_id() == hir_id => { - return tcx.types.usize + return tcx.types.usize; } Node::Ty(&hir::Ty { kind: TyKind::Typeof(ref e), .. }) if e.hir_id == hir_id => { - return tcx.typeck(def_id).node_type(e.hir_id) + return tcx.typeck(def_id).node_type(e.hir_id); } Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) @@ -43,36 +43,38 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { _ => false, }) => { - return tcx.typeck(def_id).node_type(hir_id) + return tcx.typeck(def_id).node_type(hir_id); } Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => { - return tcx - .adt_def(tcx.hir().get_parent_item(hir_id)) - .repr() - .discr_type() - .to_ty(tcx) + return tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx); } Node::GenericParam(&GenericParam { def_id: param_def_id, kind: GenericParamKind::Const { default: Some(ct), .. }, .. }) if ct.hir_id == hir_id => { - return tcx.type_of(param_def_id) + return tcx + .type_of(param_def_id) .no_bound_vars() - .expect("const parameter types cannot be generic") + .expect("const parameter types cannot be generic"); } - Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. }) - if let Node::TraitRef(trait_ref) = tcx.hir().get( - tcx.hir().parent_id(binding_id) - ) => + Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. }) + if let Node::TraitRef(trait_ref) = tcx.hir().get(tcx.hir().parent_id(binding_id)) => { let Some(trait_def_id) = trait_ref.trait_def_id() else { - return Ty::new_error_with_message(tcx,tcx.def_span(def_id), "Could not find trait"); + return Ty::new_error_with_message( + tcx, + tcx.def_span(def_id), + "Could not find trait", + ); }; let assoc_items = tcx.associated_items(trait_def_id); let assoc_item = assoc_items.find_by_name_and_kind( - tcx, binding.ident, ty::AssocKind::Const, def_id.to_def_id(), + tcx, + binding.ident, + ty::AssocKind::Const, + def_id.to_def_id(), ); return if let Some(assoc_item) = assoc_item { tcx.type_of(assoc_item.def_id) @@ -80,8 +82,12 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { .expect("const parameter types cannot be generic") } else { // FIXME(associated_const_equality): add a useful error message here. - Ty::new_error_with_message(tcx,tcx.def_span(def_id), "Could not find associated const on trait") - } + Ty::new_error_with_message( + tcx, + tcx.def_span(def_id), + "Could not find associated const on trait", + ) + }; } // This match arm is for when the def_id appears in a GAT whose @@ -138,7 +144,8 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { (generics, arg_index) } else { // I dont think it's possible to reach this but I'm not 100% sure - BoxyUwU - return Ty::new_error_with_message(tcx, + return Ty::new_error_with_message( + tcx, tcx.def_span(def_id), "unexpected non-GAT usage of an anon const", ); @@ -155,7 +162,8 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { // As there is no relevant param for `def_id`, we simply return // `None` here. let Some(type_dependent_def) = tables.type_dependent_def_id(parent_node_id) else { - return Ty::new_error_with_message(tcx, + return Ty::new_error_with_message( + tcx, tcx.def_span(def_id), format!("unable to find type-dependent def for {parent_node_id:?}"), ); @@ -196,14 +204,16 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { if let Some(path) = get_path_containing_arg_in_pat(pat, hir_id) { path } else { - return Ty::new_error_with_message(tcx, + return Ty::new_error_with_message( + tcx, tcx.def_span(def_id), format!("unable to find const parent for {hir_id} in pat {pat:?}"), ); } } _ => { - return Ty::new_error_with_message(tcx, + return Ty::new_error_with_message( + tcx, tcx.def_span(def_id), format!("unexpected const parent path {parent_node:?}"), ); @@ -216,16 +226,20 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { let Some((arg_index, segment)) = path.segments.iter().find_map(|seg| { let args = seg.args?; args.args - .iter() - .filter(|arg| arg.is_ty_or_const()) - .position(|arg| arg.hir_id() == hir_id) - .map(|index| (index, seg)).or_else(|| args.bindings .iter() - .filter_map(TypeBinding::opt_const) - .position(|ct| ct.hir_id == hir_id) - .map(|idx| (idx, seg))) + .filter(|arg| arg.is_ty_or_const()) + .position(|arg| arg.hir_id() == hir_id) + .map(|index| (index, seg)) + .or_else(|| { + args.bindings + .iter() + .filter_map(TypeBinding::opt_const) + .position(|ct| ct.hir_id == hir_id) + .map(|idx| (idx, seg)) + }) }) else { - return Ty::new_error_with_message(tcx, + return Ty::new_error_with_message( + tcx, tcx.def_span(def_id), "no arg matching AnonConst in path", ); @@ -234,7 +248,8 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { let generics = match tcx.res_generics_def_id(segment.res) { Some(def_id) => tcx.generics_of(def_id), None => { - return Ty::new_error_with_message(tcx, + return Ty::new_error_with_message( + tcx, tcx.def_span(def_id), format!("unexpected anon const res {:?} in path: {:?}", segment.res, path), ); @@ -244,10 +259,13 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { (generics, arg_index) } - _ => return Ty::new_error_with_message(tcx, - tcx.def_span(def_id), - format!("unexpected const parent in type_of(): {parent_node:?}"), - ), + _ => { + return Ty::new_error_with_message( + tcx, + tcx.def_span(def_id), + format!("unexpected const parent in type_of(): {parent_node:?}"), + ); + } }; debug!(?parent_node); diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 0efe82b20ee..1120585f1aa 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -226,7 +226,9 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams { let mut suggested = false; // Don't suggest setting the type params if there are some already: the order is // tricky to get right and the user will already know what the syntax is. - if let Some(snippet) = self.span_snippet && self.empty_generic_args { + if let Some(snippet) = self.span_snippet + && self.empty_generic_args + { if snippet.ends_with('>') { // The user wrote `Trait<'a, T>` or similar. To provide an accurate suggestion // we would have to preserve the right order. For now, as clearly the user is diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index b4af321fcc9..7941861fd2f 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -131,7 +131,9 @@ fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node } fn check_has_items(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node, span: Span) { - if let Node::Impl(impl2_id) = impl2_node && tcx.associated_item_def_ids(impl1_def_id).is_empty() { + if let Node::Impl(impl2_id) = impl2_node + && tcx.associated_item_def_ids(impl1_def_id).is_empty() + { let base_impl_span = tcx.def_span(impl2_id); tcx.sess.emit_err(errors::EmptySpecialization { span, base_impl_span }); } diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 61b182b1be7..2b5f6fd214c 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -316,12 +316,18 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { } // Suggest `'_` when in function parameter or elided function return. - if let Some(fn_decl) = node.fn_decl() && let Some(ty_id) = ty_id { + if let Some(fn_decl) = node.fn_decl() + && let Some(ty_id) = ty_id + { let in_arg = fn_decl.inputs.iter().any(|t| t.hir_id == ty_id); - let in_ret = matches!(fn_decl.output, hir::FnRetTy::Return(ty) if ty.hir_id == ty_id); + let in_ret = + matches!(fn_decl.output, hir::FnRetTy::Return(ty) if ty.hir_id == ty_id); if in_arg || (in_ret && fn_decl.lifetime_elision_allowed) { - return std::iter::repeat("'_".to_owned()).take(num_params_to_take).collect::<Vec<_>>().join(", "); + return std::iter::repeat("'_".to_owned()) + .take(num_params_to_take) + .collect::<Vec<_>>() + .join(", "); } } @@ -730,28 +736,27 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { ); if let Some(parent_node) = self.tcx.hir().opt_parent_id(self.path_segment.hir_id) - && let Some(parent_node) = self.tcx.hir().find(parent_node) - && let hir::Node::Expr(expr) = parent_node { + && let Some(parent_node) = self.tcx.hir().find(parent_node) + && let hir::Node::Expr(expr) = parent_node + { match &expr.kind { - hir::ExprKind::Path(qpath) => { - self.suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path( + hir::ExprKind::Path(qpath) => self + .suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path( err, qpath, msg, num_assoc_fn_excess_args, - num_trait_generics_except_self - ) - }, - hir::ExprKind::MethodCall(..) => { - self.suggest_moving_args_from_assoc_fn_to_trait_for_method_call( + num_trait_generics_except_self, + ), + hir::ExprKind::MethodCall(..) => self + .suggest_moving_args_from_assoc_fn_to_trait_for_method_call( err, trait_, expr, msg, num_assoc_fn_excess_args, - num_trait_generics_except_self - ) - }, + num_trait_generics_except_self, + ), _ => return, } } @@ -766,23 +771,25 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { num_trait_generics_except_self: usize, ) { if let hir::QPath::Resolved(_, path) = qpath - && let Some(trait_path_segment) = path.segments.get(0) { + && let Some(trait_path_segment) = path.segments.get(0) + { let num_generic_args_supplied_to_trait = trait_path_segment.args().num_generic_params(); - if num_generic_args_supplied_to_trait + num_assoc_fn_excess_args == num_trait_generics_except_self + if num_generic_args_supplied_to_trait + num_assoc_fn_excess_args + == num_trait_generics_except_self { if let Some(span) = self.gen_args.span_ext() - && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { + && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) + { let sugg = vec![ - (self.path_segment.ident.span, format!("{}::{}", snippet, self.path_segment.ident)), - (span.with_lo(self.path_segment.ident.span.hi()), "".to_owned()) + ( + self.path_segment.ident.span, + format!("{}::{}", snippet, self.path_segment.ident), + ), + (span.with_lo(self.path_segment.ident.span.hi()), "".to_owned()), ]; - err.multipart_suggestion( - msg, - sugg, - Applicability::MaybeIncorrect - ); + err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect); } } } diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 81fe0cc489e..aef880acbe1 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -373,7 +373,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 6 | | }; // | |_____^ expected integer, found `()` // ``` - if block.expr.is_none() && block.stmts.is_empty() + if block.expr.is_none() + && block.stmts.is_empty() && let Some(outer_span) = &mut outer_span && let Some(cond_span) = cond_span.find_ancestor_inside(*outer_span) { diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index f2c58ee2702..512d73fc103 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -421,13 +421,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .steal_diagnostic(segment.ident.span, StashKey::CallIntoMethod) { // Try suggesting `foo(a)` -> `a.foo()` if possible. - self.suggest_call_as_method( - &mut diag, - segment, - arg_exprs, - call_expr, - expected - ); + self.suggest_call_as_method(&mut diag, segment, arg_exprs, call_expr, expected); diag.emit(); } diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 2b1ac7f3537..419e154a17a 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -373,50 +373,49 @@ impl<'a, 'tcx> CastCheck<'tcx> { let mut sugg_mutref = false; if let ty::Ref(reg, cast_ty, mutbl) = *self.cast_ty.kind() { if let ty::RawPtr(TypeAndMut { ty: expr_ty, .. }) = *self.expr_ty.kind() - && fcx - .can_coerce( - Ty::new_ref(fcx.tcx, - fcx.tcx.lifetimes.re_erased, - TypeAndMut { ty: expr_ty, mutbl }, - ), - self.cast_ty, - ) + && fcx.can_coerce( + Ty::new_ref( + fcx.tcx, + fcx.tcx.lifetimes.re_erased, + TypeAndMut { ty: expr_ty, mutbl }, + ), + self.cast_ty, + ) { sugg = Some((format!("&{}*", mutbl.prefix_str()), cast_ty == expr_ty)); } else if let ty::Ref(expr_reg, expr_ty, expr_mutbl) = *self.expr_ty.kind() && expr_mutbl == Mutability::Not && mutbl == Mutability::Mut - && fcx - .can_coerce( - Ty::new_ref(fcx.tcx, - expr_reg, - TypeAndMut { ty: expr_ty, mutbl: Mutability::Mut }, - ), - self.cast_ty, - ) + && fcx.can_coerce( + Ty::new_ref( + fcx.tcx, + expr_reg, + TypeAndMut { ty: expr_ty, mutbl: Mutability::Mut }, + ), + self.cast_ty, + ) { sugg_mutref = true; } if !sugg_mutref && sugg == None - && fcx - .can_coerce( - Ty::new_ref(fcx.tcx,reg, TypeAndMut { ty: self.expr_ty, mutbl }), - self.cast_ty, - ) + && fcx.can_coerce( + Ty::new_ref(fcx.tcx, reg, TypeAndMut { ty: self.expr_ty, mutbl }), + self.cast_ty, + ) { sugg = Some((format!("&{}", mutbl.prefix_str()), false)); } } else if let ty::RawPtr(TypeAndMut { mutbl, .. }) = *self.cast_ty.kind() - && fcx - .can_coerce( - Ty::new_ref(fcx.tcx, - fcx.tcx.lifetimes.re_erased, - TypeAndMut { ty: self.expr_ty, mutbl }, - ), - self.cast_ty, - ) + && fcx.can_coerce( + Ty::new_ref( + fcx.tcx, + fcx.tcx.lifetimes.re_erased, + TypeAndMut { ty: self.expr_ty, mutbl }, + ), + self.cast_ty, + ) { sugg = Some((format!("&{}", mutbl.prefix_str()), false)); } @@ -942,10 +941,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { lint::builtin::CENUM_IMPL_DROP_CAST, self.expr.hir_id, self.span, - errors::CastEnumDrop { - expr_ty, - cast_ty, - } + errors::CastEnumDrop { expr_ty, cast_ty }, ); } } diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index c8ffd7d1506..26ea7b0fdb9 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -55,18 +55,22 @@ pub(super) fn check_fn<'a, 'tcx>( fn_maybe_err(tcx, span, fn_sig.abi); - if let Some(kind) = body.generator_kind && can_be_generator.is_some() { + if let Some(kind) = body.generator_kind + && can_be_generator.is_some() + { let yield_ty = if kind == hir::GeneratorKind::Gen { - let yield_ty = fcx - .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }); + let yield_ty = fcx.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::TypeInference, + span, + }); fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType); yield_ty } else { - Ty::new_unit(tcx,) + Ty::new_unit(tcx) }; // Resume type defaults to `()` if the generator has no argument. - let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| Ty::new_unit(tcx,)); + let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| Ty::new_unit(tcx)); fcx.resume_yield_tys = Some((resume_ty, yield_ty)); } @@ -173,7 +177,9 @@ pub(super) fn check_fn<'a, 'tcx>( check_panic_info_fn(tcx, panic_impl_did.expect_local(), fn_sig); } - if let Some(lang_start_defid) = tcx.lang_items().start_fn() && lang_start_defid == fn_def_id.to_def_id() { + if let Some(lang_start_defid) = tcx.lang_items().start_fn() + && lang_start_defid == fn_def_id.to_def_id() + { check_lang_start_fn(tcx, fn_sig, fn_def_id); } diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index e506c150f7d..06542b0cc24 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -228,7 +228,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Given a Projection predicate, we can potentially infer // the complete signature. if expected_sig.is_none() - && let ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj_predicate)) = bound_predicate.skip_binder() + && let ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj_predicate)) = + bound_predicate.skip_binder() { let inferred_sig = self.normalize( span, diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index fca675ea9d8..6c03bc3b57a 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1619,8 +1619,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { unsized_return = self.is_return_ty_definitely_unsized(fcx); } if let Some(expression) = expression - && let hir::ExprKind::Loop(loop_blk, ..) = expression.kind { - intravisit::walk_block(& mut visitor, loop_blk); + && let hir::ExprKind::Loop(loop_blk, ..) = expression.kind + { + intravisit::walk_block(&mut visitor, loop_blk); } } ObligationCauseCode::ReturnValue(id) => { @@ -1661,7 +1662,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { ); } - if visitor.ret_exprs.len() > 0 && let Some(expr) = expression { + if visitor.ret_exprs.len() > 0 + && let Some(expr) = expression + { self.note_unreachable_loop_return(&mut err, &expr, &visitor.ret_exprs); } @@ -1723,7 +1726,10 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { let parent_id = fcx.tcx.hir().parent_id(id); let parent = fcx.tcx.hir().get(parent_id); if let Some(expr) = expression - && let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { body, .. }), .. }) = parent + && let hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Closure(&hir::Closure { body, .. }), + .. + }) = parent && !matches!(fcx.tcx.hir().body(body).value.kind, hir::ExprKind::Block(..)) { fcx.suggest_missing_semicolon(&mut err, expr, expected, true); @@ -1798,12 +1804,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { && let Some(fn_sig) = fcx.body_fn_sig() && fn_sig.output().is_ty_var() { - err.span_note( - sp, - format!( - "return type inferred to be `{expected}` here" - ), - ); + err.span_note(sp, format!("return type inferred to be `{expected}` here")); } err diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 5c3f2b85966..65ec2f232ae 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -151,7 +151,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let [segment] = path.segments && segment.ident.name.as_str() == name && let Res::Local(hir_id) = path.res - && let Some((_, hir::Node::Expr(match_expr))) = self.tcx.hir().parent_iter(hir_id).nth(2) + && let Some((_, hir::Node::Expr(match_expr))) = + self.tcx.hir().parent_iter(hir_id).nth(2) && let hir::ExprKind::Match(scrutinee, _, _) = match_expr.kind && let hir::ExprKind::Tup(exprs) = scrutinee.kind && let hir::ExprKind::AddrOf(_, _, macro_arg) = exprs[idx].kind @@ -450,20 +451,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If our binding became incompatible while it was a receiver // to a method call, we may be able to make a better guess to // the source of a type mismatch. - let Some(rcvr_ty) = self.node_ty_opt(rcvr.hir_id) else { continue; }; + let Some(rcvr_ty) = self.node_ty_opt(rcvr.hir_id) else { + continue; + }; let rcvr_ty = rcvr_ty.fold_with(&mut fudger); - let Ok(method) = - self.lookup_method_for_diagnostic(rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr) - else { + let Ok(method) = self.lookup_method_for_diagnostic( + rcvr_ty, + segment, + DUMMY_SP, + parent_expr, + rcvr, + ) else { continue; }; let ideal_rcvr_ty = rcvr_ty.fold_with(&mut fudger); let ideal_method = self - .lookup_method_for_diagnostic(ideal_rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr) + .lookup_method_for_diagnostic( + ideal_rcvr_ty, + segment, + DUMMY_SP, + parent_expr, + rcvr, + ) .ok() .and_then(|method| { - let _ = self.at(&ObligationCause::dummy(), self.param_env) + let _ = self + .at(&ObligationCause::dummy(), self.param_env) .eq(DefineOpaqueTypes::No, ideal_rcvr_ty, expected_ty) .ok()?; Some(method) @@ -474,15 +488,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (idx, (expected_arg_ty, arg_expr)) in std::iter::zip(&method.sig.inputs()[1..], args).enumerate() { - let Some(arg_ty) = self.node_ty_opt(arg_expr.hir_id) else { continue; }; + let Some(arg_ty) = self.node_ty_opt(arg_expr.hir_id) else { + continue; + }; let arg_ty = arg_ty.fold_with(&mut fudger); - let _ = self.coerce( - arg_expr, - arg_ty, - *expected_arg_ty, - AllowTwoPhase::No, - None, - ); + let _ = + self.coerce(arg_expr, arg_ty, *expected_arg_ty, AllowTwoPhase::No, None); self.select_obligations_where_possible(|errs| { // Yeet the errors, we're already reporting errors. errs.clear(); @@ -648,10 +659,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None => self.tcx.types.unit, }; if self.can_eq(self.param_env, ty, expected) { - err.span_label( - ex.span, - "expected because of this `break`", - ); + err.span_label(ex.span, "expected because of this `break`"); exit = true; } } @@ -1410,10 +1418,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let bind = self.tcx.hir().find(*bind_hir_id); let parent = self.tcx.hir().find(self.tcx.hir().parent_id(*bind_hir_id)); - if let Some(hir::Node::Pat(hir::Pat { kind: hir::PatKind::Binding(_, _hir_id, _, _), .. })) = bind && - let Some(hir::Node::Pat(hir::Pat { default_binding_modes: false, .. })) = parent { - return true; - } + if let Some(hir::Node::Pat(hir::Pat { + kind: hir::PatKind::Binding(_, _hir_id, _, _), + .. + })) = bind + && let Some(hir::Node::Pat(hir::Pat { default_binding_modes: false, .. })) = parent + { + return true; + } } return false; } @@ -1507,10 +1519,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // ``` let ref_ty = match mutability { hir::Mutability::Mut => { - Ty::new_mut_ref(self.tcx,self.tcx.lifetimes.re_static, checked_ty) + Ty::new_mut_ref(self.tcx, self.tcx.lifetimes.re_static, checked_ty) } hir::Mutability::Not => { - Ty::new_imm_ref(self.tcx,self.tcx.lifetimes.re_static, checked_ty) + Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_static, checked_ty) } }; if self.can_coerce(ref_ty, expected) { @@ -1566,7 +1578,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { )); } - let prefix = match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) { + let prefix = match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) + { Some(ident) => format!("{ident}: "), None => String::new(), }; @@ -1611,8 +1624,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let make_sugg = |start: Span, end: BytePos| { // skip `(` for tuples such as `(c) = (&123)`. // make sure we won't suggest like `(c) = 123)` which is incorrect. - let sp = sm.span_extend_while(start.shrink_to_lo(), |c| c == '(' || c.is_whitespace()) - .map_or(start, |s| s.shrink_to_hi()); + let sp = sm + .span_extend_while(start.shrink_to_lo(), |c| c == '(' || c.is_whitespace()) + .map_or(start, |s| s.shrink_to_hi()); Some(( vec![(sp.with_hi(end), String::new())], "consider removing the borrow".to_string(), @@ -1635,12 +1649,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .find(|&s| sp.contains(s)) && sm.is_span_accessible(call_span) { - return make_sugg(sp, call_span.lo()) + return make_sugg(sp, call_span.lo()); } return None; } if sp.contains(expr.span) && sm.is_span_accessible(expr.span) { - return make_sugg(sp, expr.span.lo()) + return make_sugg(sp, expr.span.lo()); } } ( @@ -1760,10 +1774,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) }; - let prefix = match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) { - Some(ident) => format!("{ident}: "), - None => String::new(), - }; + let prefix = + match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) { + Some(ident) => format!("{ident}: "), + None => String::new(), + }; let (span, suggestion) = if self.is_else_if_block(expr) { // Don't suggest nonsense like `else *if` diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index a00f3c5d0d8..96df0346ac6 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -717,7 +717,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // ... except when we try to 'break rust;'. // ICE this expression in particular (see #43162). if let ExprKind::Path(QPath::Resolved(_, path)) = e.kind { - if let [segment] = path.segments && segment.ident.name == sym::rust { + if let [segment] = path.segments + && segment.ident.name == sym::rust + { fatally_break_rust(self.tcx); } } @@ -826,7 +828,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let ExprKind::Block(body, _) = return_expr.kind && let Some(last_expr) = body.expr { - span = last_expr.span; + span = last_expr.span; } ret_coercion.borrow_mut().coerce( self, @@ -841,7 +843,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Point any obligations that were registered due to opaque type // inference at the return expression. self.select_obligations_where_possible(|errors| { - self.point_at_return_for_opaque_ty_error(errors, span, return_expr_ty, return_expr.span); + self.point_at_return_for_opaque_ty_error( + errors, + span, + return_expr_ty, + return_expr.span, + ); }); } } @@ -1402,7 +1409,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let hir::ArrayLen::Body(hir::AnonConst { hir_id, .. }) = length && let Some(span) = self.tcx.hir().opt_span(hir_id) { - match self.tcx.sess.diagnostic().steal_diagnostic(span, StashKey::UnderscoreForArrayLengths) { + match self + .tcx + .sess + .diagnostic() + .steal_diagnostic(span, StashKey::UnderscoreForArrayLengths) + { Some(mut err) => { err.span_suggestion( span, @@ -1412,7 +1424,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); err.emit(); } - None => () + None => (), } } } @@ -1931,11 +1943,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err: &mut Diagnostic, ) { // I don't use 'is_range_literal' because only double-sided, half-open ranges count. - if let ExprKind::Struct( - QPath::LangItem(LangItem::Range, ..), - [range_start, range_end], - _, - ) = last_expr_field.expr.kind + if let ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), [range_start, range_end], _) = + last_expr_field.expr.kind && let variant_field = variant.fields.iter().find(|field| field.ident(self.tcx) == last_expr_field.ident) && let range_def_id = self.tcx.lang_items().range_struct() @@ -1970,13 +1979,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .sess .source_map() .span_extend_while(range_start.span, |c| c.is_whitespace()) - .unwrap_or(range_start.span).shrink_to_hi().to(range_end.span); + .unwrap_or(range_start.span) + .shrink_to_hi() + .to(range_end.span); - err.subdiagnostic(TypeMismatchFruTypo { - expr_span: range_start.span, - fru_span, - expr, - }); + err.subdiagnostic(TypeMismatchFruTypo { expr_span: range_start.span, fru_span, expr }); } } @@ -2293,7 +2300,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some('e') | Some('E') => { chars.next(); if let Some(c) = chars.peek() - && !c.is_numeric() && *c != '-' && *c != '+' + && !c.is_numeric() + && *c != '-' + && *c != '+' { return false; } @@ -2421,7 +2430,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } self.suggest_fn_call(&mut err, base, base_ty, |output_ty| { - if let ty::Adt(def, _) = output_ty.kind() && !def.is_enum() { + if let ty::Adt(def, _) = output_ty.kind() + && !def.is_enum() + { def.non_enum_variant().fields.iter().any(|field| { field.ident(self.tcx) == ident && field.vis.is_accessible_from(expr.hir_id.owner.def_id, self.tcx) @@ -2842,9 +2853,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // fixed expression: if let ExprKind::Lit(ref lit) = idx.kind && let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node - && i < types.len().try_into().expect("expected tuple index to be < usize length") + && i < types + .len() + .try_into() + .expect("expected tuple index to be < usize length") { - err.span_suggestion( brackets_span, "to access tuple elements, use", @@ -2853,7 +2866,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); needs_note = false; } else if let ExprKind::Path(..) = idx.peel_borrows().kind { - err.span_label(idx.span, "cannot access tuple elements at a variable index"); + err.span_label( + idx.span, + "cannot access tuple elements at a variable index", + ); } if needs_note { err.help( diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 952b90d6a35..38b780367e6 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -142,7 +142,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // type, `?T` is not considered unsolved, but `?I` is. The // same is true for float variables.) let fallback = match ty.kind() { - _ if let Some(e) = self.tainted_by_errors() => Ty::new_error(self.tcx,e), + _ if let Some(e) = self.tainted_by_errors() => Ty::new_error(self.tcx, e), ty::Infer(ty::IntVar(_)) => self.tcx.types.i32, ty::Infer(ty::FloatVar(_)) => self.tcx.types.f64, _ => match diverging_fallback.get(&ty) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 5dae74a1f9b..6e0e02b7814 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -445,7 +445,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> { match self.typeck_results.borrow().node_types().get(id) { Some(&t) => t, - None if let Some(e) = self.tainted_by_errors() => Ty::new_error(self.tcx,e), + None if let Some(e) = self.tainted_by_errors() => Ty::new_error(self.tcx, e), None => { bug!( "no type for node {} in fcx {}", @@ -459,7 +459,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn node_ty_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> { match self.typeck_results.borrow().node_types().get(id) { Some(&t) => Some(t), - None if let Some(e) = self.tainted_by_errors() => Some(Ty::new_error(self.tcx,e)), + None if let Some(e) = self.tainted_by_errors() => Some(Ty::new_error(self.tcx, e)), None => None, } } @@ -564,7 +564,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !errors.is_empty() { self.adjust_fulfillment_errors_for_expr_obligation(&mut errors); + let errors_causecode = errors + .iter() + .map(|e| (e.obligation.cause.span, e.root_obligation.cause.code().clone())) + .collect::<Vec<_>>(); self.err_ctxt().report_fulfillment_errors(errors); + self.collect_unused_stmts_for_coerce_return_ty(errors_causecode); } } @@ -713,7 +718,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::GenericArgKind::Type(ty) = ty.unpack() && let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *ty.kind() && let Some(def_id) = def_id.as_local() - && self.opaque_type_origin(def_id).is_some() { + && self.opaque_type_origin(def_id).is_some() + { return None; } } @@ -833,7 +839,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .resolve_fully_qualified_call(span, item_name, ty.normalized, qself.span, hir_id) .and_then(|r| { // lint bare trait if the method is found in the trait - if span.edition().at_least_rust_2021() && let Some(mut diag) = self.tcx.sess.diagnostic().steal_diagnostic(qself.span, StashKey::TraitMissingMethod) { + if span.edition().at_least_rust_2021() + && let Some(mut diag) = self + .tcx + .sess + .diagnostic() + .steal_diagnostic(qself.span, StashKey::TraitMissingMethod) + { diag.emit(); } Ok(r) @@ -863,7 +875,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // emit or cancel the diagnostic for bare traits - if span.edition().at_least_rust_2021() && let Some(mut diag) = self.tcx.sess.diagnostic().steal_diagnostic(qself.span, StashKey::TraitMissingMethod) { + if span.edition().at_least_rust_2021() + && let Some(mut diag) = self + .tcx + .sess + .diagnostic() + .steal_diagnostic(qself.span, StashKey::TraitMissingMethod) + { if trait_missing_method { // cancel the diag for bare traits when meeting `MyTrait::missing_method` diag.cancel(); @@ -949,12 +967,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { kind: hir::ItemKind::Fn(ref sig, ..), owner_id, .. - })) = self.tcx.hir().find_parent(hir_id) => Some(( - hir::HirId::make_owner(owner_id.def_id), - &sig.decl, - ident, - ident.name != sym::main, - )), + })) = self.tcx.hir().find_parent(hir_id) => + { + Some(( + hir::HirId::make_owner(owner_id.def_id), + &sig.decl, + ident, + ident.name != sym::main, + )) + } _ => None, } } @@ -1077,11 +1098,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut user_self_ty = None; let mut is_alias_variant_ctor = false; match res { - Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) - if let Some(self_ty) = self_ty => - { + Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) if let Some(self_ty) = self_ty => { let adt_def = self_ty.normalized.ty_adt_def().unwrap(); - user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did(), self_ty: self_ty.raw }); + user_self_ty = + Some(UserSelfTy { impl_def_id: adt_def.did(), self_ty: self_ty.raw }); is_alias_variant_ctor = true; } Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => { @@ -1090,9 +1110,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let container_id = assoc_item.container_id(tcx); debug!(?def_id, ?container, ?container_id); match container { - ty::TraitContainer => { - callee::check_legal_trait_for_method_call(tcx, span, None, span, container_id) - } + ty::TraitContainer => callee::check_legal_trait_for_method_call( + tcx, + span, + None, + span, + container_id, + ), ty::ImplContainer => { if segments.len() == 1 { // `<T>::assoc` will end up here, and so @@ -1478,12 +1502,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(normalized_ty) => normalized_ty, Err(errors) => { let guar = self.err_ctxt().report_fulfillment_errors(errors); - return Ty::new_error(self.tcx,guar); + return Ty::new_error(self.tcx, guar); } } } else { ty - } + } } /// Resolves `ty` by a single level if `ty` is a type variable. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 43d4496dd48..522d0e2616b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -129,21 +129,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } - for param in - [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] + for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] .into_iter() .flatten() { if self.blame_specific_arg_if_possible( - error, - def_id, - param, - *call_hir_id, - callee.span, - None, - args, - ) - { + error, + def_id, + param, + *call_hir_id, + callee.span, + None, + args, + ) { return true; } } @@ -346,8 +344,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let TypeVariableOriginKind::TypeParameterDefinition(_, def_id) = origin.kind && let generics = self.0.tcx.generics_of(self.1) && let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id) - && let Some(subst) = ty::GenericArgs::identity_for_item(self.0.tcx, self.1) - .get(index as usize) + && let Some(subst) = + ty::GenericArgs::identity_for_item(self.0.tcx, self.1).get(index as usize) { ControlFlow::Break(*subst) } else { @@ -364,11 +362,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, ) -> bool { if let traits::FulfillmentErrorCode::CodeSelectionError( - traits::SelectionError::OutputTypeParameterMismatch(box traits::SelectionOutputTypeParameterMismatch{ - expected_trait_ref, .. - }), + traits::SelectionError::OutputTypeParameterMismatch( + box traits::SelectionOutputTypeParameterMismatch { expected_trait_ref, .. }, + ), ) = error.code - && let ty::Closure(def_id, _) | ty::Generator(def_id, ..) = expected_trait_ref.skip_binder().self_ty().kind() + && let ty::Closure(def_id, _) | ty::Generator(def_id, ..) = + expected_trait_ref.skip_binder().self_ty().kind() && span.overlaps(self.tcx.def_span(*def_id)) { true @@ -446,10 +445,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .collect(); // If there's one field that references the given generic, great! if let [(idx, _)] = args_referencing_param.as_slice() - && let Some(arg) = receiver - .map_or(args.get(*idx), |rcvr| if *idx == 0 { Some(rcvr) } else { args.get(*idx - 1) }) { - - error.obligation.cause.span = arg.span.find_ancestor_in_same_ctxt(error.obligation.cause.span).unwrap_or(arg.span); + && let Some(arg) = receiver.map_or(args.get(*idx), |rcvr| { + if *idx == 0 { Some(rcvr) } else { args.get(*idx - 1) } + }) + { + error.obligation.cause.span = arg + .span + .find_ancestor_in_same_ctxt(error.obligation.cause.span) + .unwrap_or(arg.span); if let hir::Node::Expr(arg_expr) = self.tcx.hir().get(arg.hir_id) { // This is more specific than pointing at the entire argument. @@ -934,16 +937,16 @@ fn find_param_in_ty<'tcx>( return true; } if let ty::GenericArgKind::Type(ty) = arg.unpack() - && let ty::Alias(ty::Projection | ty::Inherent, ..) = ty.kind() - { - // This logic may seem a bit strange, but typically when - // we have a projection type in a function signature, the - // argument that's being passed into that signature is - // not actually constraining that projection's args in - // a meaningful way. So we skip it, and see improvements - // in some UI tests. - walk.skip_current_subtree(); - } + && let ty::Alias(ty::Projection | ty::Inherent, ..) = ty.kind() + { + // This logic may seem a bit strange, but typically when + // we have a projection type in a function signature, the + // argument that's being passed into that signature is + // not actually constraining that projection's args in + // a meaningful way. So we skip it, and see improvements + // in some UI tests. + walk.skip_current_subtree(); + } } false } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index c762e684480..9f1800b45c3 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -11,7 +11,7 @@ use crate::{ use rustc_ast as ast; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{ - pluralize, Applicability, Diagnostic, DiagnosticId, ErrorGuaranteed, MultiSpan, + pluralize, Applicability, Diagnostic, DiagnosticId, ErrorGuaranteed, MultiSpan, StashKey, }; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; @@ -27,6 +27,7 @@ use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::TypeTrace; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; +use rustc_middle::traits::ObligationCauseCode::ExprBindingObligation; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt}; @@ -652,7 +653,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && provided_arg_tys.len() == formal_and_expected_inputs.len() - 1 + tys.len() { // Wrap up the N provided arguments starting at this position in a tuple. - let provided_as_tuple = Ty::new_tup_from_iter(tcx, + let provided_as_tuple = Ty::new_tup_from_iter( + tcx, provided_arg_tys.iter().map(|(ty, _)| *ty).skip(mismatch_idx).take(tys.len()), ); @@ -884,8 +886,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && self.tcx.def_kind(fn_def_id).is_fn_like() && let self_implicit = matches!(call_expr.kind, hir::ExprKind::MethodCall(..)) as usize - && let Some(arg) = self.tcx.fn_arg_names(fn_def_id) - .get(expected_idx.as_usize() + self_implicit) + && let Some(arg) = + self.tcx.fn_arg_names(fn_def_id).get(expected_idx.as_usize() + self_implicit) && arg.name != kw::SelfLower { format!("/* {} */", arg.name) @@ -946,9 +948,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && error_span.can_be_used_for_suggestions() { if arg_idx.index() > 0 - && let Some((_, prev)) = provided_arg_tys - .get(ProvidedIdx::from_usize(arg_idx.index() - 1) - ) { + && let Some((_, prev)) = + provided_arg_tys.get(ProvidedIdx::from_usize(arg_idx.index() - 1)) + { // Include previous comma span = prev.shrink_to_hi().to(span); } @@ -1291,7 +1293,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err: &mut rustc_errors::DiagnosticBuilder<'tcx, ErrorGuaranteed>, ) { if let ty::RawPtr(ty::TypeAndMut { mutbl: hir::Mutability::Mut, .. }) = expected_ty.kind() - && let ty::RawPtr(ty::TypeAndMut { mutbl: hir::Mutability::Not, .. }) = provided_ty.kind() + && let ty::RawPtr(ty::TypeAndMut { mutbl: hir::Mutability::Not, .. }) = + provided_ty.kind() && let hir::ExprKind::Call(callee, _) = arg.kind && let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = callee.kind && let Res::Def(_, def_id) = path.res @@ -1299,9 +1302,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { // The user provided `ptr::null()`, but the function expects // `ptr::null_mut()`. - err.subdiagnostic(SuggestPtrNullMut { - span: arg.span - }); + err.subdiagnostic(SuggestPtrNullMut { span: arg.span }); } } @@ -1375,7 +1376,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => bug!("unexpected type: {:?}", ty.normalized), }, - Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _) + Res::Def( + DefKind::Struct | DefKind::Union | DefKind::TyAlias { .. } | DefKind::AssocTy, + _, + ) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => match ty.normalized.ty_adt_def() { Some(adt) if !adt.is_enum() => { @@ -1845,6 +1849,55 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + pub(super) fn collect_unused_stmts_for_coerce_return_ty( + &self, + errors_causecode: Vec<(Span, ObligationCauseCode<'tcx>)>, + ) { + for (span, code) in errors_causecode { + let Some(mut diag) = + self.tcx.sess.diagnostic().steal_diagnostic(span, StashKey::MaybeForgetReturn) + else { + continue; + }; + + if let Some(fn_sig) = self.body_fn_sig() + && let ExprBindingObligation(_, _, hir_id, ..) = code + && !fn_sig.output().is_unit() + { + let mut block_num = 0; + let mut found_semi = false; + for (_, node) in self.tcx.hir().parent_iter(hir_id) { + match node { + hir::Node::Stmt(stmt) => if let hir::StmtKind::Semi(ref expr) = stmt.kind { + let expr_ty = self.typeck_results.borrow().expr_ty(expr); + let return_ty = fn_sig.output(); + if !matches!(expr.kind, hir::ExprKind::Ret(..)) && + self.can_coerce(expr_ty, return_ty) { + found_semi = true; + } + }, + hir::Node::Block(_block) => if found_semi { + block_num += 1; + } + hir::Node::Item(item) => if let hir::ItemKind::Fn(..) = item.kind { + break; + } + _ => {} + } + } + if block_num > 1 && found_semi { + diag.span_suggestion_verbose( + span.shrink_to_lo(), + "you might have meant to return this to infer its type parameters", + "return ", + Applicability::MaybeIncorrect, + ); + } + } + diag.emit(); + } + } + /// Given a vector of fulfillment errors, try to adjust the spans of the /// errors to more accurately point at the cause of the failure. /// @@ -1928,8 +1981,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let callee_ty = callee_ty.peel_refs(); match *callee_ty.kind() { ty::Param(param) => { - let param = - self.tcx.generics_of(self.body_id).type_param(¶m, self.tcx); + let param = self.tcx.generics_of(self.body_id).type_param(¶m, self.tcx); if param.kind.is_synthetic() { // if it's `impl Fn() -> ..` then just fall down to the def-id based logic def_id = param.def_id; @@ -1943,8 +1995,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // FIXME(compiler-errors): This could be problematic if something has two // fn-like predicates with different args, but callable types really never // do that, so it's OK. - for (predicate, span) in instantiated - { + for (predicate, span) in instantiated { if let ty::ClauseKind::Trait(pred) = predicate.kind().skip_binder() && pred.self_ty().peel_refs() == callee_ty && self.tcx.is_fn_trait(pred.def_id()) @@ -1963,7 +2014,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => { // Look for a user-provided impl of a `Fn` trait, and point to it. let new_def_id = self.probe(|_| { - let trait_ref = ty::TraitRef::new(self.tcx, + let trait_ref = ty::TraitRef::new( + self.tcx, call_kind.to_def_id(self.tcx), [ callee_ty, @@ -1995,7 +2047,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - if let Some(def_span) = self.tcx.def_ident_span(def_id) && !def_span.is_dummy() { + if let Some(def_span) = self.tcx.def_ident_span(def_id) + && !def_span.is_dummy() + { let mut spans: MultiSpan = def_span.into(); let params = self @@ -2025,7 +2079,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Try to find earlier invocations of this closure to find if the type mismatch // is because of inference. If we find one, point at them. let mut call_finder = FindClosureArg { tcx: self.tcx, calls: vec![] }; - let node = self.tcx + let node = self + .tcx .opt_local_def_id_to_hir_id(self.tcx.hir().get_parent_item(call_expr.hir_id)) .and_then(|hir_id| self.tcx.hir().find(hir_id)); match node { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 9999fa2e59c..14d69141343 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -254,22 +254,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'tcx>, expected: Ty<'tcx>, ) -> bool { - if let hir::ExprKind::MethodCall(hir::PathSegment { ident: method, .. }, recv_expr, &[], _) = expr.kind && - let Some(recv_ty) = self.typeck_results.borrow().expr_ty_opt(recv_expr) && - self.can_coerce(recv_ty, expected) { - let span = if let Some(recv_span) = recv_expr.span.find_ancestor_inside(expr.span) { - expr.span.with_lo(recv_span.hi()) - } else { - expr.span.with_lo(method.span.lo() - rustc_span::BytePos(1)) - }; - err.span_suggestion_verbose( - span, - "try removing the method call", - "", - Applicability::MachineApplicable, - ); - return true; - } + if let hir::ExprKind::MethodCall(hir::PathSegment { ident: method, .. }, recv_expr, &[], _) = + expr.kind + && let Some(recv_ty) = self.typeck_results.borrow().expr_ty_opt(recv_expr) + && self.can_coerce(recv_ty, expected) + { + let span = if let Some(recv_span) = recv_expr.span.find_ancestor_inside(expr.span) { + expr.span.with_lo(recv_span.hi()) + } else { + expr.span.with_lo(method.span.lo() - rustc_span::BytePos(1)) + }; + err.span_suggestion_verbose( + span, + "try removing the method call", + "", + Applicability::MachineApplicable, + ); + return true; + } false } @@ -347,10 +349,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let name = self.tcx.item_name(def_id); let kind = self.tcx.def_kind(def_id); if let DefKind::Ctor(of, CtorKind::Fn) = kind { - err.span_label(sp, format!("`{name}` defines {} constructor here, which should be called", match of { - CtorOf::Struct => "a struct", - CtorOf::Variant => "an enum variant", - })); + err.span_label( + sp, + format!( + "`{name}` defines {} constructor here, which should be called", + match of { + CtorOf::Struct => "a struct", + CtorOf::Variant => "an enum variant", + } + ), + ); } else { let descr = self.tcx.def_kind_descr(kind, def_id); err.span_label(sp, format!("{descr} `{name}` defined here")); @@ -370,25 +378,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(method_ident) = receiver_method_ident && method_ident.name == conversion_method.name { - return None // do not suggest code that is already there (#53348) + return None; // do not suggest code that is already there (#53348) } let method_call_list = [sym::to_vec, sym::to_string]; let mut sugg = if let ExprKind::MethodCall(receiver_method, ..) = expr.kind && receiver_method.ident.name == sym::clone && method_call_list.contains(&conversion_method.name) - // If receiver is `.clone()` and found type has one of those methods, - // we guess that the user wants to convert from a slice type (`&[]` or `&str`) - // to an owned type (`Vec` or `String`). These conversions clone internally, - // so we remove the user's `clone` call. - { - vec![( - receiver_method.ident.span, - conversion_method.name.to_string() - )] - } else if expr.precedence().order() - < ExprPrecedence::MethodCall.order() + // If receiver is `.clone()` and found type has one of those methods, + // we guess that the user wants to convert from a slice type (`&[]` or `&str`) + // to an owned type (`Vec` or `String`). These conversions clone internally, + // so we remove the user's `clone` call. { + vec![(receiver_method.ident.span, conversion_method.name.to_string())] + } else if expr.precedence().order() < ExprPrecedence::MethodCall.order() { vec![ (expr.span.shrink_to_lo(), "(".to_string()), (expr.span.shrink_to_hi(), format!(").{}()", conversion_method.name)), @@ -431,7 +434,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Given `Result<_, E>`, check our expected ty is `Result<_, &E>` for // `as_ref` and `as_deref` compatibility. let error_tys_equate_as_ref = error_tys.map_or(true, |(found, expected)| { - self.can_eq(self.param_env, Ty::new_imm_ref(self.tcx,self.tcx.lifetimes.re_erased, found), expected) + self.can_eq( + self.param_env, + Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, found), + expected, + ) }); // FIXME: This could/should be extended to suggest `as_mut` and `as_deref_mut`, // but those checks need to be a bit more delicate and the benefit is diminishing. @@ -604,8 +611,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } let box_found = Ty::new_box(self.tcx, found); - let pin_box_found = Ty::new_lang_item(self.tcx, box_found, LangItem::Pin).unwrap(); - let pin_found = Ty::new_lang_item(self.tcx, found, LangItem::Pin).unwrap(); + let Some(pin_box_found) = Ty::new_lang_item(self.tcx, box_found, LangItem::Pin) else { + return false; + }; + let Some(pin_found) = Ty::new_lang_item(self.tcx, found, LangItem::Pin) else { + return false; + }; match expected.kind() { ty::Adt(def, _) if Some(def.did()) == pin_did => { if self.can_coerce(pin_box_found, expected) { @@ -766,41 +777,54 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } &hir::FnRetTy::DefaultReturn(span) if expected.is_unit() => { if let Some(found) = found.make_suggestable(self.tcx, false) { - err.subdiagnostic(errors::AddReturnTypeSuggestion::Add { span, found: found.to_string() }); + err.subdiagnostic(errors::AddReturnTypeSuggestion::Add { + span, + found: found.to_string(), + }); return true; } else if let ty::Closure(_, args) = found.kind() // FIXME(compiler-errors): Get better at printing binders... && let closure = args.as_closure() && closure.sig().is_suggestable(self.tcx, false) { - err.subdiagnostic(errors::AddReturnTypeSuggestion::Add { span, found: closure.print_as_impl_trait().to_string() }); + err.subdiagnostic(errors::AddReturnTypeSuggestion::Add { + span, + found: closure.print_as_impl_trait().to_string(), + }); return true; } else { // FIXME: if `found` could be `impl Iterator` we should suggest that. err.subdiagnostic(errors::AddReturnTypeSuggestion::MissingHere { span }); - return true + return true; } } hir::FnRetTy::Return(hir_ty) => { if let hir::TyKind::OpaqueDef(item_id, ..) = hir_ty.kind && let hir::Node::Item(hir::Item { - kind: hir::ItemKind::OpaqueTy(op_ty), - .. + kind: hir::ItemKind::OpaqueTy(op_ty), .. }) = self.tcx.hir().get(item_id.hir_id()) - && let [hir::GenericBound::LangItemTrait( - hir::LangItem::Future, _, _, generic_args)] = op_ty.bounds + && let [ + hir::GenericBound::LangItemTrait(hir::LangItem::Future, _, _, generic_args), + ] = op_ty.bounds && let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args - && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } = ty_binding.kind + && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } = + ty_binding.kind { // Check if async function's return type was omitted. // Don't emit suggestions if the found type is `impl Future<...>`. debug!(?found); if found.is_suggestable(self.tcx, false) { if term.span.is_empty() { - err.subdiagnostic(errors::AddReturnTypeSuggestion::Add { span: term.span, found: found.to_string() }); + err.subdiagnostic(errors::AddReturnTypeSuggestion::Add { + span: term.span, + found: found.to_string(), + }); return true; } else { - err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { span: term.span, expected }); + err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { + span: term.span, + expected, + }); } } } else { @@ -815,7 +839,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = self.normalize(hir_ty.span, ty); let ty = self.tcx.erase_late_bound_regions(ty); if self.can_coerce(expected, ty) { - err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { span: hir_ty.span, expected }); + err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { + span: hir_ty.span, + expected, + }); self.try_suggest_return_impl_trait(err, expected, ty, fn_id); return true; } @@ -1073,13 +1100,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .type_implements_trait( clone_trait_def, [self.tcx.erase_regions(expected_ty)], - self.param_env + self.param_env, ) .must_apply_modulo_regions() - { + { let suggestion = match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) { Some(ident) => format!(": {ident}.clone()"), - None => ".clone()".to_string() + None => ".clone()".to_string(), }; diag.span_suggestion_verbose( @@ -1089,7 +1116,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); return true; - } + } false } @@ -1117,31 +1144,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expr_inner_ty = args.type_at(0); let expected_inner_ty = expected_args.type_at(0); if let &ty::Ref(_, ty, _mutability) = expr_inner_ty.kind() - && self.can_eq(self.param_env, ty, expected_inner_ty) + && self.can_eq(self.param_env, ty, expected_inner_ty) + { + let def_path = self.tcx.def_path_str(adt_def.did()); + let span = expr.span.shrink_to_hi(); + let subdiag = if self.type_is_copy_modulo_regions(self.param_env, ty) { + errors::OptionResultRefMismatch::Copied { span, def_path } + } else if let Some(clone_did) = self.tcx.lang_items().clone_trait() + && rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions( + self, + self.param_env, + ty, + clone_did, + ) { - let def_path = self.tcx.def_path_str(adt_def.did()); - let span = expr.span.shrink_to_hi(); - let subdiag = if self.type_is_copy_modulo_regions(self.param_env, ty) { - errors::OptionResultRefMismatch::Copied { - span, def_path - } - } else if let Some(clone_did) = self.tcx.lang_items().clone_trait() - && rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions( - self, - self.param_env, - ty, - clone_did, - ) - { - errors::OptionResultRefMismatch::Cloned { - span, def_path - } - } else { - return false; - }; - diag.subdiagnostic(subdiag); - return true; - } + errors::OptionResultRefMismatch::Cloned { span, def_path } + } else { + return false; + }; + diag.subdiagnostic(subdiag); + return true; + } } false @@ -1177,14 +1200,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx, self.misc(expr.span), self.param_env, - ty::TraitRef::new(self.tcx, - into_def_id, - [expr_ty, expected_ty] - ), + ty::TraitRef::new(self.tcx, into_def_id, [expr_ty, expected_ty]), )) { let mut span = expr.span; - while expr.span.eq_ctxt(span) && let Some(parent_callsite) = span.parent_callsite() + while expr.span.eq_ctxt(span) + && let Some(parent_callsite) = span.parent_callsite() { span = parent_callsite; } @@ -1192,7 +1213,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let sugg = if expr.precedence().order() >= PREC_POSTFIX { vec![(span.shrink_to_hi(), ".into()".to_owned())] } else { - vec![(span.shrink_to_lo(), "(".to_owned()), (span.shrink_to_hi(), ").into()".to_owned())] + vec![ + (span.shrink_to_lo(), "(".to_owned()), + (span.shrink_to_hi(), ").into()".to_owned()), + ] }; diag.multipart_suggestion( format!("call `Into::into` on this expression to convert `{expr_ty}` into `{expected_ty}`"), @@ -1234,9 +1258,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // since the user probably just misunderstood how `let else` // and `&&` work together. if let Some((_, hir::Node::Local(local))) = cond_parent - && let hir::PatKind::Path(qpath) | hir::PatKind::TupleStruct(qpath, _, _) = &local.pat.kind + && let hir::PatKind::Path(qpath) | hir::PatKind::TupleStruct(qpath, _, _) = + &local.pat.kind && let hir::QPath::Resolved(None, path) = qpath - && let Some(did) = path.res.opt_def_id() + && let Some(did) = path + .res + .opt_def_id() .and_then(|did| self.tcx.opt_parent(did)) .and_then(|did| self.tcx.opt_parent(did)) && self.tcx.is_diagnostic_item(sym::Option, did) @@ -1603,7 +1630,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .. }) => { let Some(hir::Node::Local(hir::Local { init: Some(init), .. })) = - self.tcx.hir().find(self.tcx.hir().parent_id(*pat_hir_id)) else { + self.tcx.hir().find(self.tcx.hir().parent_id(*pat_hir_id)) + else { return expr; }; @@ -1630,12 +1658,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // to worry if it's a call to a typed function or closure as this would ne handled // previously. hir::ExprKind::Call(Expr { kind: call_expr_kind, .. }, _) => { - if let hir::ExprKind::Path(hir::QPath::Resolved(None, call_expr_path)) = call_expr_kind - && let hir::Path { segments: [_], res: crate::Res::Local(binding), .. } = call_expr_path - && let Some(hir::Node::Pat(hir::Pat { hir_id, .. })) = self.tcx.hir().find(*binding) + if let hir::ExprKind::Path(hir::QPath::Resolved(None, call_expr_path)) = + call_expr_kind + && let hir::Path { segments: [_], res: crate::Res::Local(binding), .. } = + call_expr_path + && let Some(hir::Node::Pat(hir::Pat { hir_id, .. })) = + self.tcx.hir().find(*binding) && let Some(closure) = self.tcx.hir().find(self.tcx.hir().parent_id(*hir_id)) && let hir::Node::Local(hir::Local { init: Some(init), .. }) = closure - && let Expr { kind: hir::ExprKind::Closure(hir::Closure { body: body_id, .. }), ..} = init + && let Expr { + kind: hir::ExprKind::Closure(hir::Closure { body: body_id, .. }), + .. + } = init { let hir::Body { value: body_expr, .. } = self.tcx.hir().body(*body_id); self.note_type_is_not_clone_inner_expr(body_expr) diff --git a/compiler/rustc_hir_typeck/src/inherited.rs b/compiler/rustc_hir_typeck/src/inherited.rs index 7064484a40f..bee79242fd1 100644 --- a/compiler/rustc_hir_typeck/src/inherited.rs +++ b/compiler/rustc_hir_typeck/src/inherited.rs @@ -129,25 +129,29 @@ impl<'tcx> Inherited<'tcx> { let infer_var_info = &mut self.infer_var_info.borrow_mut(); // (*) binder skipped - if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(tpred)) = obligation.predicate.kind().skip_binder() - && let Some(ty) = self.shallow_resolve(tpred.self_ty()).ty_vid().map(|t| self.root_var(t)) + if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(tpred)) = + obligation.predicate.kind().skip_binder() + && let Some(ty) = + self.shallow_resolve(tpred.self_ty()).ty_vid().map(|t| self.root_var(t)) && self.tcx.lang_items().sized_trait().is_some_and(|st| st != tpred.trait_ref.def_id) { let new_self_ty = self.tcx.types.unit; // Then construct a new obligation with Self = () added // to the ParamEnv, and see if it holds. - let o = obligation.with(self.tcx, - obligation - .predicate - .kind() - .rebind( - // (*) binder moved here - ty::PredicateKind::Clause(ty::ClauseKind::Trait(tpred.with_self_ty(self.tcx, new_self_ty))) - ), + let o = obligation.with( + self.tcx, + obligation.predicate.kind().rebind( + // (*) binder moved here + ty::PredicateKind::Clause(ty::ClauseKind::Trait( + tpred.with_self_ty(self.tcx, new_self_ty), + )), + ), ); // Don't report overflow errors. Otherwise equivalent to may_hold. - if let Ok(result) = self.probe(|_| self.evaluate_obligation(&o)) && result.may_apply() { + if let Ok(result) = self.probe(|_| self.evaluate_obligation(&o)) + && result.may_apply() + { infer_var_info.entry(ty).or_default().self_in_trait = true; } } diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 4e65182f158..5d516eaf507 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -70,7 +70,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Special-case transmuting from `typeof(function)` and // `Option<typeof(function)>` to present a clearer error. let from = unpack_option_like(tcx, from); - if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) && size_to == Pointer(dl.instruction_address_space).size(&tcx) { + if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) + && size_to == Pointer(dl.instruction_address_space).size(&tcx) + { struct_span_err!(tcx.sess, span, E0591, "can't transmute zero-sized type") .note(format!("source type: {from}")) .note(format!("target type: {to}")) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 7164102a30e..74f469cb39c 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -667,8 +667,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // will still match the original object type, but it won't pollute our // type variables in any form, so just do that! let (QueryResponse { value: generalized_self_ty, .. }, _ignored_var_values) = - self.fcx - .instantiate_canonical_with_fresh_inference_vars(self.span, self_ty); + self.fcx.instantiate_canonical_with_fresh_inference_vars(self.span, self_ty); self.assemble_inherent_candidates_from_object(generalized_self_ty); self.assemble_inherent_impl_candidates_for_type(p.def_id()); @@ -1690,15 +1689,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } - debug!( - "comparing return_ty {:?} with xform ret ty {:?}", - return_ty, xform_ret_ty - ); + debug!("comparing return_ty {:?} with xform ret ty {:?}", return_ty, xform_ret_ty); if let ProbeResult::Match = result && self - .at(&ObligationCause::dummy(), self.param_env) - .sup(DefineOpaqueTypes::No, return_ty, xform_ret_ty) - .is_err() + .at(&ObligationCause::dummy(), self.param_env) + .sup(DefineOpaqueTypes::No, return_ty, xform_ret_ty) + .is_err() { result = ProbeResult::BadReturnType; } @@ -1959,15 +1955,18 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { if let Some(nested) = v.meta_item_list() { // #[doc(alias("foo", "bar"))] for n in nested { - if let Some(lit) = n.lit() && name.as_str() == lit.symbol.as_str() { + if let Some(lit) = n.lit() + && name.as_str() == lit.symbol.as_str() + { return true; } } } else if let Some(meta) = v.meta_item() && let Some(lit) = meta.name_value_literal() - && name.as_str() == lit.symbol.as_str() { - // #[doc(alias = "foo")] - return true; + && name.as_str() == lit.symbol.as_str() + { + // #[doc(alias = "foo")] + return true; } } } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index a4bbb16026a..8ea0280c5e9 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -305,8 +305,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mode = no_match_data.mode; let tcx = self.tcx; let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); - let ((mut ty_str, ty_file), short_ty_str) = if trait_missing_method - && let ty::Dynamic(predicates, _, _) = rcvr_ty.kind() { + let ((mut ty_str, ty_file), short_ty_str) = + if trait_missing_method && let ty::Dynamic(predicates, _, _) = rcvr_ty.kind() { ((predicates.to_string(), None), with_forced_trimmed_paths!(predicates.to_string())) } else { (tcx.short_ty_string(rcvr_ty), with_forced_trimmed_paths!(rcvr_ty.to_string())) @@ -377,9 +377,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tcx.is_diagnostic_item(sym::write_macro, def_id) || tcx.is_diagnostic_item(sym::writeln_macro, def_id) }) && item_name.name == Symbol::intern("write_fmt"); - let mut err = if is_write - && let Some(args) = args - { + let mut err = if is_write && let Some(args) = args { self.suggest_missing_writer(rcvr_ty, args) } else { tcx.sess.create_err(NoAssociatedItem { @@ -421,9 +419,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - if let Mode::MethodCall = mode && let SelfSource::MethodCall(cal) = source { + if let Mode::MethodCall = mode + && let SelfSource::MethodCall(cal) = source + { self.suggest_await_before_method( - &mut err, item_name, rcvr_ty, cal, span, expected.only_has_type(self), + &mut err, + item_name, + rcvr_ty, + cal, + span, + expected.only_has_type(self), ); } if let Some(span) = @@ -863,7 +868,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .filter_map(|(pred, parent_pred, _cause)| { let mut suggested = false; format_pred(*pred).map(|(p, self_ty)| { - if let Some(parent) = parent_pred && suggested_bounds.contains(parent) { + if let Some(parent) = parent_pred + && suggested_bounds.contains(parent) + { // We don't suggest `PartialEq` when we already suggest `Eq`. } else if !suggested_bounds.contains(pred) { if collect_type_param_suggestions(self_ty, *pred, &p) { @@ -967,7 +974,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { unsatisfied_bounds = true; } - } else if let ty::Adt(def, targs) = rcvr_ty.kind() && let Some(args) = args { + } else if let ty::Adt(def, targs) = rcvr_ty.kind() + && let Some(args) = args + { // This is useful for methods on arbitrary self types that might have a simple // mutability difference, like calling a method on `Pin<&mut Self>` that is on // `Pin<&Self>`. @@ -975,16 +984,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut item_segment = hir::PathSegment::invalid(); item_segment.ident = item_name; for t in [Ty::new_mut_ref, Ty::new_imm_ref, |_, _, t| t] { - let new_args = tcx.mk_args_from_iter( - targs - .iter() - .map(|arg| match arg.as_type() { - Some(ty) => ty::GenericArg::from( - t(tcx, tcx.lifetimes.re_erased, ty.peel_refs()), - ), - _ => arg, - }) - ); + let new_args = + tcx.mk_args_from_iter(targs.iter().map(|arg| match arg.as_type() { + Some(ty) => ty::GenericArg::from(t( + tcx, + tcx.lifetimes.re_erased, + ty.peel_refs(), + )), + _ => arg, + })); let rcvr_ty = Ty::new_adt(tcx, *def, new_args); if let Ok(method) = self.lookup_method_for_diagnostic( rcvr_ty, @@ -1088,7 +1096,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for inherent_method in self.tcx.associated_items(inherent_impl_did).in_definition_order() { - if let Some(attr) = self.tcx.get_attr(inherent_method.def_id, sym::rustc_confusables) + if let Some(attr) = self + .tcx + .get_attr(inherent_method.def_id, sym::rustc_confusables) && let Some(candidates) = parse_confusables(attr) && candidates.contains(&item_name.name) { @@ -1307,7 +1317,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.note(note_str); } if let Some(sugg_span) = sugg_span - && let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) { + && let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) + { let path = self.tcx.def_path_str(trait_ref.skip_binder().def_id); let ty = match item.kind { @@ -1453,10 +1464,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && assoc.kind == ty::AssocKind::Fn { let sig = self.tcx.fn_sig(assoc.def_id).instantiate_identity(); - sig.inputs().skip_binder().get(0).and_then(|first| if first.peel_refs() == rcvr_ty.peel_refs() { - None - } else { - Some(first.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str())) + sig.inputs().skip_binder().get(0).and_then(|first| { + if first.peel_refs() == rcvr_ty.peel_refs() { + None + } else { + Some(first.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str())) + } }) } else { None @@ -1616,7 +1629,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { continue; } - let range_def_id = self.tcx.require_lang_item(lang_item.unwrap(), None); + let Some(range_def_id) = + lang_item.and_then(|lang_item| self.tcx.lang_items().get(lang_item)) + else { + continue; + }; let range_ty = self.tcx.type_of(range_def_id).instantiate(self.tcx, &[actual.into()]); @@ -1725,8 +1742,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let span = tcx.hir().span(hir_id); let filename = tcx.sess.source_map().span_to_filename(span); - let parent_node = - self.tcx.hir().get_parent(hir_id); + let parent_node = self.tcx.hir().get_parent(hir_id); let msg = format!( "you must specify a type for this binding, like `{concrete_type}`", ); @@ -1740,7 +1756,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .. }), ) => { - let type_span = ty.map(|ty| ty.span.with_lo(span.hi())).unwrap_or(span.shrink_to_hi()); + let type_span = ty + .map(|ty| ty.span.with_lo(span.hi())) + .unwrap_or(span.shrink_to_hi()); err.span_suggestion( // account for `let x: _ = 42;` // ^^^ @@ -1839,9 +1857,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return_type: Option<Ty<'tcx>>, ) { if let SelfSource::MethodCall(expr) = source - && let mod_id = self.tcx.parent_module(expr.hir_id).to_def_id() - && let Some((fields, args)) = - self.get_field_candidates_considering_privacy(span, actual, mod_id) + && let mod_id = self.tcx.parent_module(expr.hir_id).to_def_id() + && let Some((fields, args)) = + self.get_field_candidates_considering_privacy(span, actual, mod_id) { let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().parent_id(expr.hir_id)); @@ -2320,7 +2338,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // <&[_]>::len or <&[u32]>::len doesn't need an extra "<>" between // but for Adt type like Vec::function() // we would suggest <[_]>::function(); - _ if self.tcx.sess.source_map().span_wrapped_by_angle_or_parentheses(ty.span) => format!("{deref_ty}"), + _ if self + .tcx + .sess + .source_map() + .span_wrapped_by_angle_or_parentheses(ty.span) => + { + format!("{deref_ty}") + } _ => format!("<{deref_ty}>"), }; err.span_suggestion_verbose( @@ -2539,11 +2564,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Err(_) => (), } - let pred = ty::TraitRef::new( - self.tcx, - self.tcx.lang_items().unpin_trait().unwrap(), - [*rcvr_ty], - ); + let Some(unpin_trait) = self.tcx.lang_items().unpin_trait() else { + return; + }; + let pred = ty::TraitRef::new(self.tcx, unpin_trait, [*rcvr_ty]); let unpin = self.predicate_must_hold_considering_regions(&Obligation::new( self.tcx, ObligationCause::misc(rcvr.span, self.body_id), @@ -2573,8 +2597,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Explicitly ignore the `Pin::as_ref()` method as `Pin` does not // implement the `AsRef` trait. let skip = skippable.contains(&did) - || (("Pin::new" == *pre) && ((sym::as_ref == item_name.name) || !unpin)) - || inputs_len.is_some_and(|inputs_len| pick.item.kind == ty::AssocKind::Fn && self.tcx.fn_sig(pick.item.def_id).skip_binder().skip_binder().inputs().len() != inputs_len); + || (("Pin::new" == *pre) + && ((sym::as_ref == item_name.name) || !unpin)) + || inputs_len.is_some_and(|inputs_len| { + pick.item.kind == ty::AssocKind::Fn + && self + .tcx + .fn_sig(pick.item.def_id) + .skip_binder() + .skip_binder() + .inputs() + .len() + != inputs_len + }); // Make sure the method is defined for the *actual* receiver: we don't // want to treat `Box<Self>` as a receiver if it only works because of // an autoderef to `&self` @@ -2625,7 +2660,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // receiver has the same number of arguments that appear in the user's code. && inputs_len.is_some_and(|inputs_len| pick.item.kind == ty::AssocKind::Fn && self.tcx.fn_sig(pick.item.def_id).skip_binder().skip_binder().inputs().len() == inputs_len) { - let indent = self.tcx.sess + let indent = self + .tcx + .sess .source_map() .indentation_before(rcvr.span) .unwrap_or_else(|| " ".to_string()); @@ -2992,14 +3029,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let parent = self.tcx.hir().parent_id(expr.hir_id); - if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent) && - let hir::ExprKind::MethodCall( + if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent) + && let hir::ExprKind::MethodCall( hir::PathSegment { ident: method_name, .. }, self_expr, args, .., - ) = call_expr.kind && - let Some(self_ty) = self.typeck_results.borrow().expr_ty_opt(self_expr) { + ) = call_expr.kind + && let Some(self_ty) = self.typeck_results.borrow().expr_ty_opt(self_expr) + { let new_name = Ident { name: Symbol::intern(&format!("{}_else", method_name.as_str())), span: method_name.span, @@ -3013,10 +3051,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); // check the method arguments number - if let Ok(pick) = probe && - let fn_sig = self.tcx.fn_sig(pick.item.def_id) && - let fn_args = fn_sig.skip_binder().skip_binder().inputs() && - fn_args.len() == args.len() + 1 { + if let Ok(pick) = probe + && let fn_sig = self.tcx.fn_sig(pick.item.def_id) + && let fn_args = fn_sig.skip_binder().skip_binder().inputs() + && fn_args.len() == args.len() + 1 + { err.span_suggestion_verbose( method_name.span.shrink_to_hi(), format!("try calling `{}` instead", new_name.name.as_str()), diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index a283cd1abf5..c46e641b10d 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -430,33 +430,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(lhs_new_mutbl) = lhs_new_mutbl && let Some(rhs_new_mutbl) = rhs_new_mutbl && lhs_new_mutbl.is_not() - && rhs_new_mutbl.is_not() { + && rhs_new_mutbl.is_not() + { err.multipart_suggestion_verbose( "consider reborrowing both sides", vec![ (lhs_expr.span.shrink_to_lo(), "&*".to_string()), - (rhs_expr.span.shrink_to_lo(), "&*".to_string()) + (rhs_expr.span.shrink_to_lo(), "&*".to_string()), ], rustc_errors::Applicability::MachineApplicable, ); } else { - let mut suggest_new_borrow = |new_mutbl: ast::Mutability, sp: Span| { - // Can reborrow (&mut -> &) - if new_mutbl.is_not() { - err.span_suggestion_verbose( - sp.shrink_to_lo(), - "consider reborrowing this side", - "&*", - rustc_errors::Applicability::MachineApplicable, - ); - // Works on &mut but have & - } else { - err.span_help( - sp, - "consider making this expression a mutable borrow", - ); - } - }; + let mut suggest_new_borrow = + |new_mutbl: ast::Mutability, sp: Span| { + // Can reborrow (&mut -> &) + if new_mutbl.is_not() { + err.span_suggestion_verbose( + sp.shrink_to_lo(), + "consider reborrowing this side", + "&*", + rustc_errors::Applicability::MachineApplicable, + ); + // Works on &mut but have & + } else { + err.span_help( + sp, + "consider making this expression a mutable borrow", + ); + } + }; if let Some(lhs_new_mutbl) = lhs_new_mutbl { suggest_new_borrow(lhs_new_mutbl, lhs_expr.span); @@ -493,20 +495,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else if is_assign == IsAssign::No && let Ref(region, lhs_deref_ty, mutbl) = lhs_ty.kind() { - if self.type_is_copy_modulo_regions( - self.param_env, - *lhs_deref_ty, - ) { + if self.type_is_copy_modulo_regions(self.param_env, *lhs_deref_ty) { suggest_deref_binop(&mut err, *lhs_deref_ty); } else { let lhs_inv_mutbl = mutbl.invert(); let lhs_inv_mutbl_ty = Ty::new_ref( self.tcx, *region, - ty::TypeAndMut { - ty: *lhs_deref_ty, - mutbl: lhs_inv_mutbl, - }, + ty::TypeAndMut { ty: *lhs_deref_ty, mutbl: lhs_inv_mutbl }, ); suggest_different_borrow( @@ -522,10 +518,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let rhs_inv_mutbl_ty = Ty::new_ref( self.tcx, *region, - ty::TypeAndMut { - ty: *rhs_deref_ty, - mutbl: rhs_inv_mutbl, - }, + ty::TypeAndMut { ty: *rhs_deref_ty, mutbl: rhs_inv_mutbl }, ); suggest_different_borrow( @@ -599,7 +592,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(output_def_id) = output_def_id && let Some(trait_def_id) = trait_def_id && self.tcx.parent(output_def_id) == trait_def_id - && let Some(output_ty) = output_ty.make_suggestable(self.tcx, false) + && let Some(output_ty) = + output_ty.make_suggestable(self.tcx, false) { Some(("Output", output_ty)) } else { diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 072c7a9f36a..110ec052b35 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -406,16 +406,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .borrow_mut() .treat_byte_string_as_slice .insert(lt.hir_id.local_id); - pat_ty = Ty::new_imm_ref(tcx,tcx.lifetimes.re_static, Ty::new_slice(tcx,tcx.types.u8)); + pat_ty = + Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, Ty::new_slice(tcx, tcx.types.u8)); } } - if self.tcx.features().string_deref_patterns && let hir::ExprKind::Lit(Spanned { node: ast::LitKind::Str(..), .. }) = lt.kind { + if self.tcx.features().string_deref_patterns + && let hir::ExprKind::Lit(Spanned { node: ast::LitKind::Str(..), .. }) = lt.kind + { let tcx = self.tcx; let expected = self.resolve_vars_if_possible(expected); pat_ty = match expected.kind() { ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().string() => expected, - ty::Str => Ty::new_static_str(tcx,), + ty::Str => Ty::new_static_str(tcx), _ => pat_ty, }; } @@ -707,7 +710,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn borrow_pat_suggestion(&self, err: &mut Diagnostic, pat: &Pat<'_>) { let tcx = self.tcx; if let PatKind::Ref(inner, mutbl) = pat.kind - && let PatKind::Binding(_, _, binding, ..) = inner.kind { + && let PatKind::Binding(_, _, binding, ..) = inner.kind + { let binding_parent_id = tcx.hir().parent_id(pat.hir_id); let binding_parent = tcx.hir().get(binding_parent_id); debug!(?inner, ?pat, ?binding_parent); @@ -754,7 +758,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("to declare a mutable {ident_kind} use"), format!("mut {binding}"), )) - }; match binding_parent { @@ -777,7 +780,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::Node::Pat(pt) if let PatKind::TupleStruct(_, pat_arr, _) = pt.kind => { for i in pat_arr.iter() { if let PatKind::Ref(the_ref, _) = i.kind - && let PatKind::Binding(mt, _, ident, _) = the_ref.kind { + && let PatKind::Binding(mt, _, ident, _) = the_ref.kind + { let hir::BindingAnnotation(_, mtblty) = mt; err.span_suggestion_verbose( i.span, @@ -1480,7 +1484,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (Some(mut err), None) => { err.emit(); } - (None, None) if let Some(mut err) = + (None, None) + if let Some(mut err) = self.error_tuple_variant_index_shorthand(variant, pat, fields) => { err.emit(); @@ -2263,7 +2268,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let ty::Array(..) | ty::Slice(..) = ty.kind() { err.help("the semantics of slice patterns changed recently; see issue #62254"); - } else if self.autoderef(span, expected_ty) + } else if self + .autoderef(span, expected_ty) .any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..))) && let Some(span) = ti.span && let Some(_) = ti.origin_expr @@ -2284,7 +2290,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MaybeIncorrect, ); } - _ => () + _ => (), } if is_slice_or_array_or_vector.0 { err.span_suggestion( diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 9c16b486dbc..322859154bb 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -174,7 +174,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } hir::ExprKind::AssignOp(..) - if let Some(a) = self.typeck_results.adjustments_mut().get_mut(lhs.hir_id) => + if let Some(a) = + self.typeck_results.adjustments_mut().get_mut(lhs.hir_id) => { a.pop(); } @@ -247,7 +248,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { // Since this is "after" the other adjustment to be // discarded, we do an extra `pop()` if let Some(Adjustment { - kind: Adjust::Pointer(PointerCoercion::Unsize), .. + kind: Adjust::Pointer(PointerCoercion::Unsize), + .. }) = a.pop() { // So the borrow discard actually happens here @@ -568,10 +570,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { // Here we only detect impl trait definition conflicts when they // are equal modulo regions. - if let Some(last_opaque_ty) = self - .typeck_results - .concrete_opaque_types - .insert(opaque_type_key, hidden_type) + if let Some(last_opaque_ty) = + self.typeck_results.concrete_opaque_types.insert(opaque_type_key, hidden_type) && last_opaque_ty.ty != hidden_type.ty { assert!(!self.fcx.next_trait_solver()); diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index 9276bb0a7b7..57bc14ebcb3 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -60,9 +60,7 @@ impl<'a> DescriptionCtx<'a> { let span = Some(tcx.def_span(scope)); (span, "defined_here", String::new()) } - _ => { - (Some(tcx.def_span(scope)), "defined_here_reg", region.to_string()) - } + _ => (Some(tcx.def_span(scope)), "defined_here_reg", region.to_string()), } } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 12dcb711820..d35b318e258 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -227,8 +227,10 @@ fn msg_span_from_named_region<'tcx>( let scope = region.free_region_binding_scope(tcx).expect_local(); match fr.bound_region { ty::BoundRegionKind::BrNamed(_, name) => { - let span = if let Some(param) = - tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name)) + let span = if let Some(param) = tcx + .hir() + .get_generics(scope) + .and_then(|generics| generics.get_named(name)) { param.span } else { @@ -243,7 +245,7 @@ fn msg_span_from_named_region<'tcx>( } ty::BrAnon => ( "the anonymous lifetime as defined here".to_string(), - Some(tcx.def_span(scope)) + Some(tcx.def_span(scope)), ), _ => ( format!("the lifetime `{region}` as defined here"), @@ -715,13 +717,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { && let ty::Adt(def, args) = ty.kind() && Some(def.did()) == self.tcx.get_diagnostic_item(sym::Option) { - err.span_label(span, format!("this is an iterator with items of type `{}`", args.type_at(0))); + err.span_label( + span, + format!("this is an iterator with items of type `{}`", args.type_at(0)), + ); } else { - err.span_label(span, format!("this expression has type `{ty}`")); - } + err.span_label(span, format!("this expression has type `{ty}`")); + } } if let Some(ty::error::ExpectedFound { found, .. }) = exp_found - && ty.is_box() && ty.boxed_ty() == found + && ty.is_box() + && ty.boxed_ty() == found && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { err.span_suggestion( @@ -743,9 +749,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id); let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind { let arg_expr = args.first().expect("try desugaring call w/out arg"); - self.typeck_results.as_ref().and_then(|typeck_results| { - typeck_results.expr_ty_opt(arg_expr) - }) + self.typeck_results + .as_ref() + .and_then(|typeck_results| typeck_results.expr_ty_opt(arg_expr)) } else { bug!("try desugaring w/out call expr as scrutinee"); }; @@ -763,7 +769,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { _ => {} } } - }, + } ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { arm_block_id, arm_span, @@ -782,9 +788,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id); let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind { let arg_expr = args.first().expect("try desugaring call w/out arg"); - self.typeck_results.as_ref().and_then(|typeck_results| { - typeck_results.expr_ty_opt(arg_expr) - }) + self.typeck_results + .as_ref() + .and_then(|typeck_results| typeck_results.expr_ty_opt(arg_expr)) } else { bug!("try desugaring w/out call expr as scrutinee"); }; @@ -878,8 +884,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } // don't suggest wrapping either blocks in `if .. {} else {}` let is_empty_arm = |id| { - let hir::Node::Block(blk) = self.tcx.hir().get(id) - else { + let hir::Node::Block(blk) = self.tcx.hir().get(id) else { return false; }; if blk.expr.is_some() || !blk.stmts.is_empty() { @@ -908,12 +913,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } _ => { if let ObligationCauseCode::BindingObligation(_, span) - | ObligationCauseCode::ExprBindingObligation(_, span, ..) - = cause.code().peel_derives() + | ObligationCauseCode::ExprBindingObligation(_, span, ..) = + cause.code().peel_derives() && let TypeError::RegionsPlaceholderMismatch = terr { - err.span_note( * span, - "the lifetime requirement is introduced here"); + err.span_note(*span, "the lifetime requirement is introduced here"); } } } @@ -1742,19 +1746,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } let similarity = |ExpectedFound { expected, found }: ExpectedFound<Ty<'tcx>>| { - if let ty::Adt(expected, _) = expected.kind() && let Some(primitive) = found.primitive_symbol() { + if let ty::Adt(expected, _) = expected.kind() + && let Some(primitive) = found.primitive_symbol() + { let path = self.tcx.def_path(expected.did()).data; let name = path.last().unwrap().data.get_opt_name(); if name == Some(primitive) { return Some(Similar::PrimitiveFound { expected: *expected, found }); } - } else if let Some(primitive) = expected.primitive_symbol() && let ty::Adt(found, _) = found.kind() { + } else if let Some(primitive) = expected.primitive_symbol() + && let ty::Adt(found, _) = found.kind() + { let path = self.tcx.def_path(found.did()).data; let name = path.last().unwrap().data.get_opt_name(); if name == Some(primitive) { return Some(Similar::PrimitiveExpected { expected, found: *found }); } - } else if let ty::Adt(expected, _) = expected.kind() && let ty::Adt(found, _) = found.kind() { + } else if let ty::Adt(expected, _) = expected.kind() + && let ty::Adt(found, _) = found.kind() + { if !expected.did().is_local() && expected.did().krate == found.did().krate { // Most likely types from different versions of the same crate // are in play, in which case this message isn't so helpful. @@ -1764,8 +1774,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let f_path = self.tcx.def_path(found.did()).data; let e_path = self.tcx.def_path(expected.did()).data; - if let (Some(e_last), Some(f_last)) = (e_path.last(), f_path.last()) && e_last == f_last { - return Some(Similar::Adts{expected: *expected, found: *found}); + if let (Some(e_last), Some(f_last)) = (e_path.last(), f_path.last()) + && e_last == f_last + { + return Some(Similar::Adts { expected: *expected, found: *found }); } } None @@ -1796,7 +1808,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; let diagnose_adts = - |expected_adt : ty::AdtDef<'tcx>, + |expected_adt: ty::AdtDef<'tcx>, found_adt: ty::AdtDef<'tcx>, diagnostic: &mut Diagnostic| { let found_name = values.found.sort_string(self.tcx); @@ -1816,8 +1828,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .tcx .parent_module_from_def_id(defid.expect_local()) .to_def_id(); - let module_name = self.tcx.def_path(module).to_string_no_crate_verbose(); - format!("{name} is defined in module `crate{module_name}` of the current crate") + let module_name = + self.tcx.def_path(module).to_string_no_crate_verbose(); + format!( + "{name} is defined in module `crate{module_name}` of the current crate" + ) } else if defid.is_local() { format!("{name} is defined in the current crate") } else { @@ -1829,13 +1844,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; match s { - Similar::Adts{expected, found} => { - diagnose_adts(expected, found, diag) - } - Similar::PrimitiveFound{expected, found: prim} => { + Similar::Adts { expected, found } => diagnose_adts(expected, found, diag), + Similar::PrimitiveFound { expected, found: prim } => { diagnose_primitive(prim, values.expected, expected.did(), diag) } - Similar::PrimitiveExpected{expected: prim, found} => { + Similar::PrimitiveExpected { expected: prim, found } => { diagnose_primitive(prim, values.found, found.did(), diag) } } @@ -1877,7 +1890,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } s }; - if !(values.expected.is_simple_text(self.tcx) && values.found.is_simple_text(self.tcx)) + if !(values.expected.is_simple_text(self.tcx) + && values.found.is_simple_text(self.tcx)) || (exp_found.is_some_and(|ef| { // This happens when the type error is a subset of the expectation, // like when you have two references but one is `usize` and the other @@ -1967,13 +1981,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { && let exp_found = TypeError::Sorts(exp_found) && exp_found != terr { - self.note_and_explain_type_err( - diag, - exp_found, - cause, - span, - cause.body_id.to_def_id(), - ); + self.note_and_explain_type_err(diag, exp_found, cause, span, cause.body_id.to_def_id()); } if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values @@ -1983,7 +1991,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { { let span = self.tcx.def_span(def_id); diag.span_note(span, "this closure does not fulfill the lifetime requirements"); - self.suggest_for_all_lifetime_closure(span, self.tcx.hir().get_by_def_id(def_id), &exp_found, diag); + self.suggest_for_all_lifetime_closure( + span, + self.tcx.hir().get_by_def_id(def_id), + &exp_found, + diag, + ); } // It reads better to have the error origin as the final @@ -2009,7 +2022,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // parentheses around it, perhaps the user meant to write `(expr,)` to // build a tuple (issue #86100) (ty::Tuple(fields), _) => { - suggestions.extend(self.suggest_wrap_to_build_a_tuple( span, found, fields)) + suggestions.extend(self.suggest_wrap_to_build_a_tuple(span, found, fields)) } // If a byte was expected and the found expression is a char literal // containing a single ASCII character, perhaps the user meant to write `b'c'` to @@ -2059,8 +2072,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } // For code `if Some(..) = expr `, the type mismatch may be expected `bool` but found `()`, // we try to suggest to add the missing `let` for `if let Some(..) = expr` - (ty::Bool, ty::Tuple(list)) => if list.len() == 0 { - suggestions.extend(self.suggest_let_for_letchains(&trace.cause, span)); + (ty::Bool, ty::Tuple(list)) => { + if list.len() == 0 { + suggestions.extend(self.suggest_let_for_letchains(&trace.cause, span)); + } } (ty::Array(_, _), ty::Array(_, _)) => { suggestions.extend(self.suggest_specify_actual_length(terr, trace, span)) @@ -2070,8 +2085,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } let code = trace.cause.code(); if let &(MatchExpressionArm(box MatchExpressionArmCause { source, .. }) - | BlockTailExpression(.., source) - ) = code + | BlockTailExpression(.., source)) = code && let hir::MatchSource::TryDesugar(_) = source && let Some((expected_ty, found_ty, _, _)) = self.values_str(trace.values) { @@ -2108,17 +2122,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // Find a local statement where the initializer has // the same span as the error and the type is specified. if let hir::Stmt { - kind: hir::StmtKind::Local(hir::Local { - init: Some(hir::Expr { - span: init_span, + kind: + hir::StmtKind::Local(hir::Local { + init: Some(hir::Expr { span: init_span, .. }), + ty: Some(array_ty), .. }), - ty: Some(array_ty), - .. - }), .. } = s - && init_span == &self.span { + && init_span == &self.span + { self.result = Some(*array_ty); } } 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 e45108d1713..5408b99235d 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 @@ -163,13 +163,13 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte let ty_vars = infcx_inner.type_variables(); let var_origin = ty_vars.var_origin(ty_vid); if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind - && name != kw::SelfUpper && !var_origin.span.from_expansion() + && name != kw::SelfUpper + && !var_origin.span.from_expansion() { let generics = infcx.tcx.generics_of(infcx.tcx.parent(def_id)); let idx = generics.param_def_id_to_index(infcx.tcx, def_id).unwrap(); let generic_param_def = generics.param_at(idx as usize, infcx.tcx); - if let ty::GenericParamDefKind::Type { synthetic: true, .. } = generic_param_def.kind - { + if let ty::GenericParamDefKind::Type { synthetic: true, .. } = generic_param_def.kind { None } else { Some(name) @@ -792,8 +792,9 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { let cost = self.source_cost(&new_source) + self.attempt; debug!(?cost); self.attempt += 1; - if let Some(InferSource { kind: InferSourceKind::GenericArg { def_id: did, ..}, .. }) = self.infer_source - && let InferSourceKind::LetBinding { ref ty, ref mut def_id, ..} = new_source.kind + if let Some(InferSource { kind: InferSourceKind::GenericArg { def_id: did, .. }, .. }) = + self.infer_source + && let InferSourceKind::LetBinding { ref ty, ref mut def_id, .. } = new_source.kind && ty.is_ty_or_numeric_infer() { // Customize the output so we talk about `let x: Vec<_> = iter.collect();` instead of @@ -1242,7 +1243,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { successor, args, def_id, - } + }, }) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 3cfda0cc5c0..e2be6cf4280 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -214,7 +214,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ObligationCauseCode::MatchImpl(parent, ..) => parent.code(), _ => cause.code(), } - && let (&ObligationCauseCode::ItemObligation(item_def_id) | &ObligationCauseCode::ExprItemObligation(item_def_id, ..), None) = (code, override_error_code) + && let ( + &ObligationCauseCode::ItemObligation(item_def_id) + | &ObligationCauseCode::ExprItemObligation(item_def_id, ..), + None, + ) = (code, override_error_code) { // Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static` // lifetime as above, but called using a fully-qualified path to the method: @@ -322,13 +326,27 @@ pub fn suggest_new_region_bound( let existing_lt_name = if let Some(id) = scope_def_id && let Some(generics) = tcx.hir().get_generics(id) && let named_lifetimes = generics - .params - .iter() - .filter(|p| matches!(p.kind, GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit })) - .map(|p| { if let hir::ParamName::Plain(name) = p.name {Some(name.to_string())} else {None}}) - .filter(|n| ! matches!(n, None)) - .collect::<Vec<_>>() - && named_lifetimes.len() > 0 { + .params + .iter() + .filter(|p| { + matches!( + p.kind, + GenericParamKind::Lifetime { + kind: hir::LifetimeParamKind::Explicit + } + ) + }) + .map(|p| { + if let hir::ParamName::Plain(name) = p.name { + Some(name.to_string()) + } else { + None + } + }) + .filter(|n| !matches!(n, None)) + .collect::<Vec<_>>() + && named_lifetimes.len() > 0 + { named_lifetimes[0].clone() } else { None @@ -342,30 +360,28 @@ pub fn suggest_new_region_bound( .params .iter() .filter(|p| p.is_elided_lifetime()) - .map(|p| - if p.span.hi() - p.span.lo() == rustc_span::BytePos(1) { // Ampersand (elided without '_) - (p.span.shrink_to_hi(),format!("{name} ")) - } else { // Underscore (elided with '_) - (p.span, name.to_string()) - } - ) + .map(|p| { + if p.span.hi() - p.span.lo() == rustc_span::BytePos(1) { + // Ampersand (elided without '_) + (p.span.shrink_to_hi(), format!("{name} ")) + } else { + // Underscore (elided with '_) + (p.span, name.to_string()) + } + }) .collect::<Vec<_>>() && spans_suggs.len() > 1 { - let use_lt = - if existing_lt_name == None { + let use_lt = if existing_lt_name == None { spans_suggs.push((generics.span.shrink_to_hi(), format!("<{name}>"))); format!("you can introduce a named lifetime parameter `{name}`") } else { // make use the existing named lifetime format!("you can use the named lifetime parameter `{name}`") }; - spans_suggs - .push((fn_return.span.shrink_to_hi(), format!(" + {name} "))); + spans_suggs.push((fn_return.span.shrink_to_hi(), format!(" + {name} "))); err.multipart_suggestion_verbose( - format!( - "{declare} `{ty}` {captures}, {use_lt}", - ), + format!("{declare} `{ty}` {captures}, {use_lt}",), spans_suggs, Applicability::MaybeIncorrect, ); @@ -443,8 +459,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let trait_did = trait_id.to_def_id(); tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| { if let Node::Item(Item { - kind: ItemKind::Impl(hir::Impl { self_ty, .. }), - .. + kind: ItemKind::Impl(hir::Impl { self_ty, .. }), .. }) = tcx.hir().find_by_def_id(impl_did)? && trait_objects.iter().all(|did| { // FIXME: we should check `self_ty` against the receiver diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index 5c3beee284f..24767b0bda6 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -72,32 +72,30 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { #traits-as-parameters", ); } - (ty::Alias(ty::Projection | ty::Inherent, _), ty::Alias(ty::Projection | ty::Inherent, _)) => { + ( + ty::Alias(ty::Projection | ty::Inherent, _), + ty::Alias(ty::Projection | ty::Inherent, _), + ) => { diag.note("an associated type was expected, but a different one was found"); } // FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too. - (ty::Param(p), ty::Alias(ty::Projection, proj)) | (ty::Alias(ty::Projection, proj), ty::Param(p)) + (ty::Param(p), ty::Alias(ty::Projection, proj)) + | (ty::Alias(ty::Projection, proj), ty::Param(p)) if !tcx.is_impl_trait_in_trait(proj.def_id) => { - let p_def_id = tcx - .generics_of(body_owner_def_id) - .type_param(p, tcx) - .def_id; + let p_def_id = tcx.generics_of(body_owner_def_id).type_param(p, tcx).def_id; let p_span = tcx.def_span(p_def_id); if !sp.contains(p_span) { diag.span_label(p_span, "this type parameter"); } let hir = tcx.hir(); let mut note = true; - let parent = p_def_id - .as_local() - .and_then(|id| { - let local_id = hir.local_def_id_to_hir_id(id); - let generics = tcx.hir().find_parent(local_id)?.generics()?; - Some((id, generics)) - }); - if let Some((local_id, generics)) = parent - { + let parent = p_def_id.as_local().and_then(|id| { + let local_id = hir.local_def_id_to_hir_id(id); + let generics = tcx.hir().find_parent(local_id)?.generics()?; + Some((id, generics)) + }); + if let Some((local_id, generics)) = parent { // Synthesize the associated type restriction `Add<Output = Expected>`. // FIXME: extract this logic for use in other diagnostics. let (trait_ref, assoc_args) = proj.trait_ref_and_own_args(tcx); @@ -112,15 +110,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let mut matching_span = None; let mut matched_end_of_args = false; for bound in generics.bounds_for_param(local_id) { - let potential_spans = bound - .bounds - .iter() - .find_map(|bound| { - let bound_trait_path = bound.trait_ref()?.path; - let def_id = bound_trait_path.res.opt_def_id()?; - let generic_args = bound_trait_path.segments.iter().last().map(|path| path.args()); - (def_id == trait_ref.def_id).then_some((bound_trait_path.span, generic_args)) - }); + let potential_spans = bound.bounds.iter().find_map(|bound| { + let bound_trait_path = bound.trait_ref()?.path; + let def_id = bound_trait_path.res.opt_def_id()?; + let generic_args = bound_trait_path + .segments + .iter() + .last() + .map(|path| path.args()); + (def_id == trait_ref.def_id) + .then_some((bound_trait_path.span, generic_args)) + }); if let Some((end_of_trait, end_of_args)) = potential_spans { let args_span = end_of_args.and_then(|args| args.span()); @@ -223,7 +223,9 @@ impl<T> Trait<T> for X { diag.span_label(p_span, "this type parameter"); } } - (ty::Alias(ty::Projection | ty::Inherent, proj_ty), _) if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => { + (ty::Alias(ty::Projection | ty::Inherent, proj_ty), _) + if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => + { self.expected_projection( diag, proj_ty, @@ -232,11 +234,15 @@ impl<T> Trait<T> for X { cause.code(), ); } - (_, ty::Alias(ty::Projection | ty::Inherent, proj_ty)) if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => { - let msg = || format!( - "consider constraining the associated type `{}` to `{}`", - values.found, values.expected, - ); + (_, ty::Alias(ty::Projection | ty::Inherent, proj_ty)) + if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => + { + let msg = || { + format!( + "consider constraining the associated type `{}` to `{}`", + values.found, values.expected, + ) + }; if !(self.suggest_constraining_opaque_associated_type( diag, msg, @@ -256,19 +262,40 @@ impl<T> Trait<T> for X { ); } } - (ty::Alias(ty::Opaque, alias), _) | (_, ty::Alias(ty::Opaque, alias)) if alias.def_id.is_local() && matches!(tcx.def_kind(body_owner_def_id), DefKind::Fn | DefKind::Static(_) | DefKind::Const | DefKind::AssocFn | DefKind::AssocConst) => { + (ty::Alias(ty::Opaque, alias), _) | (_, ty::Alias(ty::Opaque, alias)) + if alias.def_id.is_local() + && matches!( + tcx.def_kind(body_owner_def_id), + DefKind::Fn + | DefKind::Static(_) + | DefKind::Const + | DefKind::AssocFn + | DefKind::AssocConst + ) => + { if tcx.is_type_alias_impl_trait(alias.def_id) { - if !tcx.opaque_types_defined_by(body_owner_def_id.expect_local()).contains(&alias.def_id.expect_local()) { - let sp = tcx.def_ident_span(body_owner_def_id).unwrap_or_else(|| tcx.def_span(body_owner_def_id)); - diag.span_note(sp, "\ + if !tcx + .opaque_types_defined_by(body_owner_def_id.expect_local()) + .contains(&alias.def_id.expect_local()) + { + let sp = tcx + .def_ident_span(body_owner_def_id) + .unwrap_or_else(|| tcx.def_span(body_owner_def_id)); + diag.span_note( + sp, + "\ this item must have the opaque type in its signature \ - in order to be able to register hidden types"); + in order to be able to register hidden types", + ); } } } - (ty::FnPtr(sig), ty::FnDef(def_id, _)) | (ty::FnDef(def_id, _), ty::FnPtr(sig)) => { + (ty::FnPtr(sig), ty::FnDef(def_id, _)) + | (ty::FnDef(def_id, _), ty::FnPtr(sig)) => { if tcx.fn_sig(*def_id).skip_binder().unsafety() < sig.unsafety() { - diag.note("unsafe functions cannot be coerced into safe function pointers"); + diag.note( + "unsafe functions cannot be coerced into safe function pointers", + ); } } _ => {} @@ -616,7 +643,8 @@ fn foo(&self) -> Self::T { String::new() } for item in &items[..] { if let hir::AssocItemKind::Type = item.kind { let assoc_ty = tcx.type_of(item.id.owner_id).instantiate_identity(); - if let hir::Defaultness::Default { has_value: true } = tcx.defaultness(item.id.owner_id) + if let hir::Defaultness::Default { has_value: true } = + tcx.defaultness(item.id.owner_id) && self.infcx.can_eq(param_env, assoc_ty, found) { diag.span_label( diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index f1d53cb59cd..fe18d00293a 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -491,12 +491,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) { if let hir::StmtKind::Local(hir::Local { - span, pat: hir::Pat{..}, ty: None, init: Some(_), .. - }) = &ex.kind - && self.found_if - && span.eq(&self.err_span) { - self.result = true; - } + span, + pat: hir::Pat { .. }, + ty: None, + init: Some(_), + .. + }) = &ex.kind + && self.found_if + && span.eq(&self.err_span) + { + self.result = true; + } walk_stmt(self, ex); } @@ -546,45 +551,59 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let expected = expected.unpack(); let found = found.unpack(); // 3. Extract the tuple type from Fn trait and suggest the change. - if let GenericArgKind::Type(expected) = expected && - let GenericArgKind::Type(found) = found && - let ty::Tuple(expected) = expected.kind() && - let ty::Tuple(found)= found.kind() && - expected.len() == found.len() { + if let GenericArgKind::Type(expected) = expected + && let GenericArgKind::Type(found) = found + && let ty::Tuple(expected) = expected.kind() + && let ty::Tuple(found) = found.kind() + && expected.len() == found.len() + { let mut suggestion = "|".to_string(); let mut is_first = true; let mut has_suggestion = false; - for (((expected, found), param_hir), arg_hir) in expected.iter() - .zip(found.iter()) - .zip(params.iter()) - .zip(fn_decl.inputs.iter()) { + for (((expected, found), param_hir), arg_hir) in + expected.iter().zip(found.iter()).zip(params.iter()).zip(fn_decl.inputs.iter()) + { if is_first { is_first = false; } else { suggestion += ", "; } - if let ty::Ref(expected_region, _, _) = expected.kind() && - let ty::Ref(found_region, _, _) = found.kind() && - expected_region.is_late_bound() && - !found_region.is_late_bound() && - let hir::TyKind::Infer = arg_hir.kind { + if let ty::Ref(expected_region, _, _) = expected.kind() + && let ty::Ref(found_region, _, _) = found.kind() + && expected_region.is_late_bound() + && !found_region.is_late_bound() + && let hir::TyKind::Infer = arg_hir.kind + { // If the expected region is late bound, the found region is not, and users are asking compiler // to infer the type, we can suggest adding `: &_`. if param_hir.pat.span == param_hir.ty_span { // for `|x|`, `|_|`, `|x: impl Foo|` - let Ok(pat) = self.tcx.sess.source_map().span_to_snippet(param_hir.pat.span) else { return; }; + let Ok(pat) = + self.tcx.sess.source_map().span_to_snippet(param_hir.pat.span) + else { + return; + }; suggestion += &format!("{pat}: &_"); } else { // for `|x: ty|`, `|_: ty|` - let Ok(pat) = self.tcx.sess.source_map().span_to_snippet(param_hir.pat.span) else { return; }; - let Ok(ty) = self.tcx.sess.source_map().span_to_snippet(param_hir.ty_span) else { return; }; + let Ok(pat) = + self.tcx.sess.source_map().span_to_snippet(param_hir.pat.span) + else { + return; + }; + let Ok(ty) = self.tcx.sess.source_map().span_to_snippet(param_hir.ty_span) + else { + return; + }; suggestion += &format!("{pat}: &{ty}"); } has_suggestion = true; } else { - let Ok(arg) = self.tcx.sess.source_map().span_to_snippet(param_hir.span) else { return; }; + let Ok(arg) = self.tcx.sess.source_map().span_to_snippet(param_hir.span) else { + return; + }; // Otherwise, keep it as-is. suggestion += &arg; } diff --git a/compiler/rustc_infer/src/infer/fudge.rs b/compiler/rustc_infer/src/infer/fudge.rs index 86c2c2be4a8..2f371c4fe31 100644 --- a/compiler/rustc_infer/src/infer/fudge.rs +++ b/compiler/rustc_infer/src/infer/fudge.rs @@ -220,7 +220,9 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for InferenceFudger<'a, 'tcx> { } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - if let ty::ReVar(vid) = *r && self.region_vars.0.contains(&vid) { + if let ty::ReVar(vid) = *r + && self.region_vars.0.contains(&vid) + { let idx = vid.index() - self.region_vars.0.start.index(); let origin = self.region_vars.1[idx]; return self.infcx.next_region_var(origin); diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index cb651363982..bee0a978ad0 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -346,7 +346,9 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // tighter bound than `'static`. // // (This might e.g. arise from being asked to prove `for<'a> { 'b: 'a }`.) - if let ty::RePlaceholder(p) = *lub && b_universe.cannot_name(p.universe) { + if let ty::RePlaceholder(p) = *lub + && b_universe.cannot_name(p.universe) + { lub = self.tcx().lifetimes.re_static; } diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs index 2d6b88226ad..6f973ee37f5 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -177,7 +177,9 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstHigherRankedOutlives<'tcx> { value: ty::Region<'tcx>, ) -> RelateResult<'tcx, ty::Region<'tcx>> { debug!("self.pattern_depth = {:?}", self.pattern_depth); - if let ty::RegionKind::ReLateBound(depth, br) = pattern.kind() && depth == self.pattern_depth { + if let ty::RegionKind::ReLateBound(depth, br) = pattern.kind() + && depth == self.pattern_depth + { self.bind(br, value) } else if pattern == value { Ok(pattern) diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index 4279d0ab7ab..7f0a4717d88 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -108,20 +108,20 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { let alias_ty_as_ty = alias_ty.to_ty(self.tcx); // Search the env for where clauses like `P: 'a`. - let env_bounds = self - .approx_declared_bounds_from_env(alias_ty) - .into_iter() - .map(|binder| { - if let Some(ty::OutlivesPredicate(ty, r)) = binder.no_bound_vars() && ty == alias_ty_as_ty { - // Micro-optimize if this is an exact match (this - // occurs often when there are no region variables - // involved). - VerifyBound::OutlivedBy(r) - } else { - let verify_if_eq_b = binder.map_bound(|ty::OutlivesPredicate(ty, bound)| VerifyIfEq { ty, bound }); - VerifyBound::IfEq(verify_if_eq_b) - } - }); + let env_bounds = self.approx_declared_bounds_from_env(alias_ty).into_iter().map(|binder| { + if let Some(ty::OutlivesPredicate(ty, r)) = binder.no_bound_vars() + && ty == alias_ty_as_ty + { + // Micro-optimize if this is an exact match (this + // occurs often when there are no region variables + // involved). + VerifyBound::OutlivedBy(r) + } else { + let verify_if_eq_b = + binder.map_bound(|ty::OutlivesPredicate(ty, bound)| VerifyIfEq { ty, bound }); + VerifyBound::IfEq(verify_if_eq_b) + } + }); // Extend with bounds that we can find from the definition. let definition_bounds = diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 708c51cabeb..3fa9a7333a4 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -457,7 +457,9 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { debug!("RegionConstraintCollector: add_verify({:?})", verify); // skip no-op cases known to be satisfied - if let VerifyBound::AllBounds(ref bs) = verify.bound && bs.is_empty() { + if let VerifyBound::AllBounds(ref bs) = verify.bound + && bs.is_empty() + { return; } diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index e72a43630e9..7a335827f37 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -62,7 +62,9 @@ pub fn report_object_safety_error<'tcx>( let mut multi_span = vec![]; let mut messages = vec![]; for violation in violations { - if let ObjectSafetyViolation::SizedSelf(sp) = &violation && !sp.is_empty() { + if let ObjectSafetyViolation::SizedSelf(sp) = &violation + && !sp.is_empty() + { // Do not report `SizedSelf` without spans pointing at `SizedSelf` obligations // with a `Span`. reported_violations.insert(ObjectSafetyViolation::SizedSelf(vec![].into())); diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 1c330c064ab..3e77a84bf9e 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -5,6 +5,7 @@ use rustc_ast::{self as ast, LitKind, MetaItemKind}; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::defer; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::Lrc; use rustc_errors::registry::Registry; use rustc_errors::{ErrorGuaranteed, Handler}; @@ -260,6 +261,12 @@ pub struct Config { /// This is a callback from the driver that is called when [`ParseSess`] is created. pub parse_sess_created: Option<Box<dyn FnOnce(&mut ParseSess) + Send>>, + /// This is a callback to hash otherwise untracked state used by the caller, if the + /// hash changes between runs the incremental cache will be cleared. + /// + /// e.g. used by Clippy to hash its config file + pub hash_untracked_state: Option<Box<dyn FnOnce(&Session, &mut StableHasher) + Send>>, + /// This is a callback from the driver that is called when we're registering lints; /// it is called during plugin registration when we have the LintStore in a non-shared state. /// @@ -269,8 +276,6 @@ pub struct Config { /// This is a callback from the driver that is called just after we have populated /// the list of queries. - /// - /// The second parameter is local providers and the third parameter is external providers. pub override_queries: Option<fn(&Session, &mut Providers)>, /// This is a callback from the driver that is called to create a codegen backend. @@ -330,6 +335,12 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se parse_sess_created(&mut sess.parse_sess); } + if let Some(hash_untracked_state) = config.hash_untracked_state { + let mut hasher = StableHasher::new(); + hash_untracked_state(&sess, &mut hasher); + sess.opts.untracked_state_hash = hasher.finish() + } + let compiler = Compiler { sess: Lrc::new(sess), codegen_backend: Lrc::from(codegen_backend), diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index fa4b8e4c36b..197fe6552d7 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -7,7 +7,7 @@ lint_array_into_iter = lint_async_fn_in_trait = use of `async fn` in public traits is discouraged as auto trait bounds cannot be specified .note = you can suppress this lint if you plan to use the trait only in your own code, or do not care about auto traits like `Send` on the `Future` - .suggestion = you can alternatively desugar to a normal `fn` that returns `impl Future` and add any desired bounds such as `Send` + .suggestion = you can alternatively desugar to a normal `fn` that returns `impl Future` and add any desired bounds such as `Send`, but these cannot be relaxed without a breaking API change lint_atomic_ordering_fence = memory fences cannot have `Relaxed` ordering .help = consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst` diff --git a/compiler/rustc_lint/src/async_fn_in_trait.rs b/compiler/rustc_lint/src/async_fn_in_trait.rs index ff4c81e2fc9..2a49a003da1 100644 --- a/compiler/rustc_lint/src/async_fn_in_trait.rs +++ b/compiler/rustc_lint/src/async_fn_in_trait.rs @@ -11,7 +11,6 @@ declare_lint! { /// ### Example /// /// ```rust - /// # #![feature(async_fn_in_trait)] /// pub trait Trait { /// async fn method(&self); /// } @@ -33,7 +32,6 @@ declare_lint! { /// For example, this code is invalid: /// /// ```rust,compile_fail - /// # #![feature(async_fn_in_trait)] /// pub trait Trait { /// async fn method(&self) {} /// } @@ -51,7 +49,6 @@ declare_lint! { /// For example, instead of: /// /// ```rust - /// # #![feature(async_fn_in_trait)] /// pub trait Trait { /// async fn method(&self) {} /// } @@ -120,9 +117,12 @@ impl<'tcx> LateLintPass<'tcx> for AsyncFnInTrait { def.owner_id.def_id, " + Send", ); - cx.tcx.emit_spanned_lint(ASYNC_FN_IN_TRAIT, item.hir_id(), async_span, AsyncFnInTraitDiag { - sugg - }); + cx.tcx.emit_spanned_lint( + ASYNC_FN_IN_TRAIT, + item.hir_id(), + async_span, + AsyncFnInTraitDiag { sugg }, + ); } } } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index be9465ba23d..3e44e168786 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -121,16 +121,14 @@ impl EarlyLintPass for WhileTrue { { let condition_span = e.span.with_hi(cond.span.hi()); let replace = format!( - "{}loop", - label.map_or_else(String::new, |label| format!( - "{}: ", - label.ident, - )) - ); - cx.emit_spanned_lint(WHILE_TRUE, condition_span, BuiltinWhileTrue { - suggestion: condition_span, - replace, - }); + "{}loop", + label.map_or_else(String::new, |label| format!("{}: ", label.ident,)) + ); + cx.emit_spanned_lint( + WHILE_TRUE, + condition_span, + BuiltinWhileTrue { suggestion: condition_span, replace }, + ); } } } @@ -164,7 +162,9 @@ declare_lint_pass!(BoxPointers => [BOX_POINTERS]); impl BoxPointers { fn check_heap_type(&self, cx: &LateContext<'_>, span: Span, ty: Ty<'_>) { for leaf in ty.walk() { - if let GenericArgKind::Type(leaf_ty) = leaf.unpack() && leaf_ty.is_box() { + if let GenericArgKind::Type(leaf_ty) = leaf.unpack() + && leaf_ty.is_box() + { cx.emit_spanned_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty }); } } @@ -681,7 +681,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { // We shouldn't recommend implementing `Copy` on stateful things, // such as iterators. if let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator) - && cx.tcx + && cx + .tcx .infer_ctxt() .build() .type_implements_trait(iter_trait, [ty], param_env) @@ -1298,10 +1299,14 @@ impl<'tcx> LateLintPass<'tcx> for UngatedAsyncFnTrackCaller { // Now, check if the function has the `#[track_caller]` attribute && let Some(attr) = cx.tcx.get_attr(def_id, sym::track_caller) { - cx.emit_spanned_lint(UNGATED_ASYNC_FN_TRACK_CALLER, attr.span, BuiltinUngatedAsyncFnTrackCaller { - label: span, - parse_sess: &cx.tcx.sess.parse_sess, - }); + cx.emit_spanned_lint( + UNGATED_ASYNC_FN_TRACK_CALLER, + attr.span, + BuiltinUngatedAsyncFnTrackCaller { + label: span, + parse_sess: &cx.tcx.sess.parse_sess, + }, + ); } } } @@ -2244,7 +2249,7 @@ declare_lint! { } declare_lint_pass!( - /// Check for used feature gates in `INCOMPLETE_FEATURES` in `rustc_feature/src/active.rs`. + /// Check for used feature gates in `INCOMPLETE_FEATURES` in `rustc_feature/src/unstable.rs`. IncompleteInternalFeatures => [INCOMPLETE_FEATURES, INTERNAL_FEATURES] ); diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 1ed9b86d66c..eb1c6be48e6 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -1357,7 +1357,7 @@ impl<'tcx> LateContext<'tcx> { && let Some(init) = match parent_node { hir::Node::Expr(expr) => Some(expr), hir::Node::Local(hir::Local { init, .. }) => *init, - _ => None + _ => None, } { expr = init.peel_blocks(); @@ -1406,9 +1406,9 @@ impl<'tcx> LateContext<'tcx> { hir::ItemKind::Const(.., body_id) | hir::ItemKind::Static(.., body_id) => { Some(self.tcx.hir().body(body_id).value) } - _ => None - } - _ => None + _ => None, + }, + _ => None, } { expr = init.peel_blocks(); diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs index 9be2edf8453..bc11082d278 100644 --- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs +++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs @@ -75,14 +75,16 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait { && supertraits(cx.tcx, t_principal.with_self_ty(cx.tcx, cx.tcx.types.trait_object_dummy_self)) .any(|sup| sup.map_bound(|x| ty::ExistentialTraitRef::erase_self_ty(cx.tcx, x)) == target_principal) { - let label = impl_.items.iter().find_map(|i| (i.ident.name == sym::Target).then_some(i.span)).map(|label| SupertraitAsDerefTargetLabel { - label, - }); - cx.emit_spanned_lint(DEREF_INTO_DYN_SUPERTRAIT, cx.tcx.def_span(item.owner_id.def_id), SupertraitAsDerefTarget { - t, - target_principal, - label, - }); + let label = impl_ + .items + .iter() + .find_map(|i| (i.ident.name == sym::Target).then_some(i.span)) + .map(|label| SupertraitAsDerefTargetLabel { label }); + cx.emit_spanned_lint( + DEREF_INTO_DYN_SUPERTRAIT, + cx.tcx.def_span(item.owner_id.def_id), + SupertraitAsDerefTarget { t, target_principal, label }, + ); } } } diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs index 467f53d445c..390a1620a2a 100644 --- a/compiler/rustc_lint/src/drop_forget_useless.rs +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -149,18 +149,37 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); match fn_name { sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => { - cx.emit_spanned_lint(DROPPING_REFERENCES, expr.span, DropRefDiag { arg_ty, label: arg.span }); - }, + cx.emit_spanned_lint( + DROPPING_REFERENCES, + expr.span, + DropRefDiag { arg_ty, label: arg.span }, + ); + } sym::mem_forget if arg_ty.is_ref() => { - cx.emit_spanned_lint(FORGETTING_REFERENCES, expr.span, ForgetRefDiag { arg_ty, label: arg.span }); - }, + cx.emit_spanned_lint( + FORGETTING_REFERENCES, + expr.span, + ForgetRefDiag { arg_ty, label: arg.span }, + ); + } sym::mem_drop if is_copy && !drop_is_single_call_in_arm => { - cx.emit_spanned_lint(DROPPING_COPY_TYPES, expr.span, DropCopyDiag { arg_ty, label: arg.span }); + cx.emit_spanned_lint( + DROPPING_COPY_TYPES, + expr.span, + DropCopyDiag { arg_ty, label: arg.span }, + ); } sym::mem_forget if is_copy => { - cx.emit_spanned_lint(FORGETTING_COPY_TYPES, expr.span, ForgetCopyDiag { arg_ty, label: arg.span }); + cx.emit_spanned_lint( + FORGETTING_COPY_TYPES, + expr.span, + ForgetCopyDiag { arg_ty, label: arg.span }, + ); } - sym::mem_drop if let ty::Adt(adt, _) = arg_ty.kind() && adt.is_manually_drop() => { + sym::mem_drop + if let ty::Adt(adt, _) = arg_ty.kind() + && adt.is_manually_drop() => + { cx.emit_spanned_lint( UNDROPPED_MANUALLY_DROPS, expr.span, @@ -169,9 +188,9 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { label: arg.span, suggestion: UndroppedManuallyDropsSuggestion { start_span: arg.span.shrink_to_lo(), - end_span: arg.span.shrink_to_hi() - } - } + end_span: arg.span.shrink_to_hi(), + }, + }, ); } _ => return, diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs index b1266b58a61..740c90757e6 100644 --- a/compiler/rustc_lint/src/expect.rs +++ b/compiler/rustc_lint/src/expect.rs @@ -11,7 +11,7 @@ pub(crate) fn provide(providers: &mut Providers) { } fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option<Symbol>) { - if !tcx.features().enabled(sym::lint_reasons) { + if !tcx.features().active(sym::lint_reasons) { return; } diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index c299e38842a..c8ec0458ba4 100644 --- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs +++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs @@ -59,13 +59,20 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles { _ => return, }; - let sub = if let Some(recv) = extract_iterator_next_call(cx, arg) + let sub = if let Some(recv) = extract_iterator_next_call(cx, arg) && let Ok(recv_snip) = cx.sess().source_map().span_to_snippet(recv.span) - { - ForLoopsOverFalliblesLoopSub::RemoveNext { suggestion: recv.span.between(arg.span.shrink_to_hi()), recv_snip } - } else { - ForLoopsOverFalliblesLoopSub::UseWhileLet { start_span: expr.span.with_hi(pat.span.lo()), end_span: pat.span.between(arg.span), var } - } ; + { + ForLoopsOverFalliblesLoopSub::RemoveNext { + suggestion: recv.span.between(arg.span.shrink_to_hi()), + recv_snip, + } + } else { + ForLoopsOverFalliblesLoopSub::UseWhileLet { + start_span: expr.span.with_hi(pat.span.lo()), + end_span: pat.span.between(arg.span), + var, + } + }; let question_mark = suggest_question_mark(cx, adt, args, expr.span) .then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg.span.shrink_to_hi() }); let suggestion = ForLoopsOverFalliblesSuggestion { @@ -84,13 +91,13 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles { fn extract_for_loop<'tcx>(expr: &Expr<'tcx>) -> Option<(&'tcx Pat<'tcx>, &'tcx Expr<'tcx>)> { if let hir::ExprKind::DropTemps(e) = expr.kind - && let hir::ExprKind::Match(iterexpr, [arm], hir::MatchSource::ForLoopDesugar) = e.kind - && let hir::ExprKind::Call(_, [arg]) = iterexpr.kind - && let hir::ExprKind::Loop(block, ..) = arm.body.kind - && let [stmt] = block.stmts - && let hir::StmtKind::Expr(e) = stmt.kind - && let hir::ExprKind::Match(_, [_, some_arm], _) = e.kind - && let hir::PatKind::Struct(_, [field], _) = some_arm.pat.kind + && let hir::ExprKind::Match(iterexpr, [arm], hir::MatchSource::ForLoopDesugar) = e.kind + && let hir::ExprKind::Call(_, [arg]) = iterexpr.kind + && let hir::ExprKind::Loop(block, ..) = arm.body.kind + && let [stmt] = block.stmts + && let hir::StmtKind::Expr(e) = stmt.kind + && let hir::ExprKind::Match(_, [_, some_arm], _) = e.kind + && let hir::PatKind::Struct(_, [field], _) = some_arm.pat.kind { Some((field.pat, arg)) } else { @@ -104,11 +111,11 @@ fn extract_iterator_next_call<'tcx>( ) -> Option<&'tcx Expr<'tcx>> { // This won't work for `Iterator::next(iter)`, is this an issue? if let hir::ExprKind::MethodCall(_, recv, _, _) = expr.kind - && cx.typeck_results().type_dependent_def_id(expr.hir_id) == cx.tcx.lang_items().next_fn() + && cx.typeck_results().type_dependent_def_id(expr.hir_id) == cx.tcx.lang_items().next_fn() { Some(recv) } else { - return None + return None; } } diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 4b803621f71..fc2d3d0a254 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -62,13 +62,11 @@ fn typeck_results_of_method_fn<'tcx>( if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) => { Some((segment.ident.span, def_id, cx.typeck_results().node_args(expr.hir_id))) - }, - _ => { - match cx.typeck_results().node_type(expr.hir_id).kind() { - &ty::FnDef(def_id, args) => Some((expr.span, def_id, args)), - _ => None, - } } + _ => match cx.typeck_results().node_type(expr.hir_id).kind() { + &ty::FnDef(def_id, args) => Some((expr.span, def_id, args)), + _ => None, + }, } } @@ -134,14 +132,11 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { _: rustc_hir::HirId, ) { if let Some(segment) = path.segments.iter().nth_back(1) - && lint_ty_kind_usage(cx, &segment.res) + && lint_ty_kind_usage(cx, &segment.res) { - let span = path.span.with_hi( - segment.args.map_or(segment.ident.span, |a| a.span_ext).hi() - ); - cx.emit_spanned_lint(USAGE_OF_TY_TYKIND, path.span, TykindKind { - suggestion: span, - }); + let span = + path.span.with_hi(segment.args.map_or(segment.ident.span, |a| a.span_ext).hi()); + cx.emit_spanned_lint(USAGE_OF_TY_TYKIND, path.span, TykindKind { suggestion: span }); } } @@ -166,10 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { None } } - Some(Node::Expr(Expr { - kind: ExprKind::Path(qpath), - .. - })) => { + Some(Node::Expr(Expr { kind: ExprKind::Path(qpath), .. })) => { if let QPath::TypeRelative(qpath_ty, ..) = qpath && qpath_ty.hir_id == ty.hir_id { @@ -180,10 +172,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { } // Can't unify these two branches because qpath below is `&&` and above is `&` // and `A | B` paths don't play well together with adjustments, apparently. - Some(Node::Expr(Expr { - kind: ExprKind::Struct(qpath, ..), - .. - })) => { + Some(Node::Expr(Expr { kind: ExprKind::Struct(qpath, ..), .. })) => { if let QPath::TypeRelative(qpath_ty, ..) = qpath && qpath_ty.hir_id == ty.hir_id { @@ -192,22 +181,28 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { None } } - _ => None + _ => None, }; match span { Some(span) => { - cx.emit_spanned_lint(USAGE_OF_TY_TYKIND, path.span, TykindKind { - suggestion: span, - }); - }, + cx.emit_spanned_lint( + USAGE_OF_TY_TYKIND, + path.span, + TykindKind { suggestion: span }, + ); + } None => cx.emit_spanned_lint(USAGE_OF_TY_TYKIND, path.span, TykindDiag), } - } else if !ty.span.from_expansion() && path.segments.len() > 1 && let Some(ty) = is_ty_or_ty_ctxt(cx, &path) { - cx.emit_spanned_lint(USAGE_OF_QUALIFIED_TY, path.span, TyQualified { - ty, - suggestion: path.span, - }); + } else if !ty.span.from_expansion() + && path.segments.len() > 1 + && let Some(ty) = is_ty_or_ty_ctxt(cx, &path) + { + cx.emit_spanned_lint( + USAGE_OF_QUALIFIED_TY, + path.span, + TyQualified { ty, suggestion: path.span }, + ); } } _ => {} @@ -398,11 +393,11 @@ impl LateLintPass<'_> for Diagnostics { } debug!(?parent); - if let Node::Item(Item { kind: ItemKind::Impl(impl_), .. }) = parent && - let Impl { of_trait: Some(of_trait), .. } = impl_ && - let Some(def_id) = of_trait.trait_def_id() && - let Some(name) = cx.tcx.get_diagnostic_name(def_id) && - matches!(name, sym::IntoDiagnostic | sym::AddToDiagnostic | sym::DecorateLint) + if let Node::Item(Item { kind: ItemKind::Impl(impl_), .. }) = parent + && let Impl { of_trait: Some(of_trait), .. } = impl_ + && let Some(def_id) = of_trait.trait_def_id() + && let Some(name) = cx.tcx.get_diagnostic_name(def_id) + && matches!(name, sym::IntoDiagnostic | sym::AddToDiagnostic | sym::DecorateLint) { found_impl = true; break; @@ -416,9 +411,9 @@ impl LateLintPass<'_> for Diagnostics { let mut found_diagnostic_message = false; for ty in args.types() { debug!(?ty); - if let Some(adt_def) = ty.ty_adt_def() && - let Some(name) = cx.tcx.get_diagnostic_name(adt_def.did()) && - matches!(name, sym::DiagnosticMessage | sym::SubdiagnosticMessage) + if let Some(adt_def) = ty.ty_adt_def() + && let Some(name) = cx.tcx.get_diagnostic_name(adt_def.did()) + && matches!(name, sym::DiagnosticMessage | sym::SubdiagnosticMessage) { found_diagnostic_message = true; break; @@ -486,8 +481,9 @@ impl EarlyLintPass for Diagnostics { } }; if let ast::ExprKind::Lit(lit) = arg.kind - && let ast::token::LitKind::Str = lit.kind { - true + && let ast::token::LitKind::Str = lit.kind + { + true } else { false } @@ -524,16 +520,19 @@ impl LateLintPass<'_> for BadOptAccess { } for field in adt_def.all_fields() { - if field.name == target.name && - let Some(attr) = cx.tcx.get_attr(field.did, sym::rustc_lint_opt_deny_field_access) && - let Some(items) = attr.meta_item_list() && - let Some(item) = items.first() && - let Some(lit) = item.lit() && - let ast::LitKind::Str(val, _) = lit.kind + if field.name == target.name + && let Some(attr) = + cx.tcx.get_attr(field.did, sym::rustc_lint_opt_deny_field_access) + && let Some(items) = attr.meta_item_list() + && let Some(item) = items.first() + && let Some(lit) = item.lit() + && let ast::LitKind::Str(val, _) = lit.kind { - cx.emit_spanned_lint(BAD_OPT_ACCESS, expr.span, BadOptAccessDiag { - msg: val.as_str(), - }); + cx.emit_spanned_lint( + BAD_OPT_ACCESS, + expr.span, + BadOptAccessDiag { msg: val.as_str() }, + ); } } } diff --git a/compiler/rustc_lint/src/invalid_from_utf8.rs b/compiler/rustc_lint/src/invalid_from_utf8.rs index e398059ade9..0b91b77a9f2 100644 --- a/compiler/rustc_lint/src/invalid_from_utf8.rs +++ b/compiler/rustc_lint/src/invalid_from_utf8.rs @@ -64,8 +64,13 @@ impl<'tcx> LateLintPass<'tcx> for InvalidFromUtf8 { && let ExprKind::Path(ref qpath) = path.kind && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() && let Some(diag_item) = cx.tcx.get_diagnostic_name(def_id) - && [sym::str_from_utf8, sym::str_from_utf8_mut, - sym::str_from_utf8_unchecked, sym::str_from_utf8_unchecked_mut].contains(&diag_item) + && [ + sym::str_from_utf8, + sym::str_from_utf8_mut, + sym::str_from_utf8_unchecked, + sym::str_from_utf8_unchecked_mut, + ] + .contains(&diag_item) { let lint = |label, utf8_error: Utf8Error| { let method = diag_item.as_str().strip_prefix("str_").unwrap(); @@ -74,13 +79,17 @@ impl<'tcx> LateLintPass<'tcx> for InvalidFromUtf8 { let is_unchecked_variant = diag_item.as_str().contains("unchecked"); cx.emit_spanned_lint( - if is_unchecked_variant { INVALID_FROM_UTF8_UNCHECKED } else { INVALID_FROM_UTF8 }, + if is_unchecked_variant { + INVALID_FROM_UTF8_UNCHECKED + } else { + INVALID_FROM_UTF8 + }, expr.span, if is_unchecked_variant { InvalidFromUtf8Diag::Unchecked { method, valid_up_to, label } } else { InvalidFromUtf8Diag::Checked { method, valid_up_to, label } - } + }, ) }; @@ -95,18 +104,19 @@ impl<'tcx> LateLintPass<'tcx> for InvalidFromUtf8 { { lint(init.span, utf8_error); } - }, + } ExprKind::Array(args) => { - let elements = args.iter().map(|e|{ - match &e.kind { + let elements = args + .iter() + .map(|e| match &e.kind { ExprKind::Lit(Spanned { node: lit, .. }) => match lit { LitKind::Byte(b) => Some(*b), LitKind::Int(b, _) => Some(*b as u8), - _ => None - } - _ => None - } - }).collect::<Option<Vec<_>>>(); + _ => None, + }, + _ => None, + }) + .collect::<Option<Vec<_>>>(); if let Some(elements) = elements && let Err(utf8_error) = std::str::from_utf8(&elements) diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index ba521b969ce..0d20f6232db 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -634,7 +634,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { /// diagnostic with no change to `specs`. fn insert_spec(&mut self, id: LintId, (mut level, src): LevelAndSource) { let (old_level, old_src) = self.provider.get_lint_level(id.lint, &self.sess); - if let Level::Expect(id) = &mut level && let LintExpectationId::Stable { .. } = id { + if let Level::Expect(id) = &mut level + && let LintExpectationId::Stable { .. } = id + { *id = id.normalize(); } // Setting to a non-forbid level is an error if the lint previously had @@ -706,7 +708,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { // The lint `unfulfilled_lint_expectations` can't be expected, as it would suppress itself. // Handling expectations of this lint would add additional complexity with little to no // benefit. The expect level for this lint will therefore be ignored. - if let Level::Expect(_) = level && id == LintId::of(UNFULFILLED_LINT_EXPECTATIONS) { + if let Level::Expect(_) = level + && id == LintId::of(UNFULFILLED_LINT_EXPECTATIONS) + { return; } @@ -747,8 +751,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { None => continue, // This is the only lint level with a `LintExpectationId` that can be created from an attribute Some(Level::Expect(unstable_id)) if let Some(hir_id) = source_hir_id => { - let LintExpectationId::Unstable { attr_id, lint_index } = unstable_id - else { bug!("stable id Level::from_attr") }; + let LintExpectationId::Unstable { attr_id, lint_index } = unstable_id else { + bug!("stable id Level::from_attr") + }; let stable_id = LintExpectationId::Stable { hir_id, @@ -1057,7 +1062,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { #[track_caller] fn check_gated_lint(&self, lint_id: LintId, span: Span, lint_from_cli: bool) -> bool { if let Some(feature) = lint_id.lint.feature_gate { - if !self.features.enabled(feature) { + if !self.features.active(feature) { let lint = builtin::UNKNOWN_LINTS; let (level, src) = self.lint_level(builtin::UNKNOWN_LINTS); struct_lint_level( diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs index 84558ee1f02..dfefaf82fd7 100644 --- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -42,18 +42,17 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable { if let hir::ItemKind::Trait(_, _, _, _, _) = item.kind && cx.tcx.object_safety_violations(def_id).is_empty() { - let direct_super_traits_iter = cx.tcx - .super_predicates_of(def_id) - .predicates - .into_iter() - .filter_map(|(pred, _)| pred.as_trait_clause()); + let direct_super_traits_iter = cx + .tcx + .super_predicates_of(def_id) + .predicates + .into_iter() + .filter_map(|(pred, _)| pred.as_trait_clause()); if direct_super_traits_iter.count() > 1 { cx.emit_spanned_lint( MULTIPLE_SUPERTRAIT_UPCASTABLE, cx.tcx.def_span(def_id), - crate::lints::MultipleSupertraitUpcastable { - ident: item.ident - }, + crate::lints::MultipleSupertraitUpcastable { ident: item.ident }, ); } } diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 145de494835..66dc726df89 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -511,7 +511,9 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { } fn check_impl_item(&mut self, cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) { - if let hir::ImplItemKind::Const(..) = ii.kind && !assoc_item_in_trait_impl(cx, ii) { + if let hir::ImplItemKind::Const(..) = ii.kind + && !assoc_item_in_trait_impl(cx, ii) + { NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ii.ident); } } diff --git a/compiler/rustc_lint/src/ptr_nulls.rs b/compiler/rustc_lint/src/ptr_nulls.rs index 0de72d8d3db..4ac8a5ceb85 100644 --- a/compiler/rustc_lint/src/ptr_nulls.rs +++ b/compiler/rustc_lint/src/ptr_nulls.rs @@ -46,22 +46,26 @@ fn incorrect_check<'a, 'tcx: 'a>( if let ExprKind::MethodCall(_, _expr, [], _) = e.kind && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) && cx.tcx.has_attr(def_id, sym::rustc_never_returns_null_ptr) - && let Some(fn_name) = cx.tcx.opt_item_ident(def_id) { + && let Some(fn_name) = cx.tcx.opt_item_ident(def_id) + { return Some(PtrNullChecksDiag::FnRet { fn_name }); } else if let ExprKind::Call(path, _args) = e.kind && let ExprKind::Path(ref qpath) = path.kind && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() && cx.tcx.has_attr(def_id, sym::rustc_never_returns_null_ptr) - && let Some(fn_name) = cx.tcx.opt_item_ident(def_id) { + && let Some(fn_name) = cx.tcx.opt_item_ident(def_id) + { return Some(PtrNullChecksDiag::FnRet { fn_name }); } e = if let ExprKind::Cast(expr, t) = e.kind - && let TyKind::Ptr(_) = t.kind { + && let TyKind::Ptr(_) = t.kind + { had_at_least_one_cast = true; expr } else if let ExprKind::MethodCall(_, expr, [], _) = e.kind && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) - && matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::ptr_cast | sym::ptr_cast_mut)) { + && matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::ptr_cast | sym::ptr_cast_mut)) + { had_at_least_one_cast = true; expr } else if had_at_least_one_cast { @@ -127,10 +131,11 @@ impl<'tcx> LateLintPass<'tcx> for PtrNullChecks { // (fn_ptr as *<const/mut> <ty>) == (0 as <ty>) ExprKind::Cast(cast_expr, _) if let ExprKind::Lit(spanned) = cast_expr.kind - && let LitKind::Int(v, _) = spanned.node && v == 0 => + && let LitKind::Int(v, _) = spanned.node + && v == 0 => { cx.emit_spanned_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag) - }, + } // Catching: // (fn_ptr as *<const/mut> <ty>) == std::ptr::null() @@ -141,9 +146,9 @@ impl<'tcx> LateLintPass<'tcx> for PtrNullChecks { && (diag_item == sym::ptr_null || diag_item == sym::ptr_null_mut) => { cx.emit_spanned_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag) - }, + } - _ => {}, + _ => {} } } _ => {} diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index 0c52fbaf78c..d44691b5e9b 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -93,7 +93,10 @@ fn is_operation_we_care_about<'tcx>( if let ExprKind::Call(path, [arg_ptr, _arg_val]) = e.kind && let ExprKind::Path(ref qpath) = path.kind && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() - && matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::ptr_write | sym::ptr_write_volatile | sym::ptr_write_unaligned)) + && matches!( + cx.tcx.get_diagnostic_name(def_id), + Some(sym::ptr_write | sym::ptr_write_volatile | sym::ptr_write_unaligned) + ) { Some((true, arg_ptr)) } else { diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index d252f651c78..f89b63e6f9f 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -163,8 +163,10 @@ fn lint_overflowing_range_endpoint<'tcx>( ty: &str, ) -> bool { // Look past casts to support cases like `0..256 as u8` - let (expr, lit_span) = if let Node::Expr(par_expr) = cx.tcx.hir().get(cx.tcx.hir().parent_id(expr.hir_id)) - && let ExprKind::Cast(_, _) = par_expr.kind { + let (expr, lit_span) = if let Node::Expr(par_expr) = + cx.tcx.hir().get(cx.tcx.hir().parent_id(expr.hir_id)) + && let ExprKind::Cast(_, _) = par_expr.kind + { (par_expr, expr.span) } else { (expr, expr.span) @@ -580,8 +582,8 @@ fn lint_nan<'tcx>( ) -> InvalidNanComparisons { // FIXME(#72505): This suggestion can be restored if `f{32,64}::is_nan` is made const. let suggestion = (!cx.tcx.hir().is_inside_const_context(e.hir_id)).then(|| { - if let Some(l_span) = l.span.find_ancestor_inside(e.span) && - let Some(r_span) = r.span.find_ancestor_inside(e.span) + if let Some(l_span) = l.span.find_ancestor_inside(e.span) + && let Some(r_span) = r.span.find_ancestor_inside(e.span) { f(l_span, r_span) } else { @@ -1293,11 +1295,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { CItemKind::Definition => "fn", }; let span_note = if let ty::Adt(def, _) = ty.kind() - && let Some(sp) = self.cx.tcx.hir().span_if_local(def.did()) { - Some(sp) - } else { - None - }; + && let Some(sp) = self.cx.tcx.hir().span_if_local(def.did()) + { + Some(sp) + } else { + None + }; self.cx.emit_spanned_lint( lint, sp, @@ -1460,7 +1463,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { type BreakTy = Ty<'tcx>; fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { - if let ty::FnPtr(sig) = ty.kind() && !self.visitor.is_internal_abi(sig.abi()) { + if let ty::FnPtr(sig) = ty.kind() + && !self.visitor.is_internal_abi(sig.abi()) + { self.tys.push(ty); } @@ -1734,7 +1739,8 @@ impl InvalidAtomicOrdering { } fn check_atomic_load_store(cx: &LateContext<'_>, expr: &Expr<'_>) { - if let Some((method, args)) = Self::inherent_atomic_method_call(cx, expr, &[sym::load, sym::store]) + if let Some((method, args)) = + Self::inherent_atomic_method_call(cx, expr, &[sym::load, sym::store]) && let Some((ordering_arg, invalid_ordering)) = match method { sym::load => Some((&args[0], sym::Release)), sym::store => Some((&args[1], sym::Acquire)), @@ -1744,9 +1750,17 @@ impl InvalidAtomicOrdering { && (ordering == invalid_ordering || ordering == sym::AcqRel) { if method == sym::load { - cx.emit_spanned_lint(INVALID_ATOMIC_ORDERING, ordering_arg.span, AtomicOrderingLoad); + cx.emit_spanned_lint( + INVALID_ATOMIC_ORDERING, + ordering_arg.span, + AtomicOrderingLoad, + ); } else { - cx.emit_spanned_lint(INVALID_ATOMIC_ORDERING, ordering_arg.span, AtomicOrderingStore); + cx.emit_spanned_lint( + INVALID_ATOMIC_ORDERING, + ordering_arg.span, + AtomicOrderingStore, + ); }; } } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index d5beff4f101..65de7e10272 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -353,7 +353,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { ty::Generator(def_id, ..) => { // async fn should be treated as "implementor of `Future`" let must_use = if cx.tcx.generator_is_async(def_id) { - let def_id = cx.tcx.lang_items().future_trait().unwrap(); + let def_id = cx.tcx.lang_items().future_trait()?; is_def_must_use(cx, def_id, span) .map(|inner| MustUsePath::Opaque(Box::new(inner))) } else { @@ -782,21 +782,23 @@ trait UnusedDelimLint { }; let suggestion = spans.map(|(lo, hi)| { let sm = cx.sess().source_map(); - let lo_replace = - if (keep_space.0 || is_kw) && - let Ok(snip) = sm.span_to_prev_source(lo) && !snip.ends_with(' ') { - " " - } else { - "" - }; + let lo_replace = if (keep_space.0 || is_kw) + && let Ok(snip) = sm.span_to_prev_source(lo) + && !snip.ends_with(' ') + { + " " + } else { + "" + }; - let hi_replace = - if keep_space.1 && - let Ok(snip) = sm.span_to_next_source(hi) && !snip.starts_with(' ') { - " " - } else { - "" - }; + let hi_replace = if keep_space.1 + && let Ok(snip) = sm.span_to_next_source(hi) + && !snip.starts_with(' ') + { + " " + } else { + "" + }; UnusedDelimSuggestion { start_span: lo, start_replace: lo_replace, @@ -1056,10 +1058,10 @@ impl UnusedParens { impl EarlyLintPass for UnusedParens { #[inline] fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { - if let ExprKind::Binary(op, lhs, _rhs) = &e.kind && - (op.node == ast::BinOpKind::Lt || op.node == ast::BinOpKind::Shl) && - let ExprKind::Cast(_expr, ty) = &lhs.kind && - let ast::TyKind::Paren(_) = &ty.kind + if let ExprKind::Binary(op, lhs, _rhs) = &e.kind + && (op.node == ast::BinOpKind::Lt || op.node == ast::BinOpKind::Shl) + && let ExprKind::Cast(_expr, ty) = &lhs.kind + && let ast::TyKind::Paren(_) = &ty.kind { self.parens_in_cast_in_lt.push(ty.id); } @@ -1111,13 +1113,19 @@ impl EarlyLintPass for UnusedParens { } fn check_expr_post(&mut self, _cx: &EarlyContext<'_>, e: &ast::Expr) { - if let ExprKind::Binary(op, lhs, _rhs) = &e.kind && - (op.node == ast::BinOpKind::Lt || op.node == ast::BinOpKind::Shl) && - let ExprKind::Cast(_expr, ty) = &lhs.kind && - let ast::TyKind::Paren(_) = &ty.kind + if let ExprKind::Binary(op, lhs, _rhs) = &e.kind + && (op.node == ast::BinOpKind::Lt || op.node == ast::BinOpKind::Shl) + && let ExprKind::Cast(_expr, ty) = &lhs.kind + && let ast::TyKind::Paren(_) = &ty.kind { - let id = self.parens_in_cast_in_lt.pop().expect("check_expr and check_expr_post must balance"); - assert_eq!(id, ty.id, "check_expr, check_ty, and check_expr_post are called, in that order, by the visitor"); + let id = self + .parens_in_cast_in_lt + .pop() + .expect("check_expr and check_expr_post must balance"); + assert_eq!( + id, ty.id, + "check_expr, check_ty, and check_expr_post are called, in that order, by the visitor" + ); } } @@ -1161,8 +1169,8 @@ impl EarlyLintPass for UnusedParens { } fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) { - if let ast::TyKind::Paren(_) = ty.kind && - Some(&ty.id) == self.parens_in_cast_in_lt.last() + if let ast::TyKind::Paren(_) = ty.kind + && Some(&ty.id) == self.parens_in_cast_in_lt.last() { return; } @@ -1206,13 +1214,14 @@ impl EarlyLintPass for UnusedParens { fn enter_where_predicate(&mut self, _: &EarlyContext<'_>, pred: &ast::WherePredicate) { use rustc_ast::{WhereBoundPredicate, WherePredicate}; if let WherePredicate::BoundPredicate(WhereBoundPredicate { - bounded_ty, - bound_generic_params, - .. - }) = pred && - let ast::TyKind::Paren(_) = &bounded_ty.kind && - bound_generic_params.is_empty() { - self.with_self_ty_parens = true; + bounded_ty, + bound_generic_params, + .. + }) = pred + && let ast::TyKind::Paren(_) = &bounded_ty.kind + && bound_generic_params.is_empty() + { + self.with_self_ty_parens = true; } } @@ -1516,9 +1525,8 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAllocation { match e.kind { hir::ExprKind::Call(path_expr, [_]) if let hir::ExprKind::Path(qpath) = &path_expr.kind - && let Some(did) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id() - && cx.tcx.is_diagnostic_item(sym::box_new, did) - => {} + && let Some(did) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id() + && cx.tcx.is_diagnostic_item(sym::box_new, did) => {} _ => return, } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 0e242c1febd..96a98393fb2 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4534,7 +4534,6 @@ declare_lint! { /// ### Example /// /// ```rust,compile_fail - /// #![feature(return_position_impl_trait_in_trait)] /// #![deny(refining_impl_trait)] /// /// use std::fmt::Display; diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 04b7c5feebe..1a8174bfd96 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -42,19 +42,20 @@ impl<'a> DiagnosticDerive<'a> { let init = match builder.slug.value_ref() { None => { span_err(builder.span, "diagnostic slug not specified") - .help("specify the slug as the first argument to the `#[diag(...)]` \ - attribute, such as `#[diag(hir_analysis_example_error)]`") + .help( + "specify the slug as the first argument to the `#[diag(...)]` \ + attribute, such as `#[diag(hir_analysis_example_error)]`", + ) .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); } - Some(slug) if let Some( Mismatch { slug_name, crate_name, slug_prefix }) = Mismatch::check(slug) => { + Some(slug) + if let Some(Mismatch { slug_name, crate_name, slug_prefix }) = + Mismatch::check(slug) => + { span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match") - .note(format!( - "slug is `{slug_name}` but the crate name is `{crate_name}`" - )) - .help(format!( - "expected a slug starting with `{slug_prefix}_...`" - )) + .note(format!("slug is `{slug_name}` but the crate name is `{crate_name}`")) + .help(format!("expected a slug starting with `{slug_prefix}_...`")) .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); } @@ -141,19 +142,20 @@ impl<'a> LintDiagnosticDerive<'a> { match builder.slug.value_ref() { None => { span_err(builder.span, "diagnostic slug not specified") - .help("specify the slug as the first argument to the attribute, such as \ - `#[diag(compiletest_example)]`") + .help( + "specify the slug as the first argument to the attribute, such as \ + `#[diag(compiletest_example)]`", + ) .emit(); DiagnosticDeriveError::ErrorHandled.to_compile_error() } - Some(slug) if let Some( Mismatch { slug_name, crate_name, slug_prefix }) = Mismatch::check(slug) => { + Some(slug) + if let Some(Mismatch { slug_name, crate_name, slug_prefix }) = + Mismatch::check(slug) => + { span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match") - .note(format!( - "slug is `{slug_name}` but the crate name is `{crate_name}`" - )) - .help(format!( - "expected a slug starting with `{slug_prefix}_...`" - )) + .note(format!("slug is `{slug_name}` but the crate name is `{crate_name}`")) + .help(format!("expected a slug starting with `{slug_prefix}_...`")) .emit(); DiagnosticDeriveError::ErrorHandled.to_compile_error() } diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index 877e9745054..877271ff077 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -577,7 +577,9 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { } } _ => { - if let Some(span) = span_field && !no_span { + if let Some(span) = span_field + && !no_span + { quote! { #diag.#name(#span, #message); } } else { quote! { #diag.#name(#message); } diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index 783d35ac7e6..cb057cd39e2 100644 --- a/compiler/rustc_metadata/src/dependency_format.rs +++ b/compiler/rustc_metadata/src/dependency_format.rs @@ -396,11 +396,14 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) { continue; } - if let Some(found_strategy) = tcx.required_panic_strategy(cnum) && desired_strategy != found_strategy { + if let Some(found_strategy) = tcx.required_panic_strategy(cnum) + && desired_strategy != found_strategy + { sess.emit_err(RequiredPanicStrategy { crate_name: tcx.crate_name(cnum), found_strategy, - desired_strategy}); + desired_strategy, + }); } let found_drop_strategy = tcx.panic_in_drop_strategy(cnum); diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 91220629fb6..59b35a6406d 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -419,7 +419,9 @@ impl<'a> MissingNativeLibrary<'a> { // if it looks like the user has provided a complete filename rather just the bare lib name, // then provide a note that they might want to try trimming the name let suggested_name = if !verbatim { - if let Some(libname) = libname.strip_prefix("lib") && let Some(libname) = libname.strip_suffix(".a") { + if let Some(libname) = libname.strip_prefix("lib") + && let Some(libname) = libname.strip_suffix(".a") + { // this is a unix style filename so trim prefix & suffix Some(libname) } else if let Some(libname) = libname.strip_suffix(".lib") { diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 098c411c8d6..ab135851b8e 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -383,7 +383,9 @@ impl<'tcx> Collector<'tcx> { // First, check for errors let mut renames = FxHashSet::default(); for lib in &self.tcx.sess.opts.libs { - if let NativeLibKind::Framework { .. } = lib.kind && !self.tcx.sess.target.is_like_osx { + if let NativeLibKind::Framework { .. } = lib.kind + && !self.tcx.sess.target.is_like_osx + { // Cannot check this when parsing options because the target is not yet available. self.tcx.sess.emit_err(errors::LibFrameworkApple); } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index b189e79df56..846f8d25025 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1692,17 +1692,22 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { // `try_to_translate_virtual_to_real` don't have to worry about how the // compiler is bootstrapped. if let Some(virtual_dir) = &sess.opts.unstable_opts.simulate_remapped_rust_src_base - && let Some(real_dir) = &sess.opts.real_rust_source_base_dir - && let rustc_span::FileName::Real(ref mut old_name) = name { + && let Some(real_dir) = &sess.opts.real_rust_source_base_dir + && let rustc_span::FileName::Real(ref mut old_name) = name + { let relative_path = match old_name { - rustc_span::RealFileName::LocalPath(local) => local.strip_prefix(real_dir).ok(), + rustc_span::RealFileName::LocalPath(local) => { + local.strip_prefix(real_dir).ok() + } rustc_span::RealFileName::Remapped { virtual_name, .. } => { - option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").and_then(|virtual_dir| virtual_name.strip_prefix(virtual_dir).ok()) + option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR") + .and_then(|virtual_dir| virtual_name.strip_prefix(virtual_dir).ok()) } }; debug!(?relative_path, ?virtual_dir, "simulate_remapped_rust_src_base"); for subdir in ["library", "compiler"] { - if let Some(rest) = relative_path.and_then(|p| p.strip_prefix(subdir).ok()) { + if let Some(rest) = relative_path.and_then(|p| p.strip_prefix(subdir).ok()) + { *old_name = rustc_span::RealFileName::Remapped { local_path: None, // FIXME: maybe we should preserve this? virtual_name: virtual_dir.join(subdir).join(rest), diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index a4ba943275e..e949e4670e2 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -525,9 +525,17 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // the remapped version -- as is necessary for reproducible builds. let mut source_file = match source_file.name { FileName::Real(ref original_file_name) => { - let adapted_file_name = source_map - .path_mapping() - .to_embeddable_absolute_path(original_file_name.clone(), working_directory); + let adapted_file_name = if self.tcx.sess.should_prefer_remapped_for_codegen() { + source_map.path_mapping().to_embeddable_absolute_path( + original_file_name.clone(), + working_directory, + ) + } else { + source_map.path_mapping().to_local_embeddable_absolute_path( + original_file_name.clone(), + working_directory, + ) + }; if adapted_file_name != *original_file_name { let mut adapted: SourceFile = (**source_file).clone(); @@ -1155,7 +1163,8 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> DefKind::OpaqueTy => { let origin = tcx.opaque_type_origin(def_id); - if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin + if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) + | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin && let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id) && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn() { @@ -1357,7 +1366,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if should_encode_expn_that_defined(def_kind) { record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id)); } - if should_encode_span(def_kind) && let Some(ident_span) = tcx.def_ident_span(def_id) { + if should_encode_span(def_kind) + && let Some(ident_span) = tcx.def_ident_span(def_id) + { record!(self.tables.def_ident_span[def_id] <- ident_span); } if def_kind.has_codegen_attrs() { @@ -1958,8 +1969,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record!(self.tables.impl_trait_ref[def_id] <- trait_ref); let trait_ref = trait_ref.instantiate_identity(); - let simplified_self_ty = - fast_reject::simplify_type(self.tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey); + let simplified_self_ty = fast_reject::simplify_type( + self.tcx, + trait_ref.self_ty(), + TreatParams::AsCandidateKey, + ); fx_hash_map .entry(trait_ref.def_id) .or_default() @@ -2372,8 +2386,9 @@ pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: hir::BodyId) -> String { let classification = classify(value); if classification == Literal - && !value.span.from_expansion() - && let Ok(snippet) = tcx.sess.source_map().span_to_snippet(value.span) { + && !value.span.from_expansion() + && let Ok(snippet) = tcx.sess.source_map().span_to_snippet(value.span) + { // For literals, we avoid invoking the pretty-printer and use the source snippet instead to // preserve certain stylistic choices the user likely made for the sake legibility like // diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 41beca072bf..c8f3c2a20a6 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -104,7 +104,7 @@ impl CanonicalVarValues<'_> { } else { // It's ok if this region var isn't unique } - }, + } ty::GenericArgKind::Type(ty) => { if let ty::Bound(ty::INNERMOST, bt) = *ty.kind() && var == bt.var diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index 1913421f54c..500536a9e9e 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -244,7 +244,9 @@ impl<Id: Eq + Hash> EffectiveVisibilities<Id> { if !(inherited_effective_vis_at_prev_level == inherited_effective_vis_at_level && level != l) { - calculated_effective_vis = if let Some(max_vis) = max_vis && !max_vis.is_at_least(inherited_effective_vis_at_level, tcx) { + calculated_effective_vis = if let Some(max_vis) = max_vis + && !max_vis.is_at_least(inherited_effective_vis_at_level, tcx) + { max_vis } else { inherited_effective_vis_at_level diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index c66f64dde32..84893b8e627 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -455,7 +455,9 @@ impl<'tcx> TyCtxt<'tcx> { // If this item was previously part of a now-stabilized feature which is still // active (i.e. the user hasn't removed the attribute for the stabilized feature // yet) then allow use of this item. - if let Some(implied_by) = implied_by && self.features().declared(implied_by) { + if let Some(implied_by) = implied_by + && self.features().declared(implied_by) + { return EvalResult::Allow; } diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index c787481bfbe..aded3e495d9 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -32,23 +32,16 @@ pub use init_mask::{InitChunk, InitChunkIter}; pub trait AllocBytes: Clone + fmt::Debug + Eq + PartialEq + Hash + Deref<Target = [u8]> + DerefMut<Target = [u8]> { - /// Adjust the bytes to the specified alignment -- by default, this is a no-op. - fn adjust_to_align(self, _align: Align) -> Self; - /// Create an `AllocBytes` from a slice of `u8`. fn from_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>, _align: Align) -> Self; - /// Create a zeroed `AllocBytes` of the specified size and alignment; - /// call the callback error handler if there is an error in allocating the memory. + /// Create a zeroed `AllocBytes` of the specified size and alignment. + /// Returns `None` if we ran out of memory on the host. fn zeroed(size: Size, _align: Align) -> Option<Self>; } // Default `bytes` for `Allocation` is a `Box<[u8]>`. impl AllocBytes for Box<[u8]> { - fn adjust_to_align(self, _align: Align) -> Self { - self - } - fn from_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>, _align: Align) -> Self { Box::<[u8]>::from(slice.into()) } @@ -299,6 +292,7 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> { } fn uninit_inner<R>(size: Size, align: Align, fail: impl FnOnce() -> R) -> Result<Self, R> { + // We raise an error if we cannot create the allocation on the host. // This results in an error that can happen non-deterministically, since the memory // available to the compiler can change between runs. Normally queries are always // deterministic. However, we can be non-deterministic here because all uses of const @@ -351,10 +345,8 @@ impl<Bytes: AllocBytes> Allocation<AllocId, (), Bytes> { extra: Extra, mut adjust_ptr: impl FnMut(Pointer<AllocId>) -> Result<Pointer<Prov>, Err>, ) -> Result<Allocation<Prov, Extra, Bytes>, Err> { - // Compute new pointer provenance, which also adjusts the bytes, and realign the pointer if - // necessary. - let mut bytes = self.bytes.adjust_to_align(self.align); - + let mut bytes = self.bytes; + // Adjust provenance of pointers stored in this allocation. let mut new_provenance = Vec::with_capacity(self.provenance.ptrs().len()); let ptr_size = cx.data_layout().pointer_size.bytes_usize(); let endian = cx.data_layout().endian; diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs index 0243fc4513a..d504af6b7ea 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs @@ -315,7 +315,9 @@ impl<Prov: Provenance> ProvenanceMap<Prov> { self.ptrs.insert_presorted(dest_ptrs.into()); } if Prov::OFFSET_IS_ADDR { - if let Some(dest_bytes) = copy.dest_bytes && !dest_bytes.is_empty() { + if let Some(dest_bytes) = copy.dest_bytes + && !dest_bytes.is_empty() + { self.bytes.get_or_insert_with(Box::default).insert_presorted(dest_bytes.into()); } } else { diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 9de40b3f974..44b22e2d383 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -216,10 +216,8 @@ pub enum InvalidProgramInfo<'tcx> { } /// Details of why a pointer had to be in-bounds. -#[derive(Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)] +#[derive(Debug, Copy, Clone)] pub enum CheckInAllocMsg { - /// We are dereferencing a pointer (i.e., creating a place). - DerefTest, /// We are access memory. MemoryAccessTest, /// We are doing pointer arithmetic. @@ -230,7 +228,16 @@ pub enum CheckInAllocMsg { InboundsTest, } -#[derive(Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)] +/// Details of which pointer is not aligned. +#[derive(Debug, Copy, Clone)] +pub enum CheckAlignMsg { + /// The accessed pointer did not have proper alignment. + AccessedPtr, + /// The access ocurred with a place that was based on a misaligned pointer. + BasedOn, +} + +#[derive(Debug, Copy, Clone)] pub enum InvalidMetaKind { /// Size of a `[T]` is too big SliceTooBig, @@ -263,6 +270,13 @@ pub struct ScalarSizeMismatch { pub data_size: u64, } +/// Information about a misaligned pointer. +#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] +pub struct Misalignment { + pub has: Align, + pub required: Align, +} + macro_rules! impl_into_diagnostic_arg_through_debug { ($($ty:ty),*$(,)?) => {$( impl IntoDiagnosticArg for $ty { @@ -324,7 +338,7 @@ pub enum UndefinedBehaviorInfo<'tcx> { /// Using an integer as a pointer in the wrong way. DanglingIntPointer(u64, CheckInAllocMsg), /// Used a pointer with bad alignment. - AlignmentCheckFailed { required: Align, has: Align }, + AlignmentCheckFailed(Misalignment, CheckAlignMsg), /// Writing to read-only memory. WriteToReadOnly(AllocId), /// Trying to access the data behind a function pointer. diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index d21f82f04f6..e360fb3eaaf 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -142,11 +142,12 @@ use crate::ty::GenericArgKind; use crate::ty::{self, Instance, Ty, TyCtxt}; pub use self::error::{ - struct_error, BadBytesAccess, CheckInAllocMsg, ErrorHandled, EvalToAllocationRawResult, - EvalToConstValueResult, EvalToValTreeResult, ExpectedKind, InterpError, InterpErrorInfo, - InterpResult, InvalidMetaKind, InvalidProgramInfo, MachineStopType, PointerKind, - ReportedErrorInfo, ResourceExhaustionInfo, ScalarSizeMismatch, UndefinedBehaviorInfo, - UnsupportedOpInfo, ValidationErrorInfo, ValidationErrorKind, + struct_error, BadBytesAccess, CheckAlignMsg, CheckInAllocMsg, ErrorHandled, + EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, ExpectedKind, + InterpError, InterpErrorInfo, InterpResult, InvalidMetaKind, InvalidProgramInfo, + MachineStopType, Misalignment, PointerKind, ReportedErrorInfo, ResourceExhaustionInfo, + ScalarSizeMismatch, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo, + ValidationErrorKind, }; pub use self::value::Scalar; diff --git a/compiler/rustc_middle/src/mir/patch.rs b/compiler/rustc_middle/src/mir/patch.rs index ce2ddec0116..eb4aa9eb95c 100644 --- a/compiler/rustc_middle/src/mir/patch.rs +++ b/compiler/rustc_middle/src/mir/patch.rs @@ -99,7 +99,9 @@ impl<'tcx> MirPatch<'tcx> { } pub fn terminate_block(&mut self, reason: UnwindTerminateReason) -> BasicBlock { - if let Some((cached_bb, cached_reason)) = self.terminate_block && reason == cached_reason { + if let Some((cached_bb, cached_reason)) = self.terminate_block + && reason == cached_reason + { return cached_bb; } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 30fc69caa3b..c7d99648f1e 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -986,18 +986,15 @@ pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>; /// pointee's type. The resulting address is the address that was stored in the pointer. If the /// pointee type is unsized, the pointer additionally stored the value of the metadata. /// -/// Computing a place may cause UB. One possibility is that the pointer used for a `Deref` may not -/// be suitably aligned. Another possibility is that the place is not in bounds, meaning it does not -/// point to an actual allocation. -/// -/// However, if this is actually UB and when the UB kicks in is undecided. This is being discussed -/// in [UCG#319]. The options include that every place must obey those rules, that only some places -/// must obey them, or that places impose no rules of their own. -/// -/// [UCG#319]: https://github.com/rust-lang/unsafe-code-guidelines/issues/319 -/// -/// Rust currently requires that every place obey those two rules. This is checked by Miri and taken -/// advantage of by codegen (via `gep inbounds`). That is possibly subject to change. +/// The "validity invariant" of places is the same as that of raw pointers, meaning that e.g. +/// `*ptr` on a dangling or unaligned pointer is never UB. (Later doing a load/store on that place +/// or turning it into a reference can be UB though!) The only ways for a place computation can +/// cause UB are: +/// - On a `Deref` projection, we do an actual load of the inner place, with all the usual +/// consequences (the inner place must be based on an aligned pointer, it must point to allocated +/// memory, the aliasig model must allow reads, this must not be a data race). +/// - For the projections that perform pointer arithmetic, the offset must in-bounds of an +/// allocation (i.e., the preconditions of `ptr::offset` must be met). #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, HashStable, TypeFoldable, TypeVisitable)] pub struct Place<'tcx> { pub local: Local, diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 08f7434a4a9..67804998a32 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -19,11 +19,12 @@ use rustc_middle::middle::region; use rustc_middle::mir::interpret::AllocId; use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Mutability, UnOp}; use rustc_middle::ty::adjustment::PointerCoercion; -use rustc_middle::ty::GenericArgsRef; -use rustc_middle::ty::{self, AdtDef, FnSig, List, Ty, UpvarArgs}; -use rustc_middle::ty::{CanonicalUserType, CanonicalUserTypeAnnotation}; +use rustc_middle::ty::{ + self, AdtDef, CanonicalUserType, CanonicalUserTypeAnnotation, FnSig, GenericArgsRef, List, Ty, + UpvarArgs, +}; use rustc_span::def_id::LocalDefId; -use rustc_span::{sym, Span, Symbol, DUMMY_SP}; +use rustc_span::{sym, ErrorGuaranteed, Span, Symbol, DUMMY_SP}; use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_target::asm::InlineAsmRegOrRegClass; use std::fmt; @@ -632,7 +633,7 @@ impl<'tcx> Pat<'tcx> { use PatKind::*; match &self.kind { - Wild | Range(..) | Binding { subpattern: None, .. } | Constant { .. } => {} + Wild | Range(..) | Binding { subpattern: None, .. } | Constant { .. } | Error(_) => {} AscribeUserType { subpattern, .. } | Binding { subpattern: Some(subpattern), .. } | Deref { subpattern } => subpattern.walk_(it), @@ -647,6 +648,21 @@ impl<'tcx> Pat<'tcx> { } } + /// Whether the pattern has a `PatKind::Error` nested within. + pub fn pat_error_reported(&self) -> Result<(), ErrorGuaranteed> { + let mut error = None; + self.walk(|pat| { + if let PatKind::Error(e) = pat.kind && error.is_none() { + error = Some(e); + } + error.is_none() + }); + match error { + None => Ok(()), + Some(e) => Err(e), + } + } + /// Walk the pattern in left-to-right order. /// /// If you always want to recurse, prefer this method over `walk`. @@ -771,6 +787,10 @@ pub enum PatKind<'tcx> { Or { pats: Box<[Box<Pat<'tcx>>]>, }, + + /// An error has been encountered during lowering. We probably shouldn't report more lints + /// related to this pattern. + Error(ErrorGuaranteed), } #[derive(Clone, Debug, PartialEq, HashStable, TypeVisitable)] @@ -934,6 +954,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> { } Ok(()) } + PatKind::Error(_) => write!(f, "<error>"), } } } diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index b84e1568884..afb58438519 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -226,7 +226,7 @@ pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<' is_primary: _, name: _, } => visitor.visit_pat(&subpattern), - Binding { .. } | Wild => {} + Binding { .. } | Wild | Error(_) => {} Variant { subpatterns, adt_def: _, args: _, variant_index: _ } | Leaf { subpatterns } => { for subpattern in subpatterns { visitor.visit_pat(&subpattern.pattern); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1ccb81dcb9b..f7bce93fee5 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1126,7 +1126,11 @@ impl<'tcx> TyCtxt<'tcx> { { v.visit_ty(alias_ty); if !v.0.is_empty() { - return Some((v.0, alias_generics.span, alias_generics.span_for_lifetime_suggestion())); + return Some(( + v.0, + alias_generics.span, + alias_generics.span_for_lifetime_suggestion(), + )); } } return None; diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index f03813a459b..49014c60a6d 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -494,7 +494,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsSuggestableVisitor<'tcx> { let parent = self.tcx.parent(def_id); let parent_ty = self.tcx.type_of(parent).instantiate_identity(); if let DefKind::TyAlias | DefKind::AssocTy = self.tcx.def_kind(parent) - && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *parent_ty.kind() + && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = + *parent_ty.kind() && parent_opaque_def_id == def_id { // Okay @@ -577,8 +578,10 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for MakeSuggestableFolder<'tcx> { Alias(Opaque, AliasTy { def_id, .. }) => { let parent = self.tcx.parent(def_id); let parent_ty = self.tcx.type_of(parent).instantiate_identity(); - if let hir::def::DefKind::TyAlias | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent) - && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *parent_ty.kind() + if let hir::def::DefKind::TyAlias | hir::def::DefKind::AssocTy = + self.tcx.def_kind(parent) + && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = + *parent_ty.kind() && parent_opaque_def_id == def_id { t diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 459c8dfb596..0fe1284eed9 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -253,7 +253,13 @@ impl<'tcx> Ty<'tcx> { ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(), ty::Alias(ty::Projection | ty::Inherent, _) => "associated type".into(), ty::Param(p) => format!("type parameter `{p}`").into(), - ty::Alias(ty::Opaque, ..) => if tcx.ty_is_opaque_future(self) { "future".into() } else { "opaque type".into() }, + ty::Alias(ty::Opaque, ..) => { + if tcx.ty_is_opaque_future(self) { + "future".into() + } else { + "opaque type".into() + } + } ty::Error(_) => "type error".into(), _ => { let width = tcx.sess.diagnostic_width(); diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index bccf5e83987..5ef7ee52636 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -868,7 +868,7 @@ where { let metadata = tcx.normalize_erasing_regions( cx.param_env(), - Ty::new_projection(tcx,metadata_def_id, [pointee]), + Ty::new_projection(tcx, metadata_def_id, [pointee]), ); // Map `Metadata = DynMetadata<dyn Trait>` back to a vtable, since it diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 2d7350387ca..e321f0a7b7f 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -319,8 +319,7 @@ pub trait PrettyPrinter<'tcx>: && let DefPathData::TypeNs(_) = key.disambiguated_data.data && Some(*visible_parent) != actual_parent { - this - .tcx() + this.tcx() // FIXME(typed_def_id): Further propagate ModDefId .module_children(ModDefId::new_unchecked(*visible_parent)) .iter() @@ -359,8 +358,14 @@ pub trait PrettyPrinter<'tcx>: // the parent type in the path. For example, `Iterator::Item`. self.write_str(get_local_name(&self, symbol, parent, parent_key).as_str())?; self.write_str("::")?; - } else if let DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::Trait - | DefKind::TyAlias | DefKind::Fn | DefKind::Const | DefKind::Static(_) = kind + } else if let DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Trait + | DefKind::TyAlias + | DefKind::Fn + | DefKind::Const + | DefKind::Static(_) = kind { } else { // If not covered above, like for example items out of `impl` blocks, fallback. @@ -1119,8 +1124,10 @@ pub trait PrettyPrinter<'tcx>: } if self.tcx().features().return_type_notation - && let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) = self.tcx().opt_rpitit_info(def_id) - && let ty::Alias(_, alias_ty) = self.tcx().fn_sig(fn_def_id).skip_binder().output().skip_binder().kind() + && let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) = + self.tcx().opt_rpitit_info(def_id) + && let ty::Alias(_, alias_ty) = + self.tcx().fn_sig(fn_def_id).skip_binder().output().skip_binder().kind() && alias_ty.def_id == def_id { let num_args = self.tcx().generics_of(fn_def_id).count(); @@ -1364,20 +1371,22 @@ pub trait PrettyPrinter<'tcx>: // cause printing to enter an infinite recursion if the anon const is in the self type i.e. // `impl<T: Default> Default for [T; 32 - 1 - 1 - 1] {` // where we would try to print `<[T; /* print `constant#0` again */] as Default>::{constant#0}` - p!(write("{}::{}", self.tcx().crate_name(def.krate), self.tcx().def_path(def).to_string_no_crate_verbose())) + p!(write( + "{}::{}", + self.tcx().crate_name(def.krate), + self.tcx().def_path(def).to_string_no_crate_verbose() + )) } } defkind => bug!("`{:?}` has unexpected defkind {:?}", ct, defkind), } } - ty::ConstKind::Infer(infer_ct) => { - match infer_ct { - ty::InferConst::Var(ct_vid) - if let Some(name) = self.const_infer_name(ct_vid) => - p!(write("{}", name)), - _ => print_underscore!(), + ty::ConstKind::Infer(infer_ct) => match infer_ct { + ty::InferConst::Var(ct_vid) if let Some(name) = self.const_infer_name(ct_vid) => { + p!(write("{}", name)) } - } + _ => print_underscore!(), + }, ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)), ty::ConstKind::Value(value) => { return self.pretty_print_const_valtree(value, ct.ty(), print_ty); @@ -2246,7 +2255,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { | ty::RePlaceholder(ty::Placeholder { bound: ty::BoundRegion { kind: br, .. }, .. }) => { - if let ty::BrNamed(_, name) = br && br.is_named() { + if let ty::BrNamed(_, name) = br + && br.is_named() + { p!(write("{}", name)); return Ok(self); } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index e5f418bbb4b..30318e585cb 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1220,7 +1220,12 @@ pub struct AliasTy<'tcx> { impl<'tcx> AliasTy<'tcx> { pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasKind { match tcx.def_kind(self.def_id) { - DefKind::AssocTy if let DefKind::Impl { of_trait: false } = tcx.def_kind(tcx.parent(self.def_id)) => ty::Inherent, + DefKind::AssocTy + if let DefKind::Impl { of_trait: false } = + tcx.def_kind(tcx.parent(self.def_id)) => + { + ty::Inherent + } DefKind::AssocTy => ty::Projection, DefKind::OpaqueTy => ty::Opaque, DefKind::TyAlias => ty::Weak, @@ -2848,7 +2853,7 @@ impl<'tcx> Ty<'tcx> { /// Returning true means the type is known to be pure and `Copy+Clone`. /// Returning `false` means nothing -- could be `Copy`, might not be. /// - /// This is mostly useful for optimizations, as there are the types + /// This is mostly useful for optimizations, as these are the types /// on which we can replace cloning with dereferencing. pub fn is_trivially_pure_clone_copy(self) -> bool { match self.kind() { diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index 578d8e7a975..f30993c9a69 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -217,7 +217,8 @@ fn find_item_ty_spans( match ty.kind { hir::TyKind::Path(hir::QPath::Resolved(_, path)) => { if let Res::Def(kind, def_id) = path.res - && !matches!(kind, DefKind::TyAlias) { + && !matches!(kind, DefKind::TyAlias) + { let check_params = def_id.as_local().map_or(true, |def_id| { if def_id == needle { spans.push(ty.span); @@ -227,8 +228,11 @@ fn find_item_ty_spans( if check_params && let Some(args) = path.segments.last().unwrap().args { let params_in_repr = tcx.params_in_repr(def_id); // the domain size check is needed because the HIR may not be well-formed at this point - for (i, arg) in args.args.iter().enumerate().take(params_in_repr.domain_size()) { - if let hir::GenericArg::Type(ty) = arg && params_in_repr.contains(i as u32) { + for (i, arg) in args.args.iter().enumerate().take(params_in_repr.domain_size()) + { + if let hir::GenericArg::Type(ty) = arg + && params_in_repr.contains(i as u32) + { find_item_ty_spans(tcx, ty, needle, spans, seen_representable); } } diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index afb65ffbe8c..7d7542a9a6a 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -213,7 +213,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Casting an enum to an integer is equivalent to computing the discriminant and casting the // discriminant. Previously every backend had to repeat the logic for this operation. Now we // create all the steps directly in MIR with operations all backends need to support anyway. - let (source, ty) = if let ty::Adt(adt_def, ..) = source.ty.kind() && adt_def.is_enum() { + let (source, ty) = if let ty::Adt(adt_def, ..) = source.ty.kind() + && adt_def.is_enum() + { let discr_ty = adt_def.repr().discr_type().to_ty(this.tcx); let temp = unpack!(block = this.as_temp(block, scope, source, Mutability::Not)); let layout = this.tcx.layout_of(this.param_env.and(source.ty)); @@ -224,7 +226,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { discr, Rvalue::Discriminant(temp.into()), ); - let (op,ty) = (Operand::Move(discr), discr_ty); + let (op, ty) = (Operand::Move(discr), discr_ty); if let Abi::Scalar(scalar) = layout.unwrap().abi && !scalar.is_always_valid(&this.tcx) @@ -236,27 +238,30 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, source_info, unsigned_place, - Rvalue::Cast(CastKind::IntToInt, Operand::Copy(discr), unsigned_ty)); + Rvalue::Cast(CastKind::IntToInt, Operand::Copy(discr), unsigned_ty), + ); let bool_ty = this.tcx.types.bool; let range = scalar.valid_range(&this.tcx); let merge_op = - if range.start <= range.end { - BinOp::BitAnd - } else { - BinOp::BitOr - }; + if range.start <= range.end { BinOp::BitAnd } else { BinOp::BitOr }; let mut comparer = |range: u128, bin_op: BinOp| -> Place<'tcx> { - let range_val = - Const::from_bits(this.tcx, range, ty::ParamEnv::empty().and(unsigned_ty)); + let range_val = Const::from_bits( + this.tcx, + range, + ty::ParamEnv::empty().and(unsigned_ty), + ); let lit_op = this.literal_operand(expr.span, range_val); let is_bin_op = this.temp(bool_ty, expr_span); this.cfg.push_assign( block, source_info, is_bin_op, - Rvalue::BinaryOp(bin_op, Box::new((Operand::Copy(unsigned_place), lit_op))), + Rvalue::BinaryOp( + bin_op, + Box::new((Operand::Copy(unsigned_place), lit_op)), + ), ); is_bin_op }; @@ -270,7 +275,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, source_info, merge_place, - Rvalue::BinaryOp(merge_op, Box::new((Operand::Move(start_place), Operand::Move(end_place)))), + Rvalue::BinaryOp( + merge_op, + Box::new(( + Operand::Move(start_place), + Operand::Move(end_place), + )), + ), ); merge_place }; @@ -278,19 +289,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, Statement { source_info, - kind: StatementKind::Intrinsic(Box::new(NonDivergingIntrinsic::Assume( - Operand::Move(assert_place), - ))), + kind: StatementKind::Intrinsic(Box::new( + NonDivergingIntrinsic::Assume(Operand::Move(assert_place)), + )), }, ); } - (op,ty) - + (op, ty) } else { let ty = source.ty; let source = unpack!( - block = this.as_operand(block, scope, source, LocalInfo::Boring, NeedsTemporary::No) + block = this.as_operand( + block, + scope, + source, + LocalInfo::Boring, + NeedsTemporary::No + ) ); (source, ty) }; diff --git a/compiler/rustc_mir_build/src/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs index 396f82c27cd..7beaef602a8 100644 --- a/compiler/rustc_mir_build/src/build/expr/stmt.rs +++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs @@ -120,32 +120,31 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // // it is usually better to focus on `the_value` rather // than the entirety of block(s) surrounding it. - let adjusted_span = - if let ExprKind::Block { block } = expr.kind - && let Some(tail_ex) = this.thir[block].expr - { - let mut expr = &this.thir[tail_ex]; - loop { - match expr.kind { - ExprKind::Block { block } - if let Some(nested_expr) = this.thir[block].expr => - { - expr = &this.thir[nested_expr]; - } - ExprKind::Scope { value: nested_expr, .. } => { - expr = &this.thir[nested_expr]; - } - _ => break, + let adjusted_span = if let ExprKind::Block { block } = expr.kind + && let Some(tail_ex) = this.thir[block].expr + { + let mut expr = &this.thir[tail_ex]; + loop { + match expr.kind { + ExprKind::Block { block } + if let Some(nested_expr) = this.thir[block].expr => + { + expr = &this.thir[nested_expr]; } + ExprKind::Scope { value: nested_expr, .. } => { + expr = &this.thir[nested_expr]; + } + _ => break, } - this.block_context.push(BlockFrame::TailExpr { - tail_result_is_ignored: true, - span: expr.span, - }); - Some(expr.span) - } else { - None - }; + } + this.block_context.push(BlockFrame::TailExpr { + tail_result_is_ignored: true, + span: expr.span, + }); + Some(expr.span) + } else { + None + }; let temp = unpack!(block = this.as_temp(block, statement_scope, expr, Mutability::Not)); diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index eb1c6a9824a..24c6e0eae36 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -736,7 +736,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.push(block, Statement { source_info, kind: StatementKind::StorageLive(local_id) }); // Although there is almost always scope for given variable in corner cases // like #92893 we might get variable with no scope. - if let Some(region_scope) = self.region_scope_tree.var_scope(var.0.local_id) && schedule_drop { + if let Some(region_scope) = self.region_scope_tree.var_scope(var.0.local_id) + && schedule_drop + { self.schedule_drop(span, region_scope, local_id, DropKind::Storage); } Place::from(local_id) @@ -814,7 +816,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - PatKind::Constant { .. } | PatKind::Range { .. } | PatKind::Wild => {} + PatKind::Constant { .. } + | PatKind::Range { .. } + | PatKind::Wild + | PatKind::Error(_) => {} PatKind::Deref { ref subpattern } => { self.visit_primary_bindings(subpattern, pattern_user_ty.deref(), f); diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index 17ac1f4e0ce..f340feb40d4 100644 --- a/compiler/rustc_mir_build/src/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs @@ -168,7 +168,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Ok(()) } - PatKind::Wild => { + PatKind::Wild | PatKind::Error(_) => { // nothing left to do Ok(()) } diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 795d1db8eec..30ce37a7ac1 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -77,7 +77,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | PatKind::Wild | PatKind::Binding { .. } | PatKind::Leaf { .. } - | PatKind::Deref { .. } => self.error_simplifiable(match_pair), + | PatKind::Deref { .. } + | PatKind::Error(_) => self.error_simplifiable(match_pair), } } @@ -111,7 +112,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | PatKind::Binding { .. } | PatKind::AscribeUserType { .. } | PatKind::Leaf { .. } - | PatKind::Deref { .. } => { + | PatKind::Deref { .. } + | PatKind::Error(_) => { // don't know how to add these patterns to a switch false } @@ -236,18 +238,27 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { TestKind::Eq { value, ty } => { let tcx = self.tcx; - if let ty::Adt(def, _) = ty.kind() && Some(def.did()) == tcx.lang_items().string() { + if let ty::Adt(def, _) = ty.kind() + && Some(def.did()) == tcx.lang_items().string() + { if !tcx.features().string_deref_patterns { - bug!("matching on `String` went through without enabling string_deref_patterns"); + bug!( + "matching on `String` went through without enabling string_deref_patterns" + ); } let re_erased = tcx.lifetimes.re_erased; - let ref_string = self.temp(Ty::new_imm_ref(tcx,re_erased, ty), test.span); - let ref_str_ty = Ty::new_imm_ref(tcx,re_erased, tcx.types.str_); + let ref_string = self.temp(Ty::new_imm_ref(tcx, re_erased, ty), test.span); + let ref_str_ty = Ty::new_imm_ref(tcx, re_erased, tcx.types.str_); let ref_str = self.temp(ref_str_ty, test.span); let deref = tcx.require_lang_item(LangItem::Deref, None); let method = trait_method(tcx, deref, sym::deref, [ty]); let eq_block = self.cfg.start_new_block(); - self.cfg.push_assign(block, source_info, ref_string, Rvalue::Ref(re_erased, BorrowKind::Shared, place)); + self.cfg.push_assign( + block, + source_info, + ref_string, + Rvalue::Ref(re_erased, BorrowKind::Shared, place), + ); self.cfg.terminate( block, source_info, @@ -262,10 +273,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { target: Some(eq_block), unwind: UnwindAction::Continue, call_source: CallSource::Misc, - fn_span: source_info.span - } + fn_span: source_info.span, + }, + ); + self.non_scalar_compare( + eq_block, + make_target_blocks, + source_info, + value, + ref_str, + ref_str_ty, ); - self.non_scalar_compare(eq_block, make_target_blocks, source_info, value, ref_str, ref_str_ty); return; } if !ty.is_scalar() { diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index bba47056457..d9098bac1c2 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -847,7 +847,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.local_decls.push(LocalDecl::with_source_info(param.ty, source_info)); // If this is a simple binding pattern, give debuginfo a nice name. - if let Some(ref pat) = param.pat && let Some(name) = pat.simple_ident() { + if let Some(ref pat) = param.pat + && let Some(name) = pat.simple_ident() + { self.var_debug_info.push(VarDebugInfo { name, source_info, diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 192bd4a83e3..2d221b826c9 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -224,7 +224,8 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { PatKind::Wild | // these just wrap other patterns PatKind::Or { .. } | - PatKind::AscribeUserType { .. } => {} + PatKind::AscribeUserType { .. } | + PatKind::Error(_) => {} } }; @@ -411,7 +412,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { } ExprKind::Field { lhs, .. } => { let lhs = &self.thir[lhs]; - if let ty::Adt(adt_def, _) = lhs.ty.kind() && adt_def.is_union() { + if let ty::Adt(adt_def, _) = lhs.ty.kind() + && adt_def.is_union() + { if let Some((assigned_ty, assignment_span)) = self.assignment_info { if assigned_ty.needs_drop(self.tcx, self.param_env) { // This would be unsafe, but should be outright impossible since we reject such unions. @@ -460,7 +463,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { } ExprKind::Let { expr: expr_id, .. } => { let let_expr = &self.thir[expr_id]; - if let ty::Adt(adt_def, _) = let_expr.ty.kind() && adt_def.is_union() { + if let ty::Adt(adt_def, _) = let_expr.ty.kind() + && adt_def.is_union() + { self.requires_unsafe(expr.span, AccessToUnionField); } } @@ -616,8 +621,7 @@ impl UnsafeOpKind { && let hir::BlockCheckMode::UnsafeBlock(_) = block.rules { true - } - else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id) + } else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id) && sig.header.is_unsafe() { true diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index 94be38beee4..e78274b4284 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -67,16 +67,21 @@ pub fn check_drop_recursion<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { let def_id = body.source.def_id().expect_local(); // First check if `body` is an `fn drop()` of `Drop` - if let DefKind::AssocFn = tcx.def_kind(def_id) && - let Some(trait_ref) = tcx.impl_of_method(def_id.to_def_id()).and_then(|def_id| tcx.impl_trait_ref(def_id)) && - let Some(drop_trait) = tcx.lang_items().drop_trait() && drop_trait == trait_ref.instantiate_identity().def_id { - + if let DefKind::AssocFn = tcx.def_kind(def_id) + && let Some(trait_ref) = + tcx.impl_of_method(def_id.to_def_id()).and_then(|def_id| tcx.impl_trait_ref(def_id)) + && let Some(drop_trait) = tcx.lang_items().drop_trait() + && drop_trait == trait_ref.instantiate_identity().def_id + { // It was. Now figure out for what type `Drop` is implemented and then // check for recursion. - if let ty::Ref(_, dropped_ty, _) = tcx.liberate_late_bound_regions( - def_id.to_def_id(), - tcx.fn_sig(def_id).instantiate_identity().input(0), - ).kind() { + if let ty::Ref(_, dropped_ty, _) = tcx + .liberate_late_bound_regions( + def_id.to_def_id(), + tcx.fn_sig(def_id).instantiate_identity().input(0), + ) + .kind() + { check_recursion(tcx, body, RecursiveDrop { drop_for: *dropped_ty }); } } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 16a85d42761..0535ea24b82 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -320,17 +320,23 @@ impl<'tcx> Cx<'tcx> { reason: errors::RustcBoxAttrReason::Attributes, }); } else if let Some(box_item) = tcx.lang_items().owned_box() { - if let hir::ExprKind::Path(hir::QPath::TypeRelative(ty, fn_path)) = fun.kind + if let hir::ExprKind::Path(hir::QPath::TypeRelative(ty, fn_path)) = + fun.kind && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind && path.res.opt_def_id().is_some_and(|did| did == box_item) && fn_path.ident.name == sym::new && let [value] = args { - return Expr { temp_lifetime, ty: expr_ty, span: expr.span, kind: ExprKind::Box { value: self.mirror_expr(value) } } + return Expr { + temp_lifetime, + ty: expr_ty, + span: expr.span, + kind: ExprKind::Box { value: self.mirror_expr(value) }, + }; } else { tcx.sess.emit_err(errors::RustcBoxAttributeError { span: expr.span, - reason: errors::RustcBoxAttrReason::NotBoxNew + reason: errors::RustcBoxAttrReason::NotBoxNew, }); } } else { @@ -343,17 +349,16 @@ impl<'tcx> Cx<'tcx> { // Tuple-like ADTs are represented as ExprKind::Call. We convert them here. let adt_data = if let hir::ExprKind::Path(ref qpath) = fun.kind - && let Some(adt_def) = expr_ty.ty_adt_def() { + && let Some(adt_def) = expr_ty.ty_adt_def() + { match qpath { - hir::QPath::Resolved(_, ref path) => { - match path.res { - Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => { - Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id))) - } - Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)), - _ => None, + hir::QPath::Resolved(_, ref path) => match path.res { + Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => { + Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id))) } - } + Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)), + _ => None, + }, hir::QPath::TypeRelative(_ty, _) => { if let Some((DefKind::Ctor(_, CtorKind::Fn), ctor_id)) = self.typeck_results().type_dependent_def(fun.hir_id) @@ -362,7 +367,6 @@ impl<'tcx> Cx<'tcx> { } else { None } - } _ => None, } diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 93434dd3cc2..9d38087fdeb 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -19,7 +19,7 @@ use rustc_hir::HirId; use rustc_middle::thir::visit::{self, Visitor}; use rustc_middle::thir::*; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; use rustc_session::lint::builtin::{ BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS, }; @@ -168,7 +168,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> { self.lint_level = lint_level; } - if let Some(initializer) = initializer && else_block.is_some() { + if let Some(initializer) = initializer + && else_block.is_some() + { self.check_let(pattern, initializer, LetSource::LetElse, span); } @@ -231,6 +233,10 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { if let LetSource::None = source { return; } + if let Err(err) = pat.pat_error_reported() { + self.error = Err(err); + return; + } self.check_patterns(pat, Refutable); let mut cx = self.new_cx(self.lint_level, true); let tpat = self.lower_pattern(&mut cx, pat); @@ -252,6 +258,10 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { self.with_lint_level(arm.lint_level, |this| { this.check_patterns(&arm.pattern, Refutable); }); + if let Err(err) = arm.pattern.pat_error_reported() { + self.error = Err(err); + return; + } } let tarms: Vec<_> = arms @@ -334,7 +344,8 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { // and record chain members that aren't let exprs. let mut chain_refutabilities = Vec::new(); - let add = |expr: ExprId, mut local_lint_level| { + let mut error = Ok(()); + let mut add = |expr: ExprId, mut local_lint_level| { // `local_lint_level` is the lint level enclosing the pattern inside `expr`. let mut expr = &self.thir[expr]; debug!(?expr, ?local_lint_level, "add"); @@ -348,6 +359,10 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { debug!(?expr, ?local_lint_level, "after scopes"); match expr.kind { ExprKind::Let { box ref pat, expr: _ } => { + if let Err(err) = pat.pat_error_reported() { + error = Err(err); + return None; + } let mut ncx = self.new_cx(local_lint_level, true); let tpat = self.lower_pattern(&mut ncx, pat); let refutable = !is_let_irrefutable(&mut ncx, local_lint_level, tpat); @@ -380,6 +395,11 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { debug!(?chain_refutabilities); chain_refutabilities.reverse(); + if error.is_err() { + self.error = error; + return; + } + // Third, emit the actual warnings. if chain_refutabilities.iter().all(|r| matches!(*r, Some((_, false)))) { // The entire chain is made up of irrefutable `let` statements @@ -393,7 +413,10 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { return; } - if let Some(until) = chain_refutabilities.iter().position(|r| !matches!(*r, Some((_, false)))) && until > 0 { + if let Some(until) = + chain_refutabilities.iter().position(|r| !matches!(*r, Some((_, false)))) + && until > 0 + { // The chain has a non-zero prefix of irrefutable `let` statements. // Check if the let source is while, for there is no alternative place to put a prefix, @@ -409,23 +432,42 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { let span_end = prefix.last().unwrap().unwrap().0; let span = span_start.to(span_end); let count = prefix.len(); - self.tcx.emit_spanned_lint(IRREFUTABLE_LET_PATTERNS, self.lint_level, span, LeadingIrrefutableLetPatterns { count }); + self.tcx.emit_spanned_lint( + IRREFUTABLE_LET_PATTERNS, + self.lint_level, + span, + LeadingIrrefutableLetPatterns { count }, + ); } } - if let Some(from) = chain_refutabilities.iter().rposition(|r| !matches!(*r, Some((_, false)))) && from != (chain_refutabilities.len() - 1) { + if let Some(from) = + chain_refutabilities.iter().rposition(|r| !matches!(*r, Some((_, false)))) + && from != (chain_refutabilities.len() - 1) + { // The chain has a non-empty suffix of irrefutable `let` statements let suffix = &chain_refutabilities[from + 1..]; let span_start = suffix[0].unwrap().0; let span_end = suffix.last().unwrap().unwrap().0; let span = span_start.to(span_end); let count = suffix.len(); - self.tcx.emit_spanned_lint(IRREFUTABLE_LET_PATTERNS, self.lint_level, span, TrailingIrrefutableLetPatterns { count }); + self.tcx.emit_spanned_lint( + IRREFUTABLE_LET_PATTERNS, + self.lint_level, + span, + TrailingIrrefutableLetPatterns { count }, + ); } } #[instrument(level = "trace", skip(self))] fn check_irrefutable(&mut self, pat: &Pat<'tcx>, origin: &str, sp: Option<Span>) { + // If we got errors while lowering, don't emit anything more. + if let Err(err) = pat.pat_error_reported() { + self.error = Err(err); + return; + } + let mut cx = self.new_cx(self.lint_level, false); let pattern = self.lower_pattern(&mut cx, pat); @@ -448,23 +490,21 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { let mut interpreted_as_const = None; if let PatKind::Constant { .. } - | PatKind::AscribeUserType { - subpattern: box Pat { kind: PatKind::Constant { .. }, .. }, - .. - } = pat.kind + | PatKind::AscribeUserType { + subpattern: box Pat { kind: PatKind::Constant { .. }, .. }, + .. + } = pat.kind && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span) { // If the pattern to match is an integer literal: if snippet.chars().all(|c| c.is_digit(10)) { // Then give a suggestion, the user might've meant to create a binding instead. misc_suggestion = Some(MiscPatternSuggestion::AttemptedIntegerLiteral { - start_span: pat.span.shrink_to_lo() + start_span: pat.span.shrink_to_lo(), }); } else if snippet.chars().all(|c| c.is_alphanumeric() || c == '_') { - interpreted_as_const = Some(InterpretedAsConst { - span: pat.span, - variable: snippet, - }); + interpreted_as_const = + Some(InterpretedAsConst { span: pat.span, variable: snippet }); } } @@ -501,20 +541,19 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { // Emit an extra note if the first uncovered witness would be uninhabited // if we disregard visibility. - let witness_1_is_privately_uninhabited = - if cx.tcx.features().exhaustive_patterns - && let Some(witness_1) = witnesses.get(0) - && let ty::Adt(adt, args) = witness_1.ty().kind() - && adt.is_enum() - && let Constructor::Variant(variant_index) = witness_1.ctor() - { - let variant = adt.variant(*variant_index); - let inhabited = variant.inhabited_predicate(cx.tcx, *adt).instantiate(cx.tcx, args); - assert!(inhabited.apply(cx.tcx, cx.param_env, cx.module)); - !inhabited.apply_ignore_module(cx.tcx, cx.param_env) - } else { - false - }; + let witness_1_is_privately_uninhabited = if cx.tcx.features().exhaustive_patterns + && let Some(witness_1) = witnesses.get(0) + && let ty::Adt(adt, args) = witness_1.ty().kind() + && adt.is_enum() + && let Constructor::Variant(variant_index) = witness_1.ctor() + { + let variant = adt.variant(*variant_index); + let inhabited = variant.inhabited_predicate(cx.tcx, *adt).instantiate(cx.tcx, args); + assert!(inhabited.apply(cx.tcx, cx.param_env, cx.module)); + !inhabited.apply_ignore_module(cx.tcx, cx.param_env) + } else { + false + }; self.error = Err(self.tcx.sess.emit_err(PatternNotCovered { span: pat.span, @@ -539,23 +578,22 @@ fn check_for_bindings_named_same_as_variants( ) { pat.walk_always(|p| { if let PatKind::Binding { - name, - mode: BindingMode::ByValue, - mutability: Mutability::Not, - subpattern: None, - ty, - .. - } = p.kind + name, + mode: BindingMode::ByValue, + mutability: Mutability::Not, + subpattern: None, + ty, + .. + } = p.kind && let ty::Adt(edef, _) = ty.peel_refs().kind() && edef.is_enum() - && edef.variants().iter().any(|variant| { - variant.name == name && variant.ctor_kind() == Some(CtorKind::Const) - }) + && edef + .variants() + .iter() + .any(|variant| variant.name == name && variant.ctor_kind() == Some(CtorKind::Const)) { let variant_count = edef.variants().len(); - let ty_path = with_no_trimmed_paths!({ - cx.tcx.def_path_str(edef.did()) - }); + let ty_path = with_no_trimmed_paths!(cx.tcx.def_path_str(edef.did())); cx.tcx.emit_spanned_lint( BINDINGS_WITH_VARIANT_NAME, cx.lint_level, @@ -566,7 +604,9 @@ fn check_for_bindings_named_same_as_variants( // suggestion would produce code that breaks on `check_irrefutable`. suggestion: if rf == Refutable || variant_count == 1 { Some(p.span) - } else { None }, + } else { + None + }, ty_path, name, }, @@ -682,12 +722,6 @@ fn non_exhaustive_match<'p, 'tcx>( arms: &[ArmId], expr_span: Span, ) -> ErrorGuaranteed { - for &arm in arms { - if let Err(err) = thir[arm].pattern.error_reported() { - return err; - } - } - let is_empty_match = arms.is_empty(); let non_empty_enum = match scrut_ty.kind() { ty::Adt(def, _) => def.is_enum() && !def.variants().is_empty(), @@ -776,8 +810,10 @@ fn non_exhaustive_match<'p, 'tcx>( } [only] => { let only = &thir[*only]; - let (pre_indentation, is_multiline) = if let Some(snippet) = sm.indentation_before(only.span) - && let Ok(with_trailing) = sm.span_extend_while(only.span, |c| c.is_whitespace() || c == ',') + let (pre_indentation, is_multiline) = if let Some(snippet) = + sm.indentation_before(only.span) + && let Ok(with_trailing) = + sm.span_extend_while(only.span, |c| c.is_whitespace() || c == ',') && sm.is_multiline(with_trailing) { (format!("\n{snippet}"), true) @@ -928,7 +964,9 @@ fn maybe_point_at_variant<'a, 'p: 'a, 'tcx: 'a>( let mut covered = vec![]; for pattern in patterns { if let Variant(variant_index) = pattern.ctor() { - if let ty::Adt(this_def, _) = pattern.ty().kind() && this_def.did() != def.did() { + if let ty::Adt(this_def, _) = pattern.ty().kind() + && this_def.did() != def.did() + { continue; } let sp = def.variant(*variant_index).ident(cx.tcx).span; diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index fde6defd87f..fc03f7891a8 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -196,9 +196,15 @@ impl<'tcx> ConstToPat<'tcx> { }; // All branches above emitted an error. Don't print any more lints. // We errored. Signal that in the pattern, so that follow up errors can be silenced. - let kind = PatKind::Constant { - value: mir::Const::Ty(ty::Const::new_error(self.tcx(), e, cv.ty())), - }; + let kind = PatKind::Error(e); + return Box::new(Pat { span: self.span, ty: cv.ty(), kind }); + } else if let ty::Adt(..) = cv.ty().kind() && matches!(cv, mir::Const::Val(..)) { + // This branch is only entered when the current `cv` is `mir::Const::Val`. + // This is because `mir::Const::ty` has already been handled by `Self::recur` + // and the invalid types may be ignored. + let err = TypeNotStructural { span: self.span, non_sm_ty }; + let e = self.tcx().sess.emit_err(err); + let kind = PatKind::Error(e); return Box::new(Pat { span: self.span, ty: cv.ty(), kind }); } else if !self.saw_const_match_lint.get() { if let Some(mir_structural_match_violation) = mir_structural_match_violation { @@ -351,7 +357,7 @@ impl<'tcx> ConstToPat<'tcx> { let e = tcx.sess.emit_err(InvalidPattern { span, non_sm_ty: ty }); self.saw_const_match_error.set(Some(e)); // We errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Constant { value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)) } + PatKind::Error(e) } ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => { debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty,); @@ -359,7 +365,7 @@ impl<'tcx> ConstToPat<'tcx> { let e = tcx.sess.emit_err(err); self.saw_const_match_error.set(Some(e)); // We errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Constant { value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)) } + PatKind::Error(e) } ty::Adt(adt_def, args) if adt_def.is_enum() => { let (&variant_index, fields) = cv.unwrap_branch().split_first().unwrap(); @@ -434,17 +440,13 @@ impl<'tcx> ConstToPat<'tcx> { } else { if let Some(e) = self.saw_const_match_error.get() { // We already errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Constant { - value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)), - } + PatKind::Error(e) } else { let err = TypeNotStructural { span, non_sm_ty: *pointee_ty }; let e = tcx.sess.emit_err(err); self.saw_const_match_error.set(Some(e)); // We errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Constant { - value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)), - } + PatKind::Error(e) } } } @@ -456,9 +458,7 @@ impl<'tcx> ConstToPat<'tcx> { let err = UnsizedPattern { span, non_sm_ty: *pointee_ty }; let e = tcx.sess.emit_err(err); // We errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Constant { - value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)), - } + PatKind::Error(e) } else { let old = self.behind_reference.replace(true); // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when @@ -489,7 +489,7 @@ impl<'tcx> ConstToPat<'tcx> { let e = tcx.sess.emit_err(err); self.saw_const_match_error.set(Some(e)); // We errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Constant { value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)) } + PatKind::Error(e) } }; @@ -508,7 +508,7 @@ impl<'tcx> ConstToPat<'tcx> { lint::builtin::NONTRIVIAL_STRUCTURAL_MATCH, id, span, - NontrivialStructuralMatch {non_sm_ty} + NontrivialStructuralMatch { non_sm_ty }, ); } diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index a7a000ba31c..bbc0aeb66cf 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -1525,6 +1525,10 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> { let pats = expand_or_pat(pat); fields = Fields::from_iter(cx, pats.into_iter().map(mkpat)); } + PatKind::Error(_) => { + ctor = Opaque; + fields = Fields::empty(); + } } DeconstructedPat::new(ctor, fields, pat.ty, pat.span) } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 25726c5a872..76ed6d2b6d7 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -252,10 +252,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { hir::PatKind::Range(ref lo_expr, ref hi_expr, end) => { let (lo_expr, hi_expr) = (lo_expr.as_deref(), hi_expr.as_deref()); - // FIXME?: returning `_` can cause inaccurate "unreachable" warnings. This can be - // fixed by returning `PatKind::Const(ConstKind::Error(...))` if #115937 gets - // merged. - self.lower_pattern_range(lo_expr, hi_expr, end, ty, span).unwrap_or(PatKind::Wild) + self.lower_pattern_range(lo_expr, hi_expr, end, ty, span) + .unwrap_or_else(PatKind::Error) } hir::PatKind::Path(ref qpath) => { @@ -423,9 +421,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { if adt_def.is_enum() { let args = match ty.kind() { ty::Adt(_, args) | ty::FnDef(_, args) => args, - ty::Error(_) => { + ty::Error(e) => { // Avoid ICE (#50585) - return PatKind::Wild; + return PatKind::Error(*e); } _ => bug!("inappropriate type for def: {:?}", ty), }; @@ -452,7 +450,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { | Res::SelfTyAlias { .. } | Res::SelfCtor(..) => PatKind::Leaf { subpatterns }, _ => { - match res { + let e = match res { Res::Def(DefKind::ConstParam, _) => { self.tcx.sess.emit_err(ConstParamInPattern { span }) } @@ -461,7 +459,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } _ => self.tcx.sess.emit_err(NonConstPath { span }), }; - PatKind::Wild + PatKind::Error(e) } }; @@ -513,14 +511,13 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // It should be assoc consts if there's no error but we cannot resolve it. debug_assert!(is_associated_const); - self.tcx.sess.emit_err(AssocConstInPattern { span }); - - return pat_from_kind(PatKind::Wild); + let e = self.tcx.sess.emit_err(AssocConstInPattern { span }); + return pat_from_kind(PatKind::Error(e)); } Err(_) => { - self.tcx.sess.emit_err(CouldNotEvalConstPattern { span }); - return pat_from_kind(PatKind::Wild); + let e = self.tcx.sess.emit_err(CouldNotEvalConstPattern { span }); + return pat_from_kind(PatKind::Error(e)); } }; @@ -574,12 +571,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { Err(ErrorHandled::TooGeneric(_)) => { // While `Reported | Linted` cases will have diagnostics emitted already // it is not true for TooGeneric case, so we need to give user more information. - self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span }); - pat_from_kind(PatKind::Wild) + let e = self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span }); + pat_from_kind(PatKind::Error(e)) } Err(_) => { - self.tcx.sess.emit_err(CouldNotEvalConstPattern { span }); - pat_from_kind(PatKind::Wild) + let e = self.tcx.sess.emit_err(CouldNotEvalConstPattern { span }); + pat_from_kind(PatKind::Error(e)) } } } @@ -629,7 +626,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let uneval = mir::UnevaluatedConst { def: def_id.to_def_id(), args, promoted: None }; debug_assert!(!args.has_free_regions()); - let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), args: args }; + let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), args }; // First try using a valtree in order to destructure the constant into a pattern. // FIXME: replace "try to do a thing, then fall back to another thing" // but something more principled, like a trait query checking whether this can be turned into a valtree. @@ -649,10 +646,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { Ok(val) => self.const_to_pat(mir::Const::Val(val, ty), id, span, None).kind, Err(ErrorHandled::TooGeneric(_)) => { // If we land here it means the const can't be evaluated because it's `TooGeneric`. - self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span }); - PatKind::Wild + let e = self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span }); + PatKind::Error(e) } - Err(ErrorHandled::Reported(..)) => PatKind::Wild, + Err(ErrorHandled::Reported(err, ..)) => PatKind::Error(err.into()), } } } @@ -685,7 +682,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { Ok(constant) => { self.const_to_pat(Const::Ty(constant), expr.hir_id, lit.span, None).kind } - Err(LitToConstError::Reported(_)) => PatKind::Wild, + Err(LitToConstError::Reported(e)) => PatKind::Error(e), Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"), } } @@ -791,6 +788,7 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> { fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self { match *self { PatKind::Wild => PatKind::Wild, + PatKind::Error(e) => PatKind::Error(e), PatKind::AscribeUserType { ref subpattern, ascription: Ascription { ref annotation, variance }, diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index 3b6276cfeb0..c957611b975 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -757,6 +757,9 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { print_indented!(self, "]", depth_lvl + 2); print_indented!(self, "}", depth_lvl + 1); } + PatKind::Error(_) => { + print_indented!(self, "Error", depth_lvl + 1); + } } print_indented!(self, "}", depth_lvl); diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 83766f31148..44bbb8374dc 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -685,8 +685,10 @@ impl Map { // `elem1` is either `Some(Variant(i))` or `None`. while let Some((mut place, elem1, elem2, ty)) = worklist.pop_front() { // The user requires a bound on the number of created values. - if let Some(value_limit) = value_limit && self.value_count >= value_limit { - break + if let Some(value_limit) = value_limit + && self.value_count >= value_limit + { + break; } // Create a place for this projection. @@ -717,7 +719,9 @@ impl Map { // Trim useless places. for opt_place in self.locals.iter_mut() { - if let Some(place) = *opt_place && self.inner_values[place].is_empty() { + if let Some(place) = *opt_place + && self.inner_values[place].is_empty() + { *opt_place = None; } } @@ -772,7 +776,7 @@ impl Map { assert!(old.is_none()); // Allocate a value slot since it doesn't have one. - assert!( self.places[len].value_index.is_none() ); + assert!(self.places[len].value_index.is_none()); self.places[len].value_index = Some(self.value_count.into()); self.value_count += 1; } diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs index b79150737d6..61bf530f11c 100644 --- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs +++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs @@ -97,13 +97,15 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> { // so emitting a lint would be redundant. if !lhs.projection.is_empty() { if let Some(def_id) = self.is_const_item_without_destructor(lhs.local) - && let Some((lint_root, span, item)) = self.should_lint_const_item_usage(&lhs, def_id, loc) { - self.tcx.emit_spanned_lint( - CONST_ITEM_MUTATION, - lint_root, - span, - errors::ConstMutate::Modify { konst: item } - ); + && let Some((lint_root, span, item)) = + self.should_lint_const_item_usage(&lhs, def_id, loc) + { + self.tcx.emit_spanned_lint( + CONST_ITEM_MUTATION, + lint_root, + span, + errors::ConstMutate::Modify { konst: item }, + ); } } // We are looking for MIR of the form: diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs index 2e6cf603d59..9ee0a704071 100644 --- a/compiler/rustc_mir_transform/src/check_packed_ref.rs +++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs @@ -46,9 +46,14 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> { // If we ever reach here it means that the generated derive // code is somehow doing an unaligned reference, which it // shouldn't do. - span_bug!(self.source_info.span, "builtin derive created an unaligned reference"); + span_bug!( + self.source_info.span, + "builtin derive created an unaligned reference" + ); } else { - self.tcx.sess.emit_err(errors::UnalignedPackedRef { span: self.source_info.span }); + self.tcx + .sess + .emit_err(errors::UnalignedPackedRef { span: self.source_info.span }); } } } diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index c428007707e..7e4731f5d8a 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -540,8 +540,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { && let BlockCheckMode::UnsafeBlock(_) = block.rules { true - } - else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id) + } else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id) && sig.header.is_unsafe() { true diff --git a/compiler/rustc_mir_transform/src/const_debuginfo.rs b/compiler/rustc_mir_transform/src/const_debuginfo.rs index 40cd2825408..e4e4270c499 100644 --- a/compiler/rustc_mir_transform/src/const_debuginfo.rs +++ b/compiler/rustc_mir_transform/src/const_debuginfo.rs @@ -55,7 +55,9 @@ fn find_optimization_opportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, Const let mut locals_to_debuginfo = BitSet::new_empty(body.local_decls.len()); for debuginfo in &body.var_debug_info { - if let VarDebugInfoContents::Place(p) = debuginfo.value && let Some(l) = p.as_local() { + if let VarDebugInfoContents::Place(p) = debuginfo.value + && let Some(l) = p.as_local() + { locals_to_debuginfo.insert(l); } } diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index d379db5e07d..3450a0f3686 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -684,7 +684,9 @@ impl<'tcx> Visitor<'tcx> for CanConstProp { impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { self.super_operand(operand, location); - if let Some(place) = operand.place() && let Some(value) = self.replace_with_const(place) { + if let Some(place) = operand.place() + && let Some(value) = self.replace_with_const(place) + { self.patch.before_effect.insert((location, place), value); } } @@ -718,7 +720,10 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { if let Rvalue::Use(Operand::Constant(c)) = rvalue && let Const::Val(..) = c.const_ { - trace!("skipping replace of Rvalue::Use({:?} because it is already a const", c); + trace!( + "skipping replace of Rvalue::Use({:?} because it is already a const", + c + ); } else if let Some(operand) = self.replace_with_const(*place) { self.patch.assignments.insert(location, operand); } diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index b51bfe8c6ab..aad513d7355 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -627,9 +627,10 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { } TerminatorKind::SwitchInt { ref discr, ref targets } => { if let Some(ref value) = self.eval_operand(&discr, location) - && let Some(value_const) = self.use_ecx(location, |this| this.ecx.read_scalar(value)) - && let Ok(constant) = value_const.try_to_int() - && let Ok(constant) = constant.to_bits(constant.size()) + && let Some(value_const) = + self.use_ecx(location, |this| this.ecx.read_scalar(value)) + && let Ok(constant) = value_const.try_to_int() + && let Ok(constant) = constant.to_bits(constant.size()) { // We managed to evaluate the discriminant, so we know we only need to visit // one target. diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs index 9a3798eea3b..be4af3b76f1 100644 --- a/compiler/rustc_mir_transform/src/copy_prop.rs +++ b/compiler/rustc_mir_transform/src/copy_prop.rs @@ -168,14 +168,15 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> { && self.storage_to_remove.contains(l) { stmt.make_nop(); - return + return; } self.super_statement(stmt, loc); // Do not leave tautological assignments around. if let StatementKind::Assign(box (lhs, ref rhs)) = stmt.kind - && let Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)) | Rvalue::CopyForDeref(rhs) = *rhs + && let Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)) | Rvalue::CopyForDeref(rhs) = + *rhs && lhs == rhs { stmt.make_nop(); diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index abf13519e9e..63126f4486b 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -219,7 +219,10 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { let tcx = self.tcx; let source_map = tcx.sess.source_map(); let body_span = self.body_span; - let file_name = Symbol::intern(&self.source_file.name.prefer_remapped().to_string_lossy()); + + use rustc_session::RemapFileNameExt; + let file_name = + Symbol::intern(&self.source_file.name.for_codegen(self.tcx.sess).to_string_lossy()); for (bcb, spans) in coverage_spans.bcbs_with_coverage_spans() { let counter_kind = self.coverage_counters.take_bcb_counter(bcb).unwrap_or_else(|| { diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index e08019bea21..1d1be8f2492 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -3,7 +3,7 @@ use std::cell::OnceCell; use rustc_data_structures::graph::WithNumNodes; use rustc_index::IndexVec; use rustc_middle::mir::{self, AggregateKind, Rvalue, Statement, StatementKind}; -use rustc_span::{BytePos, ExpnKind, MacroKind, Span, Symbol}; +use rustc_span::{BytePos, ExpnKind, MacroKind, Span, Symbol, DUMMY_SP}; use super::graph::{BasicCoverageBlock, CoverageGraph, START_BCB}; @@ -159,11 +159,12 @@ impl CoverageSpan { /// If the span is part of a macro, and the macro is visible (expands directly to the given /// body_span), returns the macro name symbol. pub fn visible_macro(&self, body_span: Span) -> Option<Symbol> { - if let Some(current_macro) = self.current_macro() && self - .expn_span - .parent_callsite() - .unwrap_or_else(|| bug!("macro must have a parent")) - .eq_ctxt(body_span) + if let Some(current_macro) = self.current_macro() + && self + .expn_span + .parent_callsite() + .unwrap_or_else(|| bug!("macro must have a parent")) + .eq_ctxt(body_span) { return Some(current_macro); } @@ -214,9 +215,6 @@ struct CoverageSpansGenerator<'a> { /// is mutated. prev_original_span: Span, - /// A copy of the expn_span from the prior iteration. - prev_expn_span: Option<Span>, - /// One or more `CoverageSpan`s with the same `Span` but different `BasicCoverageBlock`s, and /// no `BasicCoverageBlock` in this list dominates another `BasicCoverageBlock` in the list. /// If a new `curr` span also fits this criteria (compared to an existing list of @@ -271,13 +269,12 @@ impl<'a> CoverageSpansGenerator<'a> { body_span, basic_coverage_blocks, sorted_spans_iter: sorted_spans.into_iter(), - refined_spans: Vec::with_capacity(basic_coverage_blocks.num_nodes() * 2), some_curr: None, - curr_original_span: Span::with_root_ctxt(BytePos(0), BytePos(0)), + curr_original_span: DUMMY_SP, some_prev: None, - prev_original_span: Span::with_root_ctxt(BytePos(0), BytePos(0)), - prev_expn_span: None, + prev_original_span: DUMMY_SP, pending_dups: Vec::new(), + refined_spans: Vec::with_capacity(basic_coverage_blocks.num_nodes() * 2), }; coverage_spans.to_refined_spans() @@ -287,43 +284,48 @@ impl<'a> CoverageSpansGenerator<'a> { /// de-duplicated `CoverageSpan`s. fn to_refined_spans(mut self) -> Vec<CoverageSpan> { while self.next_coverage_span() { + // For the first span we don't have `prev` set, so most of the + // span-processing steps don't make sense yet. if self.some_prev.is_none() { debug!(" initial span"); - self.check_invoked_macro_name_span(); - } else if self.curr().is_mergeable(self.prev()) { - debug!(" same bcb (and neither is a closure), merge with prev={:?}", self.prev()); + self.maybe_push_macro_name_span(); + continue; + } + + // The remaining cases assume that `prev` and `curr` are set. + let prev = self.prev(); + let curr = self.curr(); + + if curr.is_mergeable(prev) { + debug!(" same bcb (and neither is a closure), merge with prev={prev:?}"); let prev = self.take_prev(); self.curr_mut().merge_from(prev); - self.check_invoked_macro_name_span(); + self.maybe_push_macro_name_span(); // Note that curr.span may now differ from curr_original_span - } else if self.prev_ends_before_curr() { + } else if prev.span.hi() <= curr.span.lo() { debug!( - " different bcbs and disjoint spans, so keep curr for next iter, and add \ - prev={:?}", - self.prev() + " different bcbs and disjoint spans, so keep curr for next iter, and add prev={prev:?}", ); let prev = self.take_prev(); self.push_refined_span(prev); - self.check_invoked_macro_name_span(); - } else if self.prev().is_closure { + self.maybe_push_macro_name_span(); + } else if prev.is_closure { // drop any equal or overlapping span (`curr`) and keep `prev` to test again in the // next iter debug!( - " curr overlaps a closure (prev). Drop curr and keep prev for next iter. \ - prev={:?}", - self.prev() + " curr overlaps a closure (prev). Drop curr and keep prev for next iter. prev={prev:?}", ); - self.take_curr(); - } else if self.curr().is_closure { + self.take_curr(); // Discards curr. + } else if curr.is_closure { self.carve_out_span_for_closure(); - } else if self.prev_original_span == self.curr().span { + } else if self.prev_original_span == curr.span { // Note that this compares the new (`curr`) span to `prev_original_span`. // In this branch, the actual span byte range of `prev_original_span` is not // important. What is important is knowing whether the new `curr` span was // **originally** the same as the original span of `prev()`. The original spans // reflect their original sort order, and for equal spans, conveys a partial // ordering based on CFG dominator priority. - if self.prev().is_macro_expansion() && self.curr().is_macro_expansion() { + if prev.is_macro_expansion() && curr.is_macro_expansion() { // Macros that expand to include branching (such as // `assert_eq!()`, `assert_ne!()`, `info!()`, `debug!()`, or // `trace!()`) typically generate callee spans with identical @@ -337,23 +339,24 @@ impl<'a> CoverageSpansGenerator<'a> { debug!( " curr and prev are part of a macro expansion, and curr has the same span \ as prev, but is in a different bcb. Drop curr and keep prev for next iter. \ - prev={:?}", - self.prev() + prev={prev:?}", ); - self.take_curr(); + self.take_curr(); // Discards curr. } else { - self.hold_pending_dups_unless_dominated(); + self.update_pending_dups(); } } else { self.cutoff_prev_at_overlapping_curr(); - self.check_invoked_macro_name_span(); + self.maybe_push_macro_name_span(); } } - debug!(" AT END, adding last prev={:?}", self.prev()); let prev = self.take_prev(); - let pending_dups = self.pending_dups.split_off(0); - for dup in pending_dups { + debug!(" AT END, adding last prev={prev:?}"); + + // Take `pending_dups` so that we can drain it while calling self methods. + // It is never used as a field after this point. + for dup in std::mem::take(&mut self.pending_dups) { debug!(" ...adding at least one pending dup={:?}", dup); self.push_refined_span(dup); } @@ -383,43 +386,40 @@ impl<'a> CoverageSpansGenerator<'a> { } fn push_refined_span(&mut self, covspan: CoverageSpan) { - let len = self.refined_spans.len(); - if len > 0 { - let last = &mut self.refined_spans[len - 1]; - if last.is_mergeable(&covspan) { - debug!( - "merging new refined span with last refined span, last={:?}, covspan={:?}", - last, covspan - ); - last.merge_from(covspan); - return; - } + if let Some(last) = self.refined_spans.last_mut() + && last.is_mergeable(&covspan) + { + // Instead of pushing the new span, merge it with the last refined span. + debug!(?last, ?covspan, "merging new refined span with last refined span"); + last.merge_from(covspan); + } else { + self.refined_spans.push(covspan); } - self.refined_spans.push(covspan) } - fn check_invoked_macro_name_span(&mut self) { - if let Some(visible_macro) = self.curr().visible_macro(self.body_span) { - if !self - .prev_expn_span - .is_some_and(|prev_expn_span| self.curr().expn_span.ctxt() == prev_expn_span.ctxt()) - { - let merged_prefix_len = self.curr_original_span.lo() - self.curr().span.lo(); - let after_macro_bang = - merged_prefix_len + BytePos(visible_macro.as_str().len() as u32 + 1); - let mut macro_name_cov = self.curr().clone(); - self.curr_mut().span = - self.curr().span.with_lo(self.curr().span.lo() + after_macro_bang); - macro_name_cov.span = - macro_name_cov.span.with_hi(macro_name_cov.span.lo() + after_macro_bang); - debug!( - " and curr starts a new macro expansion, so add a new span just for \ - the macro `{}!`, new span={:?}", - visible_macro, macro_name_cov - ); - self.push_refined_span(macro_name_cov); - } + /// If `curr` is part of a new macro expansion, carve out and push a separate + /// span that ends just after the macro name and its subsequent `!`. + fn maybe_push_macro_name_span(&mut self) { + let curr = self.curr(); + + let Some(visible_macro) = curr.visible_macro(self.body_span) else { return }; + if let Some(prev) = &self.some_prev + && prev.expn_span.ctxt() == curr.expn_span.ctxt() + { + return; } + + let merged_prefix_len = self.curr_original_span.lo() - curr.span.lo(); + let after_macro_bang = merged_prefix_len + BytePos(visible_macro.as_str().len() as u32 + 1); + let mut macro_name_cov = curr.clone(); + self.curr_mut().span = curr.span.with_lo(curr.span.lo() + after_macro_bang); + macro_name_cov.span = + macro_name_cov.span.with_hi(macro_name_cov.span.lo() + after_macro_bang); + debug!( + " and curr starts a new macro expansion, so add a new span just for \ + the macro `{visible_macro}!`, new span={macro_name_cov:?}", + ); + self.push_refined_span(macro_name_cov); } fn curr(&self) -> &CoverageSpan { @@ -434,6 +434,12 @@ impl<'a> CoverageSpansGenerator<'a> { .unwrap_or_else(|| bug!("invalid attempt to unwrap a None some_curr")) } + /// If called, then the next call to `next_coverage_span()` will *not* update `prev` with the + /// `curr` coverage span. + fn take_curr(&mut self) -> CoverageSpan { + self.some_curr.take().unwrap_or_else(|| bug!("invalid attempt to unwrap a None some_curr")) + } + fn prev(&self) -> &CoverageSpan { self.some_prev .as_ref() @@ -459,82 +465,78 @@ impl<'a> CoverageSpansGenerator<'a> { /// `pending_dups` could have as few as one span) /// In either case, no more spans will match the span of `pending_dups`, so /// add the `pending_dups` if they don't overlap `curr`, and clear the list. - fn check_pending_dups(&mut self) { - if let Some(dup) = self.pending_dups.last() && dup.span != self.prev().span { - debug!( - " SAME spans, but pending_dups are NOT THE SAME, so BCBs matched on \ - previous iteration, or prev started a new disjoint span" - ); - if dup.span.hi() <= self.curr().span.lo() { - let pending_dups = self.pending_dups.split_off(0); - for dup in pending_dups.into_iter() { - debug!(" ...adding at least one pending={:?}", dup); - self.push_refined_span(dup); - } - } else { - self.pending_dups.clear(); + fn maybe_flush_pending_dups(&mut self) { + let Some(last_dup) = self.pending_dups.last() else { return }; + if last_dup.span == self.prev().span { + return; + } + + debug!( + " SAME spans, but pending_dups are NOT THE SAME, so BCBs matched on \ + previous iteration, or prev started a new disjoint span" + ); + if last_dup.span.hi() <= self.curr().span.lo() { + // Temporarily steal `pending_dups` into a local, so that we can + // drain it while calling other self methods. + let mut pending_dups = std::mem::take(&mut self.pending_dups); + for dup in pending_dups.drain(..) { + debug!(" ...adding at least one pending={:?}", dup); + self.push_refined_span(dup); } + // The list of dups is now empty, but we can recycle its capacity. + assert!(pending_dups.is_empty() && self.pending_dups.is_empty()); + self.pending_dups = pending_dups; + } else { + self.pending_dups.clear(); } } /// Advance `prev` to `curr` (if any), and `curr` to the next `CoverageSpan` in sorted order. fn next_coverage_span(&mut self) -> bool { if let Some(curr) = self.some_curr.take() { - self.prev_expn_span = Some(curr.expn_span); self.some_prev = Some(curr); self.prev_original_span = self.curr_original_span; } while let Some(curr) = self.sorted_spans_iter.next() { debug!("FOR curr={:?}", curr); - if self.some_prev.is_some() && self.prev_starts_after_next(&curr) { + if let Some(prev) = &self.some_prev && prev.span.lo() > curr.span.lo() { + // Skip curr because prev has already advanced beyond the end of curr. + // This can only happen if a prior iteration updated `prev` to skip past + // a region of code, such as skipping past a closure. debug!( " prev.span starts after curr.span, so curr will be dropped (skipping past \ - closure?); prev={:?}", - self.prev() + closure?); prev={prev:?}", ); } else { // Save a copy of the original span for `curr` in case the `CoverageSpan` is changed // by `self.curr_mut().merge_from(prev)`. self.curr_original_span = curr.span; self.some_curr.replace(curr); - self.check_pending_dups(); + self.maybe_flush_pending_dups(); return true; } } false } - /// If called, then the next call to `next_coverage_span()` will *not* update `prev` with the - /// `curr` coverage span. - fn take_curr(&mut self) -> CoverageSpan { - self.some_curr.take().unwrap_or_else(|| bug!("invalid attempt to unwrap a None some_curr")) - } - - /// Returns true if the curr span should be skipped because prev has already advanced beyond the - /// end of curr. This can only happen if a prior iteration updated `prev` to skip past a region - /// of code, such as skipping past a closure. - fn prev_starts_after_next(&self, next_curr: &CoverageSpan) -> bool { - self.prev().span.lo() > next_curr.span.lo() - } - - /// Returns true if the curr span starts past the end of the prev span, which means they don't - /// overlap, so we now know the prev can be added to the refined coverage spans. - fn prev_ends_before_curr(&self) -> bool { - self.prev().span.hi() <= self.curr().span.lo() - } - /// If `prev`s span extends left of the closure (`curr`), carve out the closure's span from /// `prev`'s span. (The closure's coverage counters will be injected when processing the /// closure's own MIR.) Add the portion of the span to the left of the closure; and if the span /// extends to the right of the closure, update `prev` to that portion of the span. For any /// `pending_dups`, repeat the same process. fn carve_out_span_for_closure(&mut self) { - let curr_span = self.curr().span; - let left_cutoff = curr_span.lo(); - let right_cutoff = curr_span.hi(); - let has_pre_closure_span = self.prev().span.lo() < right_cutoff; - let has_post_closure_span = self.prev().span.hi() > right_cutoff; - let mut pending_dups = self.pending_dups.split_off(0); + let prev = self.prev(); + let curr = self.curr(); + + let left_cutoff = curr.span.lo(); + let right_cutoff = curr.span.hi(); + let has_pre_closure_span = prev.span.lo() < right_cutoff; + let has_post_closure_span = prev.span.hi() > right_cutoff; + + // Temporarily steal `pending_dups` into a local, so that we can + // mutate and/or drain it while calling other self methods. + let mut pending_dups = std::mem::take(&mut self.pending_dups); + if has_pre_closure_span { let mut pre_closure = self.prev().clone(); pre_closure.span = pre_closure.span.with_hi(left_cutoff); @@ -548,6 +550,7 @@ impl<'a> CoverageSpansGenerator<'a> { } self.push_refined_span(pre_closure); } + if has_post_closure_span { // Mutate `prev.span()` to start after the closure (and discard curr). // (**NEVER** update `prev_original_span` because it affects the assumptions @@ -558,12 +561,15 @@ impl<'a> CoverageSpansGenerator<'a> { debug!(" ...and at least one overlapping dup={:?}", dup); dup.span = dup.span.with_lo(right_cutoff); } - self.pending_dups.append(&mut pending_dups); - let closure_covspan = self.take_curr(); + let closure_covspan = self.take_curr(); // Prevent this curr from becoming prev. self.push_refined_span(closure_covspan); // since self.prev() was already updated } else { pending_dups.clear(); } + + // Restore the modified post-closure spans, or the empty vector's capacity. + assert!(self.pending_dups.is_empty()); + self.pending_dups = pending_dups; } /// Called if `curr.span` equals `prev_original_span` (and potentially equal to all @@ -580,26 +586,28 @@ impl<'a> CoverageSpansGenerator<'a> { /// neither `CoverageSpan` dominates the other, both (or possibly more than two) are held, /// until their disposition is determined. In this latter case, the `prev` dup is moved into /// `pending_dups` so the new `curr` dup can be moved to `prev` for the next iteration. - fn hold_pending_dups_unless_dominated(&mut self) { + fn update_pending_dups(&mut self) { + let prev_bcb = self.prev().bcb; + let curr_bcb = self.curr().bcb; + // Equal coverage spans are ordered by dominators before dominated (if any), so it should be // impossible for `curr` to dominate any previous `CoverageSpan`. - debug_assert!(!self.span_bcb_dominates(self.curr(), self.prev())); + debug_assert!(!self.basic_coverage_blocks.dominates(curr_bcb, prev_bcb)); let initial_pending_count = self.pending_dups.len(); if initial_pending_count > 0 { - let mut pending_dups = self.pending_dups.split_off(0); - pending_dups.retain(|dup| !self.span_bcb_dominates(dup, self.curr())); - self.pending_dups.append(&mut pending_dups); - if self.pending_dups.len() < initial_pending_count { + self.pending_dups + .retain(|dup| !self.basic_coverage_blocks.dominates(dup.bcb, curr_bcb)); + + let n_discarded = initial_pending_count - self.pending_dups.len(); + if n_discarded > 0 { debug!( - " discarded {} of {} pending_dups that dominated curr", - initial_pending_count - self.pending_dups.len(), - initial_pending_count + " discarded {n_discarded} of {initial_pending_count} pending_dups that dominated curr", ); } } - if self.span_bcb_dominates(self.prev(), self.curr()) { + if self.basic_coverage_blocks.dominates(prev_bcb, curr_bcb) { debug!( " different bcbs but SAME spans, and prev dominates curr. Discard prev={:?}", self.prev() @@ -664,8 +672,4 @@ impl<'a> CoverageSpansGenerator<'a> { self.pending_dups.clear(); } } - - fn span_bcb_dominates(&self, dom_covspan: &CoverageSpan, covspan: &CoverageSpan) -> bool { - self.basic_coverage_blocks.dominates(dom_covspan.bcb, covspan.bcb) - } } diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index c7529b954fe..c710e460dcb 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -319,7 +319,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } if let Some(local) = self.try_as_local(value, location) - && local != place.local // in case we had no projection to begin with. + && local != place.local + // in case we had no projection to begin with. { *place = local.into(); self.reused_locals.insert(local); diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 32dfb743905..06ae070c908 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -503,7 +503,9 @@ impl<'tcx> Inliner<'tcx> { self.tcx, ty::EarlyBinder::bind(&place.ty(callee_body, tcx).ty), ); - if ty.needs_drop(tcx, self.param_env) && let UnwindAction::Cleanup(unwind) = unwind { + if ty.needs_drop(tcx, self.param_env) + && let UnwindAction::Cleanup(unwind) = unwind + { work_list.push(unwind); } } else if callee_attrs.instruction_set != self.codegen_fn_attrs.instruction_set @@ -842,7 +844,9 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => { let fn_ty = self.instance.instantiate_mir(tcx, ty::EarlyBinder::bind(&f.const_.ty())); - self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) { + self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() + && tcx.is_intrinsic(def_id) + { // Don't give intrinsics the extra penalty for calls INSTR_COST } else { diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index a6ef2e11aa8..fbcd6e75ad4 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -93,7 +93,9 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { _ => None, }; - if let Some(new) = new && self.should_simplify(source_info, rvalue) { + if let Some(new) = new + && self.should_simplify(source_info, rvalue) + { *rvalue = new; } } @@ -150,7 +152,8 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { *rvalue = Rvalue::Use(operand.clone()); } else if *kind == CastKind::Transmute { // Transmuting an integer to another integer is just a signedness cast - if let (ty::Int(int), ty::Uint(uint)) | (ty::Uint(uint), ty::Int(int)) = (operand_ty.kind(), cast_ty.kind()) + if let (ty::Int(int), ty::Uint(uint)) | (ty::Uint(uint), ty::Int(int)) = + (operand_ty.kind(), cast_ty.kind()) && int.bit_width() == uint.bit_width() { // The width check isn't strictly necessary, as different widths @@ -172,8 +175,15 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { for (i, field) in variant.fields.iter().enumerate() { let field_ty = field.ty(self.tcx, args); if field_ty == *cast_ty { - let place = place.project_deeper(&[ProjectionElem::Field(FieldIdx::from_usize(i), *cast_ty)], self.tcx); - let operand = if operand.is_move() { Operand::Move(place) } else { Operand::Copy(place) }; + let place = place.project_deeper( + &[ProjectionElem::Field(FieldIdx::from_usize(i), *cast_ty)], + self.tcx, + ); + let operand = if operand.is_move() { + Operand::Move(place) + } else { + Operand::Copy(place) + }; *rvalue = Rvalue::Use(operand); return; } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 9ee2f6dcea0..78f76f1e513 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -162,37 +162,50 @@ fn remap_mir_for_const_eval_select<'tcx>( && tcx.item_name(def_id) == sym::const_eval_select && tcx.is_intrinsic(def_id) => { - let [tupled_args, called_in_const, called_at_rt]: [_; 3] = std::mem::take(args).try_into().unwrap(); + let [tupled_args, called_in_const, called_at_rt]: [_; 3] = + std::mem::take(args).try_into().unwrap(); let ty = tupled_args.ty(&body.local_decls, tcx); let fields = ty.tuple_fields(); let num_args = fields.len(); - let func = if context == hir::Constness::Const { called_in_const } else { called_at_rt }; - let (method, place): (fn(Place<'tcx>) -> Operand<'tcx>, Place<'tcx>) = match tupled_args { - Operand::Constant(_) => { - // there is no good way of extracting a tuple arg from a constant (const generic stuff) - // so we just create a temporary and deconstruct that. - let local = body.local_decls.push(LocalDecl::new(ty, fn_span)); - bb.statements.push(Statement { - source_info: SourceInfo::outermost(fn_span), - kind: StatementKind::Assign(Box::new((local.into(), Rvalue::Use(tupled_args.clone())))), - }); - (Operand::Move, local.into()) - } - Operand::Move(place) => (Operand::Move, place), - Operand::Copy(place) => (Operand::Copy, place), - }; - let place_elems = place.projection; - let arguments = (0..num_args).map(|x| { - let mut place_elems = place_elems.to_vec(); - place_elems.push(ProjectionElem::Field(x.into(), fields[x])); - let projection = tcx.mk_place_elems(&place_elems); - let place = Place { - local: place.local, - projection, + let func = + if context == hir::Constness::Const { called_in_const } else { called_at_rt }; + let (method, place): (fn(Place<'tcx>) -> Operand<'tcx>, Place<'tcx>) = + match tupled_args { + Operand::Constant(_) => { + // there is no good way of extracting a tuple arg from a constant (const generic stuff) + // so we just create a temporary and deconstruct that. + let local = body.local_decls.push(LocalDecl::new(ty, fn_span)); + bb.statements.push(Statement { + source_info: SourceInfo::outermost(fn_span), + kind: StatementKind::Assign(Box::new(( + local.into(), + Rvalue::Use(tupled_args.clone()), + ))), + }); + (Operand::Move, local.into()) + } + Operand::Move(place) => (Operand::Move, place), + Operand::Copy(place) => (Operand::Copy, place), }; - method(place) - }).collect(); - terminator.kind = TerminatorKind::Call { func, args: arguments, destination, target, unwind, call_source: CallSource::Misc, fn_span }; + let place_elems = place.projection; + let arguments = (0..num_args) + .map(|x| { + let mut place_elems = place_elems.to_vec(); + place_elems.push(ProjectionElem::Field(x.into(), fields[x])); + let projection = tcx.mk_place_elems(&place_elems); + let place = Place { local: place.local, projection }; + method(place) + }) + .collect(); + terminator.kind = TerminatorKind::Call { + func, + args: arguments, + destination, + target, + unwind, + call_source: CallSource::Misc, + fn_span, + }; } _ => {} } diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index 22f9c6f4f85..5f3d8dfc6c4 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -166,12 +166,16 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { let [arg] = args.as_slice() else { span_bug!(terminator.source_info.span, "Wrong number of arguments"); }; - let derefed_place = - if let Some(place) = arg.place() && let Some(local) = place.as_local() { - tcx.mk_place_deref(local.into()) - } else { - span_bug!(terminator.source_info.span, "Only passing a local is supported"); - }; + let derefed_place = if let Some(place) = arg.place() + && let Some(local) = place.as_local() + { + tcx.mk_place_deref(local.into()) + } else { + span_bug!( + terminator.source_info.span, + "Only passing a local is supported" + ); + }; // Add new statement at the end of the block that does the read, and patch // up the terminator. block.statements.push(Statement { @@ -198,12 +202,16 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { "Wrong number of arguments for write_via_move intrinsic", ); }; - let derefed_place = - if let Some(place) = ptr.place() && let Some(local) = place.as_local() { - tcx.mk_place_deref(local.into()) - } else { - span_bug!(terminator.source_info.span, "Only passing a local is supported"); - }; + let derefed_place = if let Some(place) = ptr.place() + && let Some(local) = place.as_local() + { + tcx.mk_place_deref(local.into()) + } else { + span_bug!( + terminator.source_info.span, + "Only passing a local is supported" + ); + }; block.statements.push(Statement { source_info: terminator.source_info, kind: StatementKind::Assign(Box::new(( diff --git a/compiler/rustc_mir_transform/src/lower_slice_len.rs b/compiler/rustc_mir_transform/src/lower_slice_len.rs index ac52f0ae112..ae487841179 100644 --- a/compiler/rustc_mir_transform/src/lower_slice_len.rs +++ b/compiler/rustc_mir_transform/src/lower_slice_len.rs @@ -64,8 +64,7 @@ fn lower_slice_len_call<'tcx>( // make new RValue for Len let deref_arg = tcx.mk_place_deref(arg); let r_value = Rvalue::Len(deref_arg); - let len_statement_kind = - StatementKind::Assign(Box::new((*destination, r_value))); + let len_statement_kind = StatementKind::Assign(Box::new((*destination, r_value))); let add_statement = Statement { kind: len_statement_kind, source_info: terminator.source_info }; diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs index d1a4b26a046..206cdf9fe28 100644 --- a/compiler/rustc_mir_transform/src/normalize_array_len.rs +++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs @@ -57,7 +57,9 @@ fn compute_slice_length<'tcx>( } // The length information is stored in the fat pointer, so we treat `operand` as a value. Rvalue::Use(operand) => { - if let Some(rhs) = operand.place() && let Some(rhs) = rhs.as_local() { + if let Some(rhs) = operand.place() + && let Some(rhs) = rhs.as_local() + { slice_lengths[local] = slice_lengths[rhs]; } } diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs index 67941cf4395..df39c819ba9 100644 --- a/compiler/rustc_mir_transform/src/ref_prop.rs +++ b/compiler/rustc_mir_transform/src/ref_prop.rs @@ -210,14 +210,17 @@ fn compute_replacement<'tcx>( // have been visited before. Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) | Rvalue::CopyForDeref(place) => { - if let Some(rhs) = place.as_local() && ssa.is_ssa(rhs) { + if let Some(rhs) = place.as_local() + && ssa.is_ssa(rhs) + { let target = targets[rhs]; // Only see through immutable reference and pointers, as we do not know yet if // mutable references are fully replaced. if !needs_unique && matches!(target, Value::Pointer(..)) { targets[local] = target; } else { - targets[local] = Value::Pointer(tcx.mk_place_deref(rhs.into()), needs_unique); + targets[local] = + Value::Pointer(tcx.mk_place_deref(rhs.into()), needs_unique); } } } @@ -365,7 +368,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> { *place = Place::from(target.local).project_deeper(rest, self.tcx); self.any_replacement = true; } else { - break + break; } } diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index a34d4b02764..b4784b69f7f 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -126,7 +126,10 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> { && let ty = place_for_ty.ty(self.local_decls, self.tcx).ty && self.known_to_be_zst(ty) && self.tcx.consider_optimizing(|| { - format!("RemoveZsts - Place: {:?} SourceInfo: {:?}", place_for_ty, statement.source_info) + format!( + "RemoveZsts - Place: {:?} SourceInfo: {:?}", + place_for_ty, statement.source_info + ) }) { statement.make_nop(); diff --git a/compiler/rustc_parse/src/lexer/diagnostics.rs b/compiler/rustc_parse/src/lexer/diagnostics.rs index b50bb47f297..b1bd4ac75e5 100644 --- a/compiler/rustc_parse/src/lexer/diagnostics.rs +++ b/compiler/rustc_parse/src/lexer/diagnostics.rs @@ -111,9 +111,10 @@ pub fn report_suspicious_mismatch_block( // If there is no suspicious span, give the last properly closed block may help if let Some(parent) = diag_info.matching_block_spans.last() && diag_info.open_braces.last().is_none() - && diag_info.empty_block_spans.iter().all(|&sp| sp != parent.0.to(parent.1)) { - err.span_label(parent.0, "this opening brace..."); - err.span_label(parent.1, "...matches this closing brace"); + && diag_info.empty_block_spans.iter().all(|&sp| sp != parent.0.to(parent.1)) + { + err.span_label(parent.0, "this opening brace..."); + err.span_label(parent.1, "...matches this closing brace"); } } } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 59498978948..75e3393aa96 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -314,11 +314,10 @@ impl<'a> Parser<'a> { // which uses `Symbol::to_ident_string()` and "helpfully" adds an implicit `r#` let ident_name = ident.name.to_string(); - Some(SuggEscapeIdentifier { - span: ident.span.shrink_to_lo(), - ident_name - }) - } else { None }; + Some(SuggEscapeIdentifier { span: ident.span.shrink_to_lo(), ident_name }) + } else { + None + }; let suggest_remove_comma = if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) { @@ -375,9 +374,11 @@ impl<'a> Parser<'a> { // and current token should be Ident with the item name (i.e. the function name) // if there is a `<` after the fn name, then don't show a suggestion, show help - if !self.look_ahead(1, |t| *t == token::Lt) && - let Ok(snippet) = self.sess.source_map().span_to_snippet(generic.span) { - err.multipart_suggestion_verbose( + if !self.look_ahead(1, |t| *t == token::Lt) + && let Ok(snippet) = + self.sess.source_map().span_to_snippet(generic.span) + { + err.multipart_suggestion_verbose( format!("place the generic parameter name after the {ident_name} name"), vec![ (self.token.span.shrink_to_hi(), snippet), @@ -385,11 +386,11 @@ impl<'a> Parser<'a> { ], Applicability::MaybeIncorrect, ); - } else { - err.help(format!( - "place the generic parameter name after the {ident_name} name" - )); - } + } else { + err.help(format!( + "place the generic parameter name after the {ident_name} name" + )); + } } } Err(err) => { @@ -402,7 +403,9 @@ impl<'a> Parser<'a> { } } - if let Some(recovered_ident) = recovered_ident && recover { + if let Some(recovered_ident) = recovered_ident + && recover + { err.emit(); Ok(recovered_ident) } else { @@ -617,19 +620,19 @@ impl<'a> Parser<'a> { } if let TokenKind::Ident(prev, _) = &self.prev_token.kind - && let TokenKind::Ident(cur, _) = &self.token.kind + && let TokenKind::Ident(cur, _) = &self.token.kind { - let concat = Symbol::intern(&format!("{prev}{cur}")); - let ident = Ident::new(concat, DUMMY_SP); - if ident.is_used_keyword() || ident.is_reserved() || ident.is_raw_guess() { - let span = self.prev_token.span.to(self.token.span); - err.span_suggestion_verbose( - span, - format!("consider removing the space to spell keyword `{concat}`"), - concat, - Applicability::MachineApplicable, - ); - } + let concat = Symbol::intern(&format!("{prev}{cur}")); + let ident = Ident::new(concat, DUMMY_SP); + if ident.is_used_keyword() || ident.is_reserved() || ident.is_raw_guess() { + let span = self.prev_token.span.to(self.token.span); + err.span_suggestion_verbose( + span, + format!("consider removing the space to spell keyword `{concat}`"), + concat, + Applicability::MachineApplicable, + ); + } } // `pub` may be used for an item or `pub(crate)` @@ -1084,8 +1087,7 @@ impl<'a> Parser<'a> { .emit(); match self.parse_expr() { Ok(_) => { - *expr = - self.mk_expr_err(expr.span.to(self.prev_token.span)); + *expr = self.mk_expr_err(expr.span.to(self.prev_token.span)); return Ok(()); } Err(err) => { @@ -1277,7 +1279,9 @@ impl<'a> Parser<'a> { return if token::ModSep == self.token.kind { // We have some certainty that this was a bad turbofish at this point. // `foo< bar >::` - if let ExprKind::Binary(o, ..) = inner_op.kind && o.node == BinOpKind::Lt { + if let ExprKind::Binary(o, ..) = inner_op.kind + && o.node == BinOpKind::Lt + { err.suggest_turbofish = Some(op.span.shrink_to_lo()); } else { err.help_turbofish = Some(()); @@ -1307,7 +1311,9 @@ impl<'a> Parser<'a> { } else if token::OpenDelim(Delimiter::Parenthesis) == self.token.kind { // We have high certainty that this was a bad turbofish at this point. // `foo< bar >(` - if let ExprKind::Binary(o, ..) = inner_op.kind && o.node == BinOpKind::Lt { + if let ExprKind::Binary(o, ..) = inner_op.kind + && o.node == BinOpKind::Lt + { err.suggest_turbofish = Some(op.span.shrink_to_lo()); } else { err.help_turbofish = Some(()); @@ -1885,19 +1891,21 @@ impl<'a> Parser<'a> { let sm = self.sess.source_map(); let left = begin_par_sp; let right = self.prev_token.span; - let left_snippet = if let Ok(snip) = sm.span_to_prev_source(left) && - !snip.ends_with(' ') { - " ".to_string() - } else { - "".to_string() - }; + let left_snippet = if let Ok(snip) = sm.span_to_prev_source(left) + && !snip.ends_with(' ') + { + " ".to_string() + } else { + "".to_string() + }; - let right_snippet = if let Ok(snip) = sm.span_to_next_source(right) && - !snip.starts_with(' ') { - " ".to_string() - } else { - "".to_string() - }; + let right_snippet = if let Ok(snip) = sm.span_to_next_source(right) + && !snip.starts_with(' ') + { + " ".to_string() + } else { + "".to_string() + }; self.sess.emit_err(ParenthesesInForHead { span: vec![left, right], diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index a9f497e55e6..44cb90227e7 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1007,8 +1007,9 @@ impl<'a> Parser<'a> { let span = self.token.span; let sm = self.sess.source_map(); let (span, actual) = match (&self.token.kind, self.subparser_name) { - (token::Eof, Some(_)) if let Ok(actual) = sm.span_to_snippet(sm.next_point(span)) => - (span.shrink_to_hi(), actual.into()), + (token::Eof, Some(_)) if let Ok(actual) = sm.span_to_snippet(sm.next_point(span)) => { + (span.shrink_to_hi(), actual.into()) + } _ => (span, actual), }; self.sess.emit_err(errors::UnexpectedTokenAfterDot { span, actual }); @@ -1550,10 +1551,7 @@ impl<'a> Parser<'a> { self.sess.emit_err(errors::MacroInvocationWithQualifiedPath(path.span)); } let lo = path.span; - let mac = P(MacCall { - path, - args: self.parse_delim_args()?, - }); + let mac = P(MacCall { path, args: self.parse_delim_args()? }); (lo.to(self.prev_token.span), ExprKind::MacCall(mac)) } else if self.check(&token::OpenDelim(Delimiter::Brace)) && let Some(expr) = self.maybe_parse_struct_expr(&qself, &path) @@ -1771,7 +1769,9 @@ impl<'a> Parser<'a> { fn parse_expr_break(&mut self) -> PResult<'a, P<Expr>> { let lo = self.prev_token.span; let mut label = self.eat_label(); - let kind = if self.token == token::Colon && let Some(label) = label.take() { + let kind = if self.token == token::Colon + && let Some(label) = label.take() + { // The value expression can be a labeled loop, see issue #86948, e.g.: // `loop { break 'label: loop { break 'label 42; }; }` let lexpr = self.parse_expr_labeled(label, true)?; @@ -2377,16 +2377,18 @@ impl<'a> Parser<'a> { let mut recover_block_from_condition = |this: &mut Self| { let block = match &mut cond.kind { ExprKind::Binary(Spanned { span: binop_span, .. }, _, right) - if let ExprKind::Block(_, None) = right.kind => { - self.sess.emit_err(errors::IfExpressionMissingThenBlock { - if_span: lo, - missing_then_block_sub: - errors::IfExpressionMissingThenBlockSub::UnfinishedCondition(cond_span.shrink_to_lo().to(*binop_span)), - let_else_sub: None, - - }); - std::mem::replace(right, this.mk_expr_err(binop_span.shrink_to_hi())) - }, + if let ExprKind::Block(_, None) = right.kind => + { + self.sess.emit_err(errors::IfExpressionMissingThenBlock { + if_span: lo, + missing_then_block_sub: + errors::IfExpressionMissingThenBlockSub::UnfinishedCondition( + cond_span.shrink_to_lo().to(*binop_span), + ), + let_else_sub: None, + }); + std::mem::replace(right, this.mk_expr_err(binop_span.shrink_to_hi())) + } ExprKind::Block(_, None) => { self.sess.emit_err(errors::IfExpressionMissingCondition { if_span: lo.shrink_to_hi(), @@ -2569,13 +2571,16 @@ impl<'a> Parser<'a> { } fn error_on_extra_if(&mut self, cond: &P<Expr>) -> PResult<'a, ()> { - if let ExprKind::Binary(Spanned { span: binop_span, node: binop}, _, right) = &cond.kind && - let BinOpKind::And = binop && - let ExprKind::If(cond, ..) = &right.kind { - Err(self.sess.create_err(errors::UnexpectedIfWithIf(binop_span.shrink_to_hi().to(cond.span.shrink_to_lo())))) - } else { - Ok(()) - } + if let ExprKind::Binary(Spanned { span: binop_span, node: binop }, _, right) = &cond.kind + && let BinOpKind::And = binop + && let ExprKind::If(cond, ..) = &right.kind + { + Err(self.sess.create_err(errors::UnexpectedIfWithIf( + binop_span.shrink_to_hi().to(cond.span.shrink_to_lo()), + ))) + } else { + Ok(()) + } } /// Parses `for <src_pat> in <src_expr> <src_loop_block>` (`for` token already eaten). @@ -2923,9 +2928,9 @@ impl<'a> Parser<'a> { .or_else(|mut err| { if this.token == token::FatArrow { if let Ok(expr_lines) = sm.span_to_lines(expr.span) - && let Ok(arm_start_lines) = sm.span_to_lines(arm_start_span) - && arm_start_lines.lines[0].end_col == expr_lines.lines[0].end_col - && expr_lines.lines.len() == 2 + && let Ok(arm_start_lines) = sm.span_to_lines(arm_start_span) + && arm_start_lines.lines[0].end_col == expr_lines.lines[0].end_col + && expr_lines.lines.len() == 2 { // We check whether there's any trailing code in the parse span, // if there isn't, we very likely have the following: @@ -3181,7 +3186,7 @@ impl<'a> Parser<'a> { e.span_suggestion_verbose( self.token.span.shrink_to_lo(), "try naming a field", - &format!("{ident}: ", ), + &format!("{ident}: ",), Applicability::MaybeIncorrect, ); } @@ -3574,8 +3579,7 @@ impl MutVisitor for CondChecker<'_> { noop_visit_expr(e, self); self.forbid_let_reason = forbid_let_reason; } - ExprKind::Cast(ref mut op, _) - | ExprKind::Type(ref mut op, _) => { + ExprKind::Cast(ref mut op, _) | ExprKind::Type(ref mut op, _) => { let forbid_let_reason = self.forbid_let_reason; self.forbid_let_reason = Some(OtherForbidden); self.visit_expr(op); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index cc54cc5bebb..982f601c0d5 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -122,7 +122,9 @@ impl<'a> Parser<'a> { ) -> PResult<'a, Option<Item>> { // Don't use `maybe_whole` so that we have precise control // over when we bump the parser - if let token::Interpolated(nt) = &self.token.kind && let token::NtItem(item) = &**nt { + if let token::Interpolated(nt) = &self.token.kind + && let token::NtItem(item) = &**nt + { let mut item = item.clone(); self.bump(); @@ -623,11 +625,10 @@ impl<'a> Parser<'a> { // `impl<T: Default> impl Default for Wrapper<T>` // ^^^^^ let extra_impl_kw = ty_first.span.until(bound.span()); - self.sess - .emit_err(errors::ExtraImplKeywordInTraitImpl { - extra_impl_kw, - impl_trait_span: ty_first.span - }); + self.sess.emit_err(errors::ExtraImplKeywordInTraitImpl { + extra_impl_kw, + impl_trait_span: ty_first.span, + }); } else { self.sess.emit_err(errors::ExpectedTraitInTraitImplFoundType { span: ty_first.span, @@ -1306,7 +1307,9 @@ impl<'a> Parser<'a> { // Provide a nice error message if the user placed a where-clause before the item body. // Users may be tempted to write such code if they are still used to the deprecated // where-clause location on type aliases and associated types. See also #89122. - if before_where_clause.has_where_token && let Some(expr) = &expr { + if before_where_clause.has_where_token + && let Some(expr) = &expr + { self.sess.emit_err(errors::WhereClauseBeforeConstBody { span: before_where_clause.span, name: ident.span, @@ -1949,7 +1952,8 @@ impl<'a> Parser<'a> { let mut err = self.expected_ident_found_err(); if self.eat_keyword_noexpect(kw::Let) && let removal_span = self.prev_token.span.until(self.token.span) - && let Ok(ident) = self.parse_ident_common(false) + && let Ok(ident) = self + .parse_ident_common(false) // Cancel this error, we don't need it. .map_err(|err| err.cancel()) && self.token.kind == TokenKind::Colon diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 6c24646f39a..597303cae73 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -558,8 +558,9 @@ impl<'a> Parser<'a> { } if case == Case::Insensitive - && let Some((ident, /* is_raw */ false)) = self.token.ident() - && ident.as_str().to_lowercase() == kw.as_str().to_lowercase() { + && let Some((ident, /* is_raw */ false)) = self.token.ident() + && ident.as_str().to_lowercase() == kw.as_str().to_lowercase() + { true } else { false @@ -587,12 +588,10 @@ impl<'a> Parser<'a> { } if case == Case::Insensitive - && let Some((ident, /* is_raw */ false)) = self.token.ident() - && ident.as_str().to_lowercase() == kw.as_str().to_lowercase() { - self.sess.emit_err(errors::KwBadCase { - span: ident.span, - kw: kw.as_str() - }); + && let Some((ident, /* is_raw */ false)) = self.token.ident() + && ident.as_str().to_lowercase() == kw.as_str().to_lowercase() + { + self.sess.emit_err(errors::KwBadCase { span: ident.span, kw: kw.as_str() }); self.bump(); return true; } diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index ff059a7e865..025b0615a7e 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -115,7 +115,7 @@ impl<'a> Parser<'a> { Some(item) => NtItem(item), None => { return Err(UnexpectedNonterminal::Item(self.token.span) - .into_diagnostic(&self.sess.span_diagnostic)); + .into_diagnostic(&self.sess.span_diagnostic)); } }, NonterminalKind::Block => { @@ -127,7 +127,7 @@ impl<'a> Parser<'a> { Some(s) => NtStmt(P(s)), None => { return Err(UnexpectedNonterminal::Statement(self.token.span) - .into_diagnostic(&self.sess.span_diagnostic)); + .into_diagnostic(&self.sess.span_diagnostic)); } }, NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr => { @@ -146,19 +146,15 @@ impl<'a> Parser<'a> { NonterminalKind::Expr => NtExpr(self.parse_expr_force_collect()?), NonterminalKind::Literal => { // The `:literal` matcher does not support attributes - NtLiteral( - self.collect_tokens_no_attrs(|this| this.parse_literal_maybe_minus())?, - ) + NtLiteral(self.collect_tokens_no_attrs(|this| this.parse_literal_maybe_minus())?) } - NonterminalKind::Ty => NtTy( - self.collect_tokens_no_attrs(|this| this.parse_ty_no_question_mark_recover())?, - ), + NonterminalKind::Ty => { + NtTy(self.collect_tokens_no_attrs(|this| this.parse_ty_no_question_mark_recover())?) + } // this could be handled like a token, since it is one - NonterminalKind::Ident - if let Some((ident, is_raw)) = get_macro_ident(&self.token) => - { + NonterminalKind::Ident if let Some((ident, is_raw)) = get_macro_ident(&self.token) => { self.bump(); NtIdent(ident, is_raw) } @@ -166,15 +162,17 @@ impl<'a> Parser<'a> { return Err(UnexpectedNonterminal::Ident { span: self.token.span, token: self.token.clone(), - }.into_diagnostic(&self.sess.span_diagnostic)); + } + .into_diagnostic(&self.sess.span_diagnostic)); + } + NonterminalKind::Path => { + NtPath(P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?)) } - NonterminalKind::Path => NtPath( - P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?), - ), NonterminalKind::Meta => NtMeta(P(self.parse_attr_item(true)?)), - NonterminalKind::Vis => NtVis( - P(self.collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?), - ), + NonterminalKind::Vis => { + NtVis(P(self + .collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?)) + } NonterminalKind::Lifetime => { if self.check_lifetime() { NtLifetime(self.expect_lifetime().ident) @@ -182,7 +180,8 @@ impl<'a> Parser<'a> { return Err(UnexpectedNonterminal::Lifetime { span: self.token.span, token: self.token.clone(), - }.into_diagnostic(&self.sess.span_diagnostic)); + } + .into_diagnostic(&self.sess.span_diagnostic)); } } }; diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 445516c03a1..2fcb9a78cfd 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -764,7 +764,8 @@ impl<'a> Parser<'a> { if let ast::TyKind::Slice(inner_ty) | ast::TyKind::Array(inner_ty, _) = &ty.kind && let ast::TyKind::Err = inner_ty.kind && let Some(snapshot) = snapshot - && let Some(expr) = self.recover_unbraced_const_arg_that_can_begin_ty(snapshot) + && let Some(expr) = + self.recover_unbraced_const_arg_that_can_begin_ty(snapshot) { return Ok(Some(self.dummy_const_arg_needs_braces( self.struct_span_err(expr.span, "invalid const generic expression"), @@ -776,12 +777,10 @@ impl<'a> Parser<'a> { } Err(err) => { if let Some(snapshot) = snapshot - && let Some(expr) = self.recover_unbraced_const_arg_that_can_begin_ty(snapshot) + && let Some(expr) = + self.recover_unbraced_const_arg_that_can_begin_ty(snapshot) { - return Ok(Some(self.dummy_const_arg_needs_braces( - err, - expr.span, - ))); + return Ok(Some(self.dummy_const_arg_needs_braces(err, expr.span))); } // Try to recover from possible `const` arg without braces. return self.recover_const_arg(start, err).map(Some); diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 12c267351b9..e2f59cb2071 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -52,7 +52,9 @@ impl<'a> Parser<'a> { // Don't use `maybe_whole` so that we have precise control // over when we bump the parser - if let token::Interpolated(nt) = &self.token.kind && let token::NtStmt(stmt) = &**nt { + if let token::Interpolated(nt) = &self.token.kind + && let token::NtStmt(stmt) = &**nt + { let mut stmt = stmt.clone(); self.bump(); stmt.visit_attrs(|stmt_attrs| { @@ -227,8 +229,9 @@ impl<'a> Parser<'a> { /// Also error if the previous token was a doc comment. fn error_outer_attrs(&self, attrs: AttrWrapper) { if !attrs.is_empty() - && let attrs = attrs.take_for_recovery(self.sess) - && let attrs @ [.., last] = &*attrs { + && let attrs = attrs.take_for_recovery(self.sess) + && let attrs @ [.., last] = &*attrs + { if last.is_doc_comment() { self.sess.emit_err(errors::DocCommentDoesNotDocumentAnything { span: last.span, @@ -616,15 +619,17 @@ impl<'a> Parser<'a> { match &mut stmt.kind { // Expression without semicolon. StmtKind::Expr(expr) - if self.token != token::Eof && classify::expr_requires_semi_to_be_stmt(expr) => { + if self.token != token::Eof && classify::expr_requires_semi_to_be_stmt(expr) => + { // Just check for errors and recover; do not eat semicolon yet. // `expect_one_of` returns PResult<'a, bool /* recovered */> - let expect_result = self.expect_one_of(&[], &[token::Semi, token::CloseDelim(Delimiter::Brace)]); + let expect_result = + self.expect_one_of(&[], &[token::Semi, token::CloseDelim(Delimiter::Brace)]); let replace_with_err = 'break_recover: { match expect_result { - // Recover from parser, skip type error to avoid extra errors. + // Recover from parser, skip type error to avoid extra errors. Ok(true) => true, Err(mut e) => { if let TokenKind::DocComment(..) = self.token.kind @@ -654,14 +659,19 @@ impl<'a> Parser<'a> { } match &expr.kind { - ExprKind::Path(None, ast::Path { segments, .. }) if segments.len() == 1 => { + ExprKind::Path(None, ast::Path { segments, .. }) + if segments.len() == 1 => + { if self.token == token::Colon && self.look_ahead(1, |token| { - token.is_whole_block() || matches!( - token.kind, - token::Ident(kw::For | kw::Loop | kw::While, false) - | token::OpenDelim(Delimiter::Brace) - ) + token.is_whole_block() + || matches!( + token.kind, + token::Ident( + kw::For | kw::Loop | kw::While, + false + ) | token::OpenDelim(Delimiter::Brace) + ) }) { let snapshot = self.create_snapshot_for_diagnostic(); @@ -702,9 +712,8 @@ impl<'a> Parser<'a> { } true - } - Ok(false) => false + Ok(false) => false, } }; @@ -727,7 +736,9 @@ impl<'a> Parser<'a> { } eat_semi = false; } - StmtKind::Empty | StmtKind::Item(_) | StmtKind::Local(_) | StmtKind::Semi(_) => eat_semi = false, + StmtKind::Empty | StmtKind::Item(_) | StmtKind::Local(_) | StmtKind::Semi(_) => { + eat_semi = false + } } if add_semi_to_stmt || (eat_semi && self.eat(&token::Semi)) { diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 0a64b2f806a..badea5d6133 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -893,13 +893,15 @@ impl<'a> Parser<'a> { // to recover from errors, not make more). let path = if self.may_recover() { let (span, message, sugg, path, applicability) = match &ty.kind { - TyKind::Ptr(..) | TyKind::Ref(..) if let TyKind::Path(_, path) = &ty.peel_refs().kind => { + TyKind::Ptr(..) | TyKind::Ref(..) + if let TyKind::Path(_, path) = &ty.peel_refs().kind => + { ( ty.span.until(path.span), "consider removing the indirection", "", path, - Applicability::MaybeIncorrect + Applicability::MaybeIncorrect, ) } TyKind::ImplTrait(_, bounds) @@ -910,10 +912,10 @@ impl<'a> Parser<'a> { "use the trait bounds directly", "", &tr.trait_ref.path, - Applicability::MachineApplicable + Applicability::MachineApplicable, ) } - _ => return Err(err) + _ => return Err(err), }; err.span_suggestion_verbose(span, message, sugg, applicability); @@ -1027,7 +1029,8 @@ impl<'a> Parser<'a> { args.into_iter() .filter_map(|arg| { if let ast::AngleBracketedArg::Arg(generic_arg) = arg - && let ast::GenericArg::Lifetime(lifetime) = generic_arg { + && let ast::GenericArg::Lifetime(lifetime) = generic_arg + { Some(lifetime) } else { None diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index fbf3dff7560..8b408d8202e 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1076,7 +1076,9 @@ impl CheckAttrVisitor<'_> { ) -> bool { let mut is_valid = true; - if let Some(mi) = attr.meta() && let Some(list) = mi.meta_item_list() { + if let Some(mi) = attr.meta() + && let Some(list) = mi.meta_item_list() + { for meta in list { if let Some(i_meta) = meta.meta_item() { match i_meta.name_or_empty() { @@ -1133,14 +1135,7 @@ impl CheckAttrVisitor<'_> { is_valid = false; } - sym::masked - if !self.check_doc_masked( - attr, - meta, - hir_id, - target, - ) => - { + sym::masked if !self.check_doc_masked(attr, meta, hir_id, target) => { is_valid = false; } @@ -1192,13 +1187,11 @@ impl CheckAttrVisitor<'_> { INVALID_DOC_ATTRIBUTES, hir_id, i_meta.span, - errors::DocTestUnknownSpotlight { - path, - span: i_meta.span - } + errors::DocTestUnknownSpotlight { path, span: i_meta.span }, ); - } else if i_meta.has_name(sym::include) && - let Some(value) = i_meta.value_str() { + } else if i_meta.has_name(sym::include) + && let Some(value) = i_meta.value_str() + { let applicability = if list.len() == 1 { Applicability::MachineApplicable } else { @@ -1213,16 +1206,19 @@ impl CheckAttrVisitor<'_> { errors::DocTestUnknownInclude { path, value: value.to_string(), - inner: match attr.style { AttrStyle::Inner=> "!" , AttrStyle::Outer => "" }, + inner: match attr.style { + AttrStyle::Inner => "!", + AttrStyle::Outer => "", + }, sugg: (attr.meta().unwrap().span, applicability), - } + }, ); } else { self.tcx.emit_spanned_lint( INVALID_DOC_ATTRIBUTES, hir_id, i_meta.span, - errors::DocTestUnknownAny { path } + errors::DocTestUnknownAny { path }, ); } is_valid = false; @@ -2195,8 +2191,9 @@ impl CheckAttrVisitor<'_> { attr.span, errors::MacroExport::Normal, ); - } else if let Some(meta_item_list) = attr.meta_item_list() && - !meta_item_list.is_empty() { + } else if let Some(meta_item_list) = attr.meta_item_list() + && !meta_item_list.is_empty() + { if meta_item_list.len() > 1 { self.tcx.emit_spanned_lint( INVALID_MACRO_EXPORT_ARGUMENTS, @@ -2261,9 +2258,9 @@ impl CheckAttrVisitor<'_> { { errors::UnusedNote::EmptyList { name: attr.name_or_empty() } } else if matches!( - attr.name_or_empty(), - sym::allow | sym::warn | sym::deny | sym::forbid | sym::expect - ) && let Some(meta) = attr.meta_item_list() + attr.name_or_empty(), + sym::allow | sym::warn | sym::deny | sym::forbid | sym::expect + ) && let Some(meta) = attr.meta_item_list() && meta.len() == 1 && let Some(item) = meta[0].meta_item() && let MetaItemKind::NameValue(_) = &item.kind diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index 6d176af8098..7188c177feb 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -86,7 +86,7 @@ impl<'tcx> CheckConstVisitor<'tcx> { let is_feature_allowed = |feature_gate| { // All features require that the corresponding gate be enabled, // even if the function has `#[rustc_allow_const_fn_unstable(the_gate)]`. - if !tcx.features().enabled(feature_gate) { + if !tcx.features().active(feature_gate) { return false; } @@ -134,7 +134,7 @@ impl<'tcx> CheckConstVisitor<'tcx> { let required_gates = required_gates.unwrap_or(&[]); let missing_gates: Vec<_> = - required_gates.iter().copied().filter(|&g| !features.enabled(g)).collect(); + required_gates.iter().copied().filter(|&g| !features.active(g)).collect(); match missing_gates.as_slice() { [] => { diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index f853039f72c..87d4850b475 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -193,15 +193,15 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { if let hir::ExprKind::Assign(lhs, rhs, _) = assign.kind && check_for_self_assign_helper(self.typeck_results(), lhs, rhs) - && !assign.span.from_expansion() + && !assign.span.from_expansion() { - let is_field_assign = matches!(lhs.kind, hir::ExprKind::Field(..)); - self.tcx.emit_spanned_lint( - lint::builtin::DEAD_CODE, - assign.hir_id, - assign.span, - UselessAssignment { is_field_assign, ty: self.typeck_results().expr_ty(lhs) } - ) + let is_field_assign = matches!(lhs.kind, hir::ExprKind::Field(..)); + self.tcx.emit_spanned_lint( + lint::builtin::DEAD_CODE, + assign.hir_id, + assign.span, + UselessAssignment { is_field_assign, ty: self.typeck_results().expr_ty(lhs) }, + ) } } @@ -671,7 +671,8 @@ fn check_trait_item( if matches!(tcx.def_kind(id.owner_id), DefKind::AssocConst | DefKind::AssocFn) { let trait_item = tcx.hir().trait_item(id); if matches!(trait_item.kind, Const(_, Some(_)) | Fn(_, hir::TraitFn::Provided(_))) - && let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, trait_item.owner_id.def_id) + && let Some(comes_from_allow) = + has_allow_dead_code_or_lang_attr(tcx, trait_item.owner_id.def_id) { worklist.push((trait_item.owner_id.def_id, comes_from_allow)); } diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index c92d0b878ea..51a64b3855f 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -121,9 +121,13 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId, let def_id = local_def_id.to_def_id(); Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx, def_id) })) } else { - if let Some(main_def) = tcx.resolutions(()).main_def && let Some(def_id) = main_def.opt_fn_def_id() { + if let Some(main_def) = tcx.resolutions(()).main_def + && let Some(def_id) = main_def.opt_fn_def_id() + { // non-local main imports are handled below - if let Some(def_id) = def_id.as_local() && matches!(tcx.hir().find_by_def_id(def_id), Some(Node::ForeignItem(_))) { + if let Some(def_id) = def_id.as_local() + && matches!(tcx.hir().find_by_def_id(def_id), Some(Node::ForeignItem(_))) + { tcx.sess.emit_err(ExternMain { span: tcx.def_span(def_id) }); return None; } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 4b27b6d8c36..a4397ceeb8c 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1311,7 +1311,9 @@ impl<'a> IntoDiagnostic<'a> for NoMainErr { diag.span_label(self.sp.shrink_to_hi(), note); } - if let Some(main_def) = self.main_def_opt && main_def.opt_fn_def_id().is_none(){ + if let Some(main_def) = self.main_def_opt + && main_def.opt_fn_def_id().is_none() + { // There is something at `crate::main`, but it is not a function definition. diag.span_label(main_def.span, fluent::passes_non_function_main); } diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs index 44174b1b89d..ceb8f58cac0 100644 --- a/compiler/rustc_passes/src/lib_features.rs +++ b/compiler/rustc_passes/src/lib_features.rs @@ -56,7 +56,9 @@ impl<'tcx> LibFeatureCollector<'tcx> { } } - if let Some(s) = since && s.as_str() == VERSION_PLACEHOLDER { + if let Some(s) = since + && s.as_str() == VERSION_PLACEHOLDER + { since = Some(rust_version_symbol()); } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 20e996eaec4..1fe44b2b877 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -1512,13 +1512,15 @@ impl<'tcx> Liveness<'_, 'tcx> { Some(body), |spans, hir_id, ln, var| { if !self.live_on_entry(ln, var) - && let Some(name) = self.should_warn(var) { - self.ir.tcx.emit_spanned_lint( - lint::builtin::UNUSED_ASSIGNMENTS, - hir_id, - spans, - errors::UnusedAssignPassed { name }, - ); } + && let Some(name) = self.should_warn(var) + { + self.ir.tcx.emit_spanned_lint( + lint::builtin::UNUSED_ASSIGNMENTS, + hir_id, + spans, + errors::UnusedAssignPassed { name }, + ); + } }, ); } @@ -1707,13 +1709,14 @@ impl<'tcx> Liveness<'_, 'tcx> { fn warn_about_dead_assign(&self, spans: Vec<Span>, hir_id: HirId, ln: LiveNode, var: Variable) { if !self.live_on_exit(ln, var) - && let Some(name) = self.should_warn(var) { - self.ir.tcx.emit_spanned_lint( - lint::builtin::UNUSED_ASSIGNMENTS, - hir_id, - spans, - errors::UnusedAssign { name }, - ); - } + && let Some(name) = self.should_warn(var) + { + self.ir.tcx.emit_spanned_lint( + lint::builtin::UNUSED_ASSIGNMENTS, + hir_id, + spans, + errors::UnusedAssign { name }, + ); + } } } diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 1239d6d91ac..e93368a84ba 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -97,7 +97,9 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> { _ => None, }; - if let Some(res) = res && let Some(def_id) = res.opt_def_id().and_then(|el| el.as_local()) { + if let Some(res) = res + && let Some(def_id) = res.opt_def_id().and_then(|el| el.as_local()) + { if self.def_id_represents_local_inlined_item(def_id.to_def_id()) { self.worklist.push(def_id); } else { diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 9c265e8ec11..bb23dc257d7 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -998,14 +998,17 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { all_implications: &FxHashMap<Symbol, Symbol>, ) { for (feature, since) in defined_features { - if let Some(since) = since && let Some(span) = remaining_lib_features.get(&feature) { + if let Some(since) = since + && let Some(span) = remaining_lib_features.get(&feature) + { // Warn if the user has enabled an already-stable lib feature. if let Some(implies) = all_implications.get(&feature) { - unnecessary_partially_stable_feature_lint(tcx, *span, *feature, *implies, *since); + unnecessary_partially_stable_feature_lint( + tcx, *span, *feature, *implies, *since, + ); } else { unnecessary_stable_feature_lint(tcx, *span, *feature, *since); } - } remaining_lib_features.remove(feature); diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index 75e071f1fcf..9a6fb88c281 100644 --- a/compiler/rustc_passes/src/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs @@ -26,7 +26,9 @@ pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) { for id in crate_items.foreign_items() { let attrs = tcx.hir().attrs(id.hir_id()); if let Some((lang_item, _)) = lang_items::extract(attrs) { - if let Some(item) = LangItem::from_name(lang_item) && item.is_weak() { + if let Some(item) = LangItem::from_name(lang_item) + && item.is_weak() + { if items.get(item).is_none() { items.missing.push(item); } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 21d7bcbed5e..5599c6100a5 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -573,7 +573,8 @@ impl<'tcx> EmbargoVisitor<'tcx> { if !child.reexport_chain.is_empty() && child.vis.is_accessible_from(defining_mod, self.tcx) && let Res::Def(def_kind, def_id) = child.res - && let Some(def_id) = def_id.as_local() { + && let Some(def_id) = def_id.as_local() + { let vis = self.tcx.local_visibility(def_id); self.update_macro_reachable_def(def_id, def_kind, vis, defining_mod, macro_ev); } @@ -674,7 +675,8 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { if self.impl_trait_pass && let hir::ItemKind::OpaqueTy(ref opaque) = item.kind - && !opaque.in_trait { + && !opaque.in_trait + { // FIXME: This is some serious pessimization intended to workaround deficiencies // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time // reachable if they are returned via `impl Trait`, even from private functions. diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index ae8414ebba6..69a9c0eb95a 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -459,7 +459,9 @@ where // Similarly, fingerprint the result to assert that // it doesn't have anything not considered hashable. - if cfg!(debug_assertions) && let Some(hash_result) = query.hash_result() { + if cfg!(debug_assertions) + && let Some(hash_result) = query.hash_result() + { qcx.dep_context().with_stable_hashing_context(|mut hcx| { hash_result(&mut hcx, &result); }); diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 110286255c5..925ee615b09 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -187,7 +187,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } else if let Some((span, msg, sugg, appl)) = suggestion { err.span_suggestion_verbose(span, msg, sugg, appl); err.emit(); - } else if let [segment] = path.as_slice() && is_call { + } else if let [segment] = path.as_slice() + && is_call + { err.stash(segment.ident.span, rustc_errors::StashKey::CallIntoMethod); } else { err.emit(); @@ -1690,7 +1692,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { non_exhaustive = Some(attr.span); } else if let Some(span) = ctor_fields_span { err.span_label(span, "a constructor is private if any of the fields is private"); - if let Res::Def(_, d) = res && let Some(fields) = self.field_visibility_spans.get(&d) { + if let Res::Def(_, d) = res + && let Some(fields) = self.field_visibility_spans.get(&d) + { err.multipart_suggestion_verbose( format!( "consider making the field{} publicly accessible", @@ -1739,7 +1743,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } // Final step in the import chain, point out if the ADT is `non_exhaustive` // which is probably why this privacy violation occurred. - if next_binding.is_none() && let Some(span) = non_exhaustive { + if next_binding.is_none() + && let Some(span) = non_exhaustive + { note_span.push_span_label( span, "cannot be constructed because it is `#[non_exhaustive]`", @@ -1846,7 +1852,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { parent_scope, None, ignore_binding, - ).ok() + ) + .ok() } else if let Some(ribs) = ribs && let Some(TypeNS | ValueNS) = opt_ns { @@ -1870,7 +1877,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { None, false, ignore_binding, - ).ok() + ) + .ok() }; if let Some(binding) = binding { let mut found = |what| { @@ -2232,7 +2240,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Add the import to the start, with a `{` if required. let start_point = source_map.start_point(after_crate_name); - if is_definitely_crate && let Ok(start_snippet) = source_map.span_to_snippet(start_point) { + if is_definitely_crate + && let Ok(start_snippet) = source_map.span_to_snippet(start_point) + { corrections.push(( start_point, if has_nested { @@ -2247,7 +2257,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Add a `};` to the end if nested, matching the `{` added at the start. if !has_nested { - corrections.push((source_map.end_point(after_crate_name), "};".to_string())); + corrections + .push((source_map.end_point(after_crate_name), "};".to_string())); } } else { // If the root import is module-relative, add the import separately @@ -2586,7 +2597,13 @@ fn show_candidates( for candidate in &mut accessible_path_strings { // produce an additional newline to separate the new use statement // from the directly following item. - let additional_newline = if let FoundUse::No = found_use && let DiagnosticMode::Normal = mode { "\n" } else { "" }; + let additional_newline = if let FoundUse::No = found_use + && let DiagnosticMode::Normal = mode + { + "\n" + } else { + "" + }; candidate.0 = format!("{add_use}{}{append}{trailing}{additional_newline}", &candidate.0); } diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index 46f5df5ca6f..4477b967283 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -147,7 +147,8 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { warn_ambiguity |= nested_binding.warn_ambiguity; } if !is_ambiguity(binding, warn_ambiguity) - && let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) { + && let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) + { self.update_def(def_id, binding.vis.expect_local(), parent_id); } } diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 54388f80f15..f2fd4b0bf60 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -896,7 +896,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if !restricted_shadowing && binding.expansion != LocalExpnId::ROOT { if let NameBindingKind::Import { import, .. } = binding.kind - && matches!(import.kind, ImportKind::MacroExport) { + && matches!(import.kind, ImportKind::MacroExport) + { self.macro_expanded_macro_export_errors.insert((path_span, binding.span)); } } @@ -928,9 +929,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if !self.is_accessible_from(import_vis, parent_scope.module) { continue; } - if let Some(ignored) = ignore_binding && - let NameBindingKind::Import { import, .. } = ignored.kind && - import == *single_import { + if let Some(ignored) = ignore_binding + && let NameBindingKind::Import { import, .. } = ignored.kind + && import == *single_import + { // Ignore not just the binding itself, but if it has a shadowed_glob, // ignore that, too, because this loop is supposed to only process // named imports. @@ -1440,7 +1442,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { finalize, ignore_binding, ) - } else if let Some(ribs) = ribs && let Some(TypeNS | ValueNS) = opt_ns { + } else if let Some(ribs) = ribs + && let Some(TypeNS | ValueNS) = opt_ns + { match self.resolve_ident_in_lexical_scope( ident, ns, diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index d271519a8a3..b34790a925e 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -313,26 +313,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { (true, true) => { // FIXME: remove `!binding.is_ambiguity()` after delete the warning ambiguity. if !binding.is_ambiguity() - && let NameBindingKind::Import { import: old_import, .. } = old_binding.kind + && let NameBindingKind::Import { import: old_import, .. } = + old_binding.kind && let NameBindingKind::Import { import, .. } = binding.kind - && old_import == import { + && old_import == import + { // We should replace the `old_binding` with `binding` regardless // of whether they has same resolution or not when they are // imported from the same glob-import statement. resolution.binding = Some(binding); } else if res != old_binding.res() { let binding = if warn_ambiguity { - this.warn_ambiguity( - AmbiguityKind::GlobVsGlob, - old_binding, - binding, - ) + this.warn_ambiguity(AmbiguityKind::GlobVsGlob, old_binding, binding) } else { - this.ambiguity( - AmbiguityKind::GlobVsGlob, - old_binding, - binding, - ) + this.ambiguity(AmbiguityKind::GlobVsGlob, old_binding, binding) }; resolution.binding = Some(binding); } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) { @@ -434,7 +428,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let t = f(self, resolution); - if let Some(binding) = resolution.binding() && old_binding != Some(binding) { + if let Some(binding) = resolution.binding() + && old_binding != Some(binding) + { (binding, t, warn_ambiguity || old_binding.is_some()) } else { return t; @@ -637,7 +633,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if binding.res() != Res::Err && glob_binding.res() != Res::Err - && let NameBindingKind::Import { import: glob_import, .. } = glob_binding.kind + && let NameBindingKind::Import { import: glob_import, .. } = + glob_binding.kind && let Some(binding_id) = binding_id && let Some(glob_import_id) = glob_import.id() && let glob_import_def_id = self.local_def_id(glob_import_id) @@ -738,11 +735,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { match &import.kind { ImportKind::Single { source, .. } => { if let Some(ModuleOrUniformRoot::Module(module)) = import.imported_module.get() - && let Some(module) = module.opt_def_id() + && let Some(module) = module.opt_def_id() { self.find_cfg_stripped(&mut diag, &source.name, module) } - }, + } _ => {} } } @@ -989,10 +986,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } if !is_prelude - && let Some(max_vis) = max_vis.get() - && !max_vis.is_at_least(import.expect_vis(), self.tcx) + && let Some(max_vis) = max_vis.get() + && !max_vis.is_at_least(import.expect_vis(), self.tcx) { - self.lint_buffer.buffer_lint(UNUSED_IMPORTS, id, import.span, fluent::resolve_glob_import_doesnt_reexport); + self.lint_buffer.buffer_lint( + UNUSED_IMPORTS, + id, + import.span, + fluent::resolve_glob_import_doesnt_reexport, + ); } return None; } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ece8b7f6ec9..42ca407cddf 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -736,7 +736,8 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, // Check whether we should interpret this as a bare trait object. if qself.is_none() && let Some(partial_res) = self.r.partial_res_map.get(&ty.id) - && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res() + && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = + partial_res.full_res() { // This path is actually a bare trait object. In case of a bare `Fn`-trait // object with anonymous lifetimes, we need this rib to correctly place the @@ -2046,7 +2047,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { if lifetime_count != 0 { parameter_info.push(ElisionFnParameter { index, - ident: if let Some(pat) = pat && let PatKind::Ident(_, ident, _) = pat.kind { + ident: if let Some(pat) = pat + && let PatKind::Ident(_, ident, _) = pat.kind + { Some(ident) } else { None @@ -2140,7 +2143,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { impl<'a> Visitor<'a> for SelfVisitor<'_, '_, '_> { fn visit_ty(&mut self, ty: &'a Ty) { trace!("SelfVisitor considering ty={:?}", ty); - if let TyKind::Ref(lt, ref mt) = ty.kind && self.is_self_ty(&mt.ty) { + if let TyKind::Ref(lt, ref mt) = ty.kind + && self.is_self_ty(&mt.ty) + { let lt_id = if let Some(lt) = lt { lt.id } else { @@ -3602,7 +3607,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { sugg.to_string(), Applicability::MaybeIncorrect, )) - } else if res.is_none() && let PathSource::Type | PathSource::Expr(_) = source { + } else if res.is_none() + && let PathSource::Type | PathSource::Expr(_) = source + { this.suggest_adding_generic_parameter(path, source) } else { None @@ -4004,7 +4011,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { "unnecessary qualification", lint::BuiltinLintDiagnostics::UnusedQualifications { removal_span: finalize.path_span.until(last_segment.ident.span), - } + }, ) } } @@ -4057,13 +4064,13 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { (block.could_be_bare_literal, &block.stmts[..]) && let ExprKind::Type(..) = expr.kind { - self.diagnostic_metadata.current_block_could_be_bare_struct_literal = - Some(block.span); + self.diagnostic_metadata.current_block_could_be_bare_struct_literal = Some(block.span); } // Descend into the block. for stmt in &block.stmts { if let StmtKind::Item(ref item) = stmt.kind - && let ItemKind::MacroDef(..) = item.kind { + && let ItemKind::MacroDef(..) = item.kind + { num_macro_definition_ribs += 1; let res = self.r.local_def_id(item.id).to_def_id(); self.ribs[ValueNS].push(Rib::new(RibKind::MacroDefinition(res))); @@ -4419,7 +4426,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { && let Some(def_id) = res.opt_def_id() && !def_id.is_local() && self.r.tcx.crate_types().contains(&CrateType::ProcMacro) - && matches!(self.r.tcx.sess.opts.resolve_doc_links, ResolveDocLinks::ExportedMetadata) { + && matches!( + self.r.tcx.sess.opts.resolve_doc_links, + ResolveDocLinks::ExportedMetadata + ) + { // Encoding foreign def ids in proc macro crate metadata will ICE. return None; } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index bc5f8a37b0f..a5f8f61f3db 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -229,8 +229,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { i.ident.name == item_str.name // Don't suggest if the item is in Fn signature arguments (#112590). && !sig.span.contains(item_span) - }) - { + }) { let sp = item_span.shrink_to_lo(); // Account for `Foo { field }` when suggesting `self.field` so we result on @@ -241,7 +240,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } _ => None, }; - let pre = if let Some(field) = field && field.is_shorthand { + let pre = if let Some(field) = field + && field.is_shorthand + { format!("{item_ident}: ") } else { String::new() @@ -254,13 +255,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } _ => matches!( source, - PathSource::Expr(Some(Expr { kind: ExprKind::Call(..), ..})), + PathSource::Expr(Some(Expr { kind: ExprKind::Call(..), .. })), ), }; match &item.kind { AssocItemKind::Fn(fn_) - if (!sig.decl.has_self() || !is_call) && fn_.sig.decl.has_self() => { + if (!sig.decl.has_self() || !is_call) && fn_.sig.decl.has_self() => + { // Ensure that we only suggest `self.` if `self` is available, // you can't call `fn foo(&self)` from `fn bar()` (#115992). // We also want to mention that the method exists. @@ -270,19 +272,16 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { )); None } - AssocItemKind::Fn(fn_) - if !fn_.sig.decl.has_self() && !is_call => { + AssocItemKind::Fn(fn_) if !fn_.sig.decl.has_self() && !is_call => { span_label = Some(( item.ident.span, "an associated function by that name is available on `Self` here", )); None } - AssocItemKind::Fn(fn_) if fn_.sig.decl.has_self() => Some(( - sp, - "consider using the method on `Self`", - format!("{pre}self."), - )), + AssocItemKind::Fn(fn_) if fn_.sig.decl.has_self() => { + Some((sp, "consider using the method on `Self`", format!("{pre}self."))) + } AssocItemKind::Fn(_) => Some(( sp, "consider using the associated function on `Self`", @@ -293,7 +292,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { "consider using the associated constant on `Self`", format!("{pre}Self::"), )), - _ => None + _ => None, } } else { None @@ -379,8 +378,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { prefix_path: &[Segment], following_seg: Option<&Segment>, ) -> Vec<ImportSuggestion> { - if let Some(segment) = prefix_path.last() && - let Some(following_seg) = following_seg + if let Some(segment) = prefix_path.last() + && let Some(following_seg) = following_seg { let candidates = self.r.lookup_import_candidates( segment.ident, @@ -392,12 +391,16 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { candidates .into_iter() .filter(|candidate| { - if let Some(def_id) = candidate.did && - let Some(module) = self.r.get_module(def_id) { - Some(def_id) != self.parent_scope.module.opt_def_id() && - self.r.resolutions(module).borrow().iter().any(|(key, _r)| { - key.ident.name == following_seg.ident.name - }) + if let Some(def_id) = candidate.did + && let Some(module) = self.r.get_module(def_id) + { + Some(def_id) != self.parent_scope.module.opt_def_id() + && self + .r + .resolutions(module) + .borrow() + .iter() + .any(|(key, _r)| key.ident.name == following_seg.ident.name) } else { false } @@ -747,11 +750,15 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } // Try to find in last block rib - if let Some(rib) = &self.last_block_rib && let RibKind::Normal = rib.kind { + if let Some(rib) = &self.last_block_rib + && let RibKind::Normal = rib.kind + { for (ident, &res) in &rib.bindings { - if let Res::Local(_) = res && path.len() == 1 && - ident.span.eq_ctxt(path[0].ident.span) && - ident.name == path[0].ident.name { + if let Res::Local(_) = res + && path.len() == 1 + && ident.span.eq_ctxt(path[0].ident.span) + && ident.name == path[0].ident.name + { err.span_help( ident.span, format!("the binding `{path_str}` is available in a different scope in the same function"), @@ -867,9 +874,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { // (could be in a different file) or introduced in the same file as the typo // (could belong to a different crate) if let TypoCandidate::Shadowed(res, Some(sugg_span)) = typo_sugg - && res - .opt_def_id() - .is_some_and(|id| id.is_local() || is_in_same_file(span, sugg_span)) + && res.opt_def_id().is_some_and(|id| id.is_local() || is_in_same_file(span, sugg_span)) { err.span_label( sugg_span, @@ -1074,12 +1079,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { && trait_ref.path.span == span && let PathSource::Trait(_) = source && let Some(Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)) = res - && let Ok(self_ty_str) = - self.r.tcx.sess.source_map().span_to_snippet(self_ty.span) + && let Ok(self_ty_str) = self.r.tcx.sess.source_map().span_to_snippet(self_ty.span) && let Ok(trait_ref_str) = self.r.tcx.sess.source_map().span_to_snippet(trait_ref.path.span) { - err.multipart_suggestion( + err.multipart_suggestion( "`impl` items mention the trait being implemented first and the type it is being implemented for second", vec![(trait_ref.path.span, self_ty_str), (self_ty.span, trait_ref_str)], Applicability::MaybeIncorrect, @@ -1106,12 +1110,10 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { source: PathSource<'_>, span: Span, ) -> bool { - if let PathSource::Expr(_) = source && - let Some(Expr { - span: expr_span, - kind: ExprKind::Assign(lhs, _, _), - .. - }) = self.diagnostic_metadata.in_if_condition { + if let PathSource::Expr(_) = source + && let Some(Expr { span: expr_span, kind: ExprKind::Assign(lhs, _, _), .. }) = + self.diagnostic_metadata.in_if_condition + { // Icky heuristic so we don't suggest: // `if (i + 2) = 2` => `if let (i + 2) = 2` (approximately pattern) // `if 2 = i` => `if let 2 = i` (lhs needs to contain error span) @@ -1240,31 +1242,32 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { let mut has_self_arg = None; if let PathSource::Expr(Some(parent)) = source && let ExprKind::Call(_, args) = &parent.kind - && !args.is_empty() { - let mut expr_kind = &args[0].kind; - loop { - match expr_kind { - ExprKind::Path(_, arg_name) if arg_name.segments.len() == 1 => { - if arg_name.segments[0].ident.name == kw::SelfLower { - let call_span = parent.span; - let tail_args_span = if args.len() > 1 { - Some(Span::new( - args[1].span.lo(), - args.last().unwrap().span.hi(), - call_span.ctxt(), - None, - )) - } else { - None - }; - has_self_arg = Some((call_span, tail_args_span)); - } - break; + && !args.is_empty() + { + let mut expr_kind = &args[0].kind; + loop { + match expr_kind { + ExprKind::Path(_, arg_name) if arg_name.segments.len() == 1 => { + if arg_name.segments[0].ident.name == kw::SelfLower { + let call_span = parent.span; + let tail_args_span = if args.len() > 1 { + Some(Span::new( + args[1].span.lo(), + args.last().unwrap().span.hi(), + call_span.ctxt(), + None, + )) + } else { + None + }; + has_self_arg = Some((call_span, tail_args_span)); } - ExprKind::AddrOf(_, _, expr) => expr_kind = &expr.kind, - _ => break, + break; } + ExprKind::AddrOf(_, _, expr) => expr_kind = &expr.kind, + _ => break, } + } } has_self_arg } @@ -1321,8 +1324,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { ); true } else if kind == DefKind::Struct - && let Some(lhs_source_span) = lhs_span.find_ancestor_inside(expr.span) - && let Ok(snippet) = self.r.tcx.sess.source_map().span_to_snippet(lhs_source_span) + && let Some(lhs_source_span) = lhs_span.find_ancestor_inside(expr.span) + && let Ok(snippet) = self.r.tcx.sess.source_map().span_to_snippet(lhs_source_span) { // The LHS is a type that originates from a macro call. // We have to add angle brackets around it. @@ -1427,7 +1430,13 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { .map(|(idx, new)| (new, old_fields.get(idx))) .map(|(new, old)| { let new = new.to_ident_string(); - if let Some(Some(old)) = old && new != *old { format!("{new}: {old}") } else { new } + if let Some(Some(old)) = old + && new != *old + { + format!("{new}: {old}") + } else { + new + } }) .collect::<Vec<String>>() } else { @@ -1813,7 +1822,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } } - if let RibKind::MacroDefinition(def) = rib.kind && def == self.r.macro_def(ctxt) { + if let RibKind::MacroDefinition(def) = rib.kind + && def == self.r.macro_def(ctxt) + { // If an invocation of this macro created `ident`, give up on `ident` // and switch to `ident`'s source from the macro definition. ctxt.remove_mark(); @@ -1934,18 +1945,20 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { // try to give a suggestion for this pattern: `name = blah`, which is common in other languages // suggest `let name = blah` to introduce a new binding fn let_binding_suggestion(&mut self, err: &mut Diagnostic, ident_span: Span) -> bool { - if let Some(Expr { kind: ExprKind::Assign(lhs, .. ), .. }) = self.diagnostic_metadata.in_assignment && - let ast::ExprKind::Path(None, _) = lhs.kind { - if !ident_span.from_expansion() { - err.span_suggestion_verbose( - ident_span.shrink_to_lo(), - "you might have meant to introduce a new binding", - "let ".to_string(), - Applicability::MaybeIncorrect, - ); - return true; - } + if let Some(Expr { kind: ExprKind::Assign(lhs, ..), .. }) = + self.diagnostic_metadata.in_assignment + && let ast::ExprKind::Path(None, _) = lhs.kind + { + if !ident_span.from_expansion() { + err.span_suggestion_verbose( + ident_span.shrink_to_lo(), + "you might have meant to introduce a new binding", + "let ".to_string(), + Applicability::MaybeIncorrect, + ); + return true; } + } false } @@ -2406,7 +2419,10 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { continue; } - if !span.can_be_used_for_suggestions() && suggest_note && let Some(name) = name { + if !span.can_be_used_for_suggestions() + && suggest_note + && let Some(name) = name + { suggest_note = false; // Avoid displaying the same help multiple times. err.span_label( span, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 0bc45967e3d..501747df5c9 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -826,8 +826,10 @@ impl<'a> NameBindingData<'a> { matches!(import.kind, ImportKind::ExternCrate { .. }) } NameBindingKind::Module(module) - if let ModuleKind::Def(DefKind::Mod, def_id, _) = module.kind - => def_id.is_crate_root(), + if let ModuleKind::Def(DefKind::Mod, def_id, _) = module.kind => + { + def_id.is_crate_root() + } _ => false, } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index f0a1a4ff931..2ff6fb424e6 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -748,33 +748,45 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } path_res @ (PathResult::NonModule(..) | PathResult::Failed { .. }) => { let mut suggestion = None; - let (span, label, module) = if let PathResult::Failed { span, label, module, .. } = path_res { - // try to suggest if it's not a macro, maybe a function - if let PathResult::NonModule(partial_res) = self.maybe_resolve_path(&path, Some(ValueNS), &parent_scope) - && partial_res.unresolved_segments() == 0 { - let sm = self.tcx.sess.source_map(); - let exclamation_span = sm.next_point(span); - suggestion = Some(( - vec![(exclamation_span, "".to_string())], - format!("{} is not a macro, but a {}, try to remove `!`", Segment::names_to_string(&path), partial_res.base_res().descr()), - Applicability::MaybeIncorrect + let (span, label, module) = + if let PathResult::Failed { span, label, module, .. } = path_res { + // try to suggest if it's not a macro, maybe a function + if let PathResult::NonModule(partial_res) = + self.maybe_resolve_path(&path, Some(ValueNS), &parent_scope) + && partial_res.unresolved_segments() == 0 + { + let sm = self.tcx.sess.source_map(); + let exclamation_span = sm.next_point(span); + suggestion = Some(( + vec![(exclamation_span, "".to_string())], + format!( + "{} is not a macro, but a {}, try to remove `!`", + Segment::names_to_string(&path), + partial_res.base_res().descr() + ), + Applicability::MaybeIncorrect, )); - } - (span, label, module) - } else { - ( - path_span, - format!( - "partially resolved path in {} {}", - kind.article(), - kind.descr() - ), - None, - ) - }; + } + (span, label, module) + } else { + ( + path_span, + format!( + "partially resolved path in {} {}", + kind.article(), + kind.descr() + ), + None, + ) + }; self.report_error( span, - ResolutionError::FailedToResolve { last_segment: path.last().map(|segment| segment.ident.name), label, suggestion, module }, + ResolutionError::FailedToResolve { + last_segment: path.last().map(|segment| segment.ident.name), + label, + suggestion, + module, + }, ); } PathResult::Module(..) | PathResult::Indeterminate => unreachable!(), diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 7c41c32d022..fe4b8c7f69c 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -346,7 +346,9 @@ pub fn has_primitive_or_keyword_docs(attrs: &[ast::Attribute]) -> bool { for attr in attrs { if attr.has_name(sym::rustc_doc_primitive) { return true; - } else if attr.has_name(sym::doc) && let Some(items) = attr.meta_item_list() { + } else if attr.has_name(sym::doc) + && let Some(items) = attr.meta_item_list() + { for item in items { if item.has_name(sym::keyword) { return true; diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index 3af83aaaaa8..e26d25d9a41 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -4,6 +4,7 @@ version = "0.0.0" edition = "2021" [dependencies] +bitflags = "1.2.1" getopts = "0.2" rustc_macros = { path = "../rustc_macros" } tracing = "0.1" diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 2a6f5994c49..2e991b4c0ad 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -21,8 +21,8 @@ use rustc_feature::UnstableFeatures; use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION}; use rustc_span::source_map::{FileName, FilePathMapping}; use rustc_span::symbol::{sym, Symbol}; -use rustc_span::RealFileName; use rustc_span::SourceFileHashAlgorithm; +use rustc_span::{FileNameDisplayPreference, RealFileName}; use rustc_errors::emitter::HumanReadableErrorType; use rustc_errors::{ColorConfig, DiagnosticArgValue, HandlerFlags, IntoDiagnosticArg}; @@ -1018,6 +1018,32 @@ impl OutputFilenames { } } +bitflags::bitflags! { + /// Scopes used to determined if it need to apply to --remap-path-prefix + pub struct RemapPathScopeComponents: u8 { + /// Apply remappings to the expansion of std::file!() macro + const MACRO = 1 << 0; + /// Apply remappings to printed compiler diagnostics + const DIAGNOSTICS = 1 << 1; + /// Apply remappings to debug information only when they are written to + /// compiled executables or libraries, but not when they are in split + /// debuginfo files + const UNSPLIT_DEBUGINFO = 1 << 2; + /// Apply remappings to debug information only when they are written to + /// split debug information files, but not in compiled executables or + /// libraries + const SPLIT_DEBUGINFO = 1 << 3; + /// Apply remappings to the paths pointing to split debug information + /// files. Does nothing when these files are not generated. + const SPLIT_DEBUGINFO_PATH = 1 << 4; + + /// An alias for macro,unsplit-debuginfo,split-debuginfo-path. This + /// ensures all paths in compiled executables or libraries are remapped + /// but not elsewhere. + const OBJECT = Self::MACRO.bits | Self::UNSPLIT_DEBUGINFO.bits | Self::SPLIT_DEBUGINFO_PATH.bits; + } +} + pub fn host_triple() -> &'static str { // Get the host triple out of the build environment. This ensures that our // idea of the host triple is the same as for the set of libraries we've @@ -1030,6 +1056,22 @@ pub fn host_triple() -> &'static str { (option_env!("CFG_COMPILER_HOST_TRIPLE")).expect("CFG_COMPILER_HOST_TRIPLE") } +fn file_path_mapping( + remap_path_prefix: Vec<(PathBuf, PathBuf)>, + unstable_opts: &UnstableOptions, +) -> FilePathMapping { + FilePathMapping::new( + remap_path_prefix.clone(), + if unstable_opts.remap_path_scope.contains(RemapPathScopeComponents::DIAGNOSTICS) + && !remap_path_prefix.is_empty() + { + FileNameDisplayPreference::Remapped + } else { + FileNameDisplayPreference::Local + }, + ) +} + impl Default for Options { fn default() -> Options { Options { @@ -1047,6 +1089,7 @@ impl Default for Options { target_triple: TargetTriple::from_triple(host_triple()), test: false, incremental: None, + untracked_state_hash: Default::default(), unstable_opts: Default::default(), prints: Vec::new(), cg: Default::default(), @@ -1084,7 +1127,7 @@ impl Options { } pub fn file_path_mapping(&self) -> FilePathMapping { - FilePathMapping::new(self.remap_path_prefix.clone()) + file_path_mapping(self.remap_path_prefix.clone(), &self.unstable_opts) } /// Returns `true` if there will be an output file generated. @@ -2866,7 +2909,7 @@ pub fn build_session_options( handler.early_error(format!("Current directory is invalid: {e}")); }); - let remap = FilePathMapping::new(remap_path_prefix.clone()); + let remap = file_path_mapping(remap_path_prefix.clone(), &unstable_opts); let (path, remapped) = remap.map_prefix(&working_dir); let working_dir = if remapped { RealFileName::Remapped { virtual_name: path.into_owned(), local_path: Some(working_dir) } @@ -2889,6 +2932,7 @@ pub fn build_session_options( target_triple, test, incremental, + untracked_state_hash: Default::default(), unstable_opts, prints, cg, @@ -3167,17 +3211,17 @@ impl PpMode { /// we have an opt-in scheme here, so one is hopefully forced to think about /// how the hash should be calculated when adding a new command-line argument. pub(crate) mod dep_tracking { - use super::Polonius; use super::{ BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, - LtoCli, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, Passes, - ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, - SymbolManglingVersion, TraitSolver, TrimmedDefPaths, + LtoCli, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, Polonius, + RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, + SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths, }; use crate::lint; use crate::options::WasiExecModel; - use crate::utils::{NativeLib, NativeLibKind}; + use crate::utils::NativeLib; + use rustc_data_structures::stable_hasher::Hash64; use rustc_errors::LanguageIdentifier; use rustc_feature::UnstableFeatures; use rustc_span::edition::Edition; @@ -3233,6 +3277,7 @@ pub(crate) mod dep_tracking { usize, NonZeroUsize, u64, + Hash64, String, PathBuf, lint::Level, @@ -3247,14 +3292,12 @@ pub(crate) mod dep_tracking { MergeFunctions, PanicStrategy, RelroLevel, - Passes, OptLevel, LtoCli, DebugInfo, DebugInfoCompression, UnstableFeatures, NativeLib, - NativeLibKind, SanitizerSet, CFGuard, CFProtection, @@ -3267,6 +3310,7 @@ pub(crate) mod dep_tracking { StackProtector, SwitchWithOptPath, SymbolManglingVersion, + RemapPathScopeComponents, SourceFileHashAlgorithm, TrimmedDefPaths, OutFileName, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index eb1aa6d6c88..9561c7ba760 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -4,6 +4,7 @@ use crate::search_paths::SearchPath; use crate::utils::NativeLib; use crate::{lint, EarlyErrorHandler}; use rustc_data_structures::profiling::TimePassesFormat; +use rustc_data_structures::stable_hasher::Hash64; use rustc_errors::ColorConfig; use rustc_errors::{LanguageIdentifier, TerminalUrl}; use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, SanitizerSet}; @@ -158,6 +159,10 @@ top_level_options!( /// directory to store intermediate results. incremental: Option<PathBuf> [UNTRACKED], assert_incr_state: Option<IncrementalStateAssertion> [UNTRACKED], + /// Set by the `Config::hash_untracked_state` callback for custom + /// drivers to invalidate the incremental cache + #[rustc_lint_opt_deny_field_access("should only be used via `Config::hash_untracked_state`")] + untracked_state_hash: Hash64 [TRACKED_NO_CRATE_HASH], unstable_opts: UnstableOptions [SUBSTRUCT], prints: Vec<PrintRequest> [UNTRACKED], @@ -422,6 +427,7 @@ mod desc { pub const parse_proc_macro_execution_strategy: &str = "one of supported execution strategies (`same-thread`, or `cross-thread`)"; pub const parse_dump_solver_proof_tree: &str = "one of: `always`, `on-request`, `on-error`"; + pub const parse_remap_path_scope: &str = "comma separated list of scopes: `macro`, `diagnostics`, `unsplit-debuginfo`, `split-debuginfo`, `split-debuginfo-path`, `object`, `all`"; } mod parse { @@ -1090,6 +1096,30 @@ mod parse { true } + pub(crate) fn parse_remap_path_scope( + slot: &mut RemapPathScopeComponents, + v: Option<&str>, + ) -> bool { + if let Some(v) = v { + *slot = RemapPathScopeComponents::empty(); + for s in v.split(',') { + *slot |= match s { + "macro" => RemapPathScopeComponents::MACRO, + "diagnostics" => RemapPathScopeComponents::DIAGNOSTICS, + "unsplit-debuginfo" => RemapPathScopeComponents::UNSPLIT_DEBUGINFO, + "split-debuginfo" => RemapPathScopeComponents::SPLIT_DEBUGINFO, + "split-debuginfo-path" => RemapPathScopeComponents::SPLIT_DEBUGINFO_PATH, + "object" => RemapPathScopeComponents::OBJECT, + "all" => RemapPathScopeComponents::all(), + _ => return false, + } + } + true + } else { + false + } + } + pub(crate) fn parse_relocation_model(slot: &mut Option<RelocModel>, v: Option<&str>) -> bool { match v.and_then(|s| RelocModel::from_str(s).ok()) { Some(relocation_model) => *slot = Some(relocation_model), @@ -1726,6 +1756,8 @@ options! { "choose which RELRO level to use"), remap_cwd_prefix: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED], "remap paths under the current working directory to this path prefix"), + remap_path_scope: RemapPathScopeComponents = (RemapPathScopeComponents::all(), parse_remap_path_scope, [TRACKED], + "remap path scope (default: all)"), remark_dir: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED], "directory into which to write optimization remarks (if not specified, they will be \ written to standard error output)"), diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs index 7a57b0621cd..9cd96895a61 100644 --- a/compiler/rustc_session/src/output.rs +++ b/compiler/rustc_session/src/output.rs @@ -186,10 +186,14 @@ pub fn invalid_output_for_target(sess: &Session, crate_type: CrateType) -> bool return true; } } - if let CrateType::ProcMacro | CrateType::Dylib = crate_type && sess.target.only_cdylib { + if let CrateType::ProcMacro | CrateType::Dylib = crate_type + && sess.target.only_cdylib + { return true; } - if let CrateType::Executable = crate_type && !sess.target.executables { + if let CrateType::Executable = crate_type + && !sess.target.executables + { return true; } diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 671204c0d8e..abb0ab5630c 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -39,7 +39,7 @@ pub struct GatedSpans { impl GatedSpans { /// Feature gate the given `span` under the given `feature` - /// which is same `Symbol` used in `active.rs`. + /// which is same `Symbol` used in `unstable.rs`. pub fn gate(&self, feature: Symbol, span: Span) { self.spans.borrow_mut().entry(feature).or_default().push(span); } @@ -78,7 +78,7 @@ impl SymbolGallery { } /// Construct a diagnostic for a language feature error due to the given `span`. -/// The `feature`'s `Symbol` is the one you used in `active.rs` and `rustc_span::symbols`. +/// The `feature`'s `Symbol` is the one you used in `unstable.rs` and `rustc_span::symbols`. #[track_caller] pub fn feature_err( sess: &ParseSess, diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 5cac11cc8f7..79307498165 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1,7 +1,8 @@ use crate::code_stats::CodeStats; pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use crate::config::{ - self, CrateType, InstrumentCoverage, OptLevel, OutFileName, OutputType, SwitchWithOptPath, + self, CrateType, InstrumentCoverage, OptLevel, OutFileName, OutputType, + RemapPathScopeComponents, SwitchWithOptPath, }; use crate::config::{ErrorOutputType, Input}; use crate::errors; @@ -254,7 +255,11 @@ impl Session { pub fn local_crate_source_file(&self) -> Option<PathBuf> { let path = self.io.input.opt_path()?; - Some(self.opts.file_path_mapping().map_prefix(path).0.into_owned()) + if self.should_prefer_remapped_for_codegen() { + Some(self.opts.file_path_mapping().map_prefix(path).0.into_owned()) + } else { + Some(path.to_path_buf()) + } } fn check_miri_unleashed_features(&self) { @@ -1243,6 +1248,53 @@ impl Session { pub fn link_dead_code(&self) -> bool { self.opts.cg.link_dead_code.unwrap_or(false) } + + pub fn should_prefer_remapped_for_codegen(&self) -> bool { + // bail out, if any of the requested crate types aren't: + // "compiled executables or libraries" + for crate_type in &self.opts.crate_types { + match crate_type { + CrateType::Executable + | CrateType::Dylib + | CrateType::Rlib + | CrateType::Staticlib + | CrateType::Cdylib => continue, + CrateType::ProcMacro => return false, + } + } + + let has_split_debuginfo = match self.split_debuginfo() { + SplitDebuginfo::Off => false, + SplitDebuginfo::Packed => true, + SplitDebuginfo::Unpacked => true, + }; + + let remap_path_scopes = &self.opts.unstable_opts.remap_path_scope; + let mut prefer_remapped = false; + + if remap_path_scopes.contains(RemapPathScopeComponents::UNSPLIT_DEBUGINFO) { + prefer_remapped |= !has_split_debuginfo; + } + + if remap_path_scopes.contains(RemapPathScopeComponents::SPLIT_DEBUGINFO) { + prefer_remapped |= has_split_debuginfo; + } + + prefer_remapped + } + + pub fn should_prefer_remapped_for_split_debuginfo_paths(&self) -> bool { + let has_split_debuginfo = match self.split_debuginfo() { + SplitDebuginfo::Off => false, + SplitDebuginfo::Packed | SplitDebuginfo::Unpacked => true, + }; + + self.opts + .unstable_opts + .remap_path_scope + .contains(RemapPathScopeComponents::SPLIT_DEBUGINFO_PATH) + && has_split_debuginfo + } } // JUSTIFICATION: part of session construction @@ -1752,3 +1804,53 @@ fn mk_emitter(output: ErrorOutputType) -> Box<DynEmitter> { }; emitter } + +pub trait RemapFileNameExt { + type Output<'a> + where + Self: 'a; + + fn for_scope(&self, sess: &Session, scopes: RemapPathScopeComponents) -> Self::Output<'_>; + + fn for_codegen(&self, sess: &Session) -> Self::Output<'_>; +} + +impl RemapFileNameExt for rustc_span::FileName { + type Output<'a> = rustc_span::FileNameDisplay<'a>; + + fn for_scope(&self, sess: &Session, scopes: RemapPathScopeComponents) -> Self::Output<'_> { + if sess.opts.unstable_opts.remap_path_scope.contains(scopes) { + self.prefer_remapped_unconditionaly() + } else { + self.prefer_local() + } + } + + fn for_codegen(&self, sess: &Session) -> Self::Output<'_> { + if sess.should_prefer_remapped_for_codegen() { + self.prefer_remapped_unconditionaly() + } else { + self.prefer_local() + } + } +} + +impl RemapFileNameExt for rustc_span::RealFileName { + type Output<'a> = &'a Path; + + fn for_scope(&self, sess: &Session, scopes: RemapPathScopeComponents) -> Self::Output<'_> { + if sess.opts.unstable_opts.remap_path_scope.contains(scopes) { + self.remapped_path_if_available() + } else { + self.local_path_if_available() + } + } + + fn for_codegen(&self, sess: &Session) -> Self::Output<'_> { + if sess.should_prefer_remapped_for_codegen() { + self.remapped_path_if_available() + } else { + self.local_path_if_available() + } + } +} diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs index aea7c6c2842..3ed044ad769 100644 --- a/compiler/rustc_session/src/utils.rs +++ b/compiler/rustc_session/src/utils.rs @@ -161,7 +161,9 @@ pub fn extra_compiler_flags() -> Option<(Vec<String>, bool)> { pub(crate) fn is_ascii_ident(string: &str) -> bool { let mut chars = string.chars(); - if let Some(start) = chars.next() && (start.is_ascii_alphabetic() || start == '_') { + if let Some(start) = chars.next() + && (start.is_ascii_alphabetic() || start == '_') + { chars.all(|char| char.is_ascii_alphanumeric() || char == '_') } else { false diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 2a265fc1f5b..f26d18ad38f 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -17,8 +17,10 @@ use rustc_middle::ty::{self, Ty, TyCtxt, Variance}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_target::abi::FieldIdx; use stable_mir::mir::{CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx}; -use stable_mir::ty::{FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy}; -use stable_mir::{self, opaque, Context}; +use stable_mir::ty::{ + FloatTy, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span, TyKind, UintTy, +}; +use stable_mir::{self, opaque, Context, Filename}; use tracing::debug; mod alloc; @@ -50,10 +52,27 @@ impl<'tcx> Context for Tables<'tcx> { self.tcx.def_path_str(self[def_id]) } - fn print_span(&self, span: stable_mir::ty::Span) -> String { + fn span_to_string(&self, span: stable_mir::ty::Span) -> String { self.tcx.sess.source_map().span_to_diagnostic_string(self[span]) } + fn get_filename(&self, span: &Span) -> Filename { + opaque( + &self + .tcx + .sess + .source_map() + .span_to_filename(self[*span]) + .display(rustc_span::FileNameDisplayPreference::Local) + .to_string(), + ) + } + + fn get_lines(&self, span: &Span) -> LineInfo { + let lines = &self.tcx.sess.source_map().span_to_location_info(self[*span]); + LineInfo { start_line: lines.1, start_col: lines.2, end_line: lines.3, end_col: lines.4 } + } + fn def_kind(&mut self, def_id: stable_mir::DefId) -> stable_mir::DefKind { self.tcx.def_kind(self[def_id]).stable(self) } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index e62efab5793..49b4042d148 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -370,7 +370,7 @@ impl FileName { } } - pub fn prefer_remapped(&self) -> FileNameDisplay<'_> { + pub fn prefer_remapped_unconditionaly(&self) -> FileNameDisplay<'_> { FileNameDisplay { inner: self, display_pref: FileNameDisplayPreference::Remapped } } diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 0b575c13adf..612d396b099 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -1124,16 +1124,13 @@ pub struct FilePathMapping { impl FilePathMapping { pub fn empty() -> FilePathMapping { - FilePathMapping::new(Vec::new()) + FilePathMapping::new(Vec::new(), FileNameDisplayPreference::Local) } - pub fn new(mapping: Vec<(PathBuf, PathBuf)>) -> FilePathMapping { - let filename_display_for_diagnostics = if mapping.is_empty() { - FileNameDisplayPreference::Local - } else { - FileNameDisplayPreference::Remapped - }; - + pub fn new( + mapping: Vec<(PathBuf, PathBuf)>, + filename_display_for_diagnostics: FileNameDisplayPreference, + ) -> FilePathMapping { FilePathMapping { mapping, filename_display_for_diagnostics } } @@ -1287,6 +1284,27 @@ impl FilePathMapping { } } + /// Expand a relative path to an absolute path **without** remapping taken into account. + /// + /// The resulting `RealFileName` will have its `virtual_path` portion erased if + /// possible (i.e. if there's also a remapped path). + pub fn to_local_embeddable_absolute_path( + &self, + file_path: RealFileName, + working_directory: &RealFileName, + ) -> RealFileName { + let file_path = file_path.local_path_if_available(); + if file_path.is_absolute() { + // No remapping has applied to this path and it is absolute, + // so the working directory cannot influence it either, so + // we are done. + return RealFileName::LocalPath(file_path.to_path_buf()); + } + debug_assert!(file_path.is_relative()); + let working_directory = working_directory.local_path_if_available(); + RealFileName::LocalPath(Path::new(working_directory).join(file_path)) + } + /// Attempts to (heuristically) reverse a prefix mapping. /// /// Returns [`Some`] if there is exactly one mapping where the "to" part is diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs index a12f50c87a2..5697969ddb8 100644 --- a/compiler/rustc_span/src/source_map/tests.rs +++ b/compiler/rustc_span/src/source_map/tests.rs @@ -351,7 +351,10 @@ fn reverse_map_prefix(mapping: &FilePathMapping, p: &str) -> Option<String> { fn path_prefix_remapping() { // Relative to relative { - let mapping = &FilePathMapping::new(vec![(path("abc/def"), path("foo"))]); + let mapping = &FilePathMapping::new( + vec![(path("abc/def"), path("foo"))], + FileNameDisplayPreference::Remapped, + ); assert_eq!(map_path_prefix(mapping, "abc/def/src/main.rs"), path_str("foo/src/main.rs")); assert_eq!(map_path_prefix(mapping, "abc/def"), path_str("foo")); @@ -359,7 +362,10 @@ fn path_prefix_remapping() { // Relative to absolute { - let mapping = &FilePathMapping::new(vec![(path("abc/def"), path("/foo"))]); + let mapping = &FilePathMapping::new( + vec![(path("abc/def"), path("/foo"))], + FileNameDisplayPreference::Remapped, + ); assert_eq!(map_path_prefix(mapping, "abc/def/src/main.rs"), path_str("/foo/src/main.rs")); assert_eq!(map_path_prefix(mapping, "abc/def"), path_str("/foo")); @@ -367,7 +373,10 @@ fn path_prefix_remapping() { // Absolute to relative { - let mapping = &FilePathMapping::new(vec![(path("/abc/def"), path("foo"))]); + let mapping = &FilePathMapping::new( + vec![(path("/abc/def"), path("foo"))], + FileNameDisplayPreference::Remapped, + ); assert_eq!(map_path_prefix(mapping, "/abc/def/src/main.rs"), path_str("foo/src/main.rs")); assert_eq!(map_path_prefix(mapping, "/abc/def"), path_str("foo")); @@ -375,7 +384,10 @@ fn path_prefix_remapping() { // Absolute to absolute { - let mapping = &FilePathMapping::new(vec![(path("/abc/def"), path("/foo"))]); + let mapping = &FilePathMapping::new( + vec![(path("/abc/def"), path("/foo"))], + FileNameDisplayPreference::Remapped, + ); assert_eq!(map_path_prefix(mapping, "/abc/def/src/main.rs"), path_str("/foo/src/main.rs")); assert_eq!(map_path_prefix(mapping, "/abc/def"), path_str("/foo")); @@ -385,8 +397,10 @@ fn path_prefix_remapping() { #[test] fn path_prefix_remapping_expand_to_absolute() { // "virtual" working directory is relative path - let mapping = - &FilePathMapping::new(vec![(path("/foo"), path("FOO")), (path("/bar"), path("BAR"))]); + let mapping = &FilePathMapping::new( + vec![(path("/foo"), path("FOO")), (path("/bar"), path("BAR"))], + FileNameDisplayPreference::Remapped, + ); let working_directory = path("/foo"); let working_directory = RealFileName::Remapped { local_path: Some(working_directory.clone()), @@ -487,8 +501,10 @@ fn path_prefix_remapping_expand_to_absolute() { fn path_prefix_remapping_reverse() { // Ignores options without alphanumeric chars. { - let mapping = - &FilePathMapping::new(vec![(path("abc"), path("/")), (path("def"), path("."))]); + let mapping = &FilePathMapping::new( + vec![(path("abc"), path("/")), (path("def"), path("."))], + FileNameDisplayPreference::Remapped, + ); assert_eq!(reverse_map_prefix(mapping, "/hello.rs"), None); assert_eq!(reverse_map_prefix(mapping, "./hello.rs"), None); @@ -496,20 +512,20 @@ fn path_prefix_remapping_reverse() { // Returns `None` if multiple options match. { - let mapping = &FilePathMapping::new(vec![ - (path("abc"), path("/redacted")), - (path("def"), path("/redacted")), - ]); + let mapping = &FilePathMapping::new( + vec![(path("abc"), path("/redacted")), (path("def"), path("/redacted"))], + FileNameDisplayPreference::Remapped, + ); assert_eq!(reverse_map_prefix(mapping, "/redacted/hello.rs"), None); } // Distinct reverse mappings. { - let mapping = &FilePathMapping::new(vec![ - (path("abc"), path("/redacted")), - (path("def/ghi"), path("/fake/dir")), - ]); + let mapping = &FilePathMapping::new( + vec![(path("abc"), path("/redacted")), (path("def/ghi"), path("/fake/dir"))], + FileNameDisplayPreference::Remapped, + ); assert_eq!( reverse_map_prefix(mapping, "/redacted/path/hello.rs"), diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index 93ab154601f..bfc9e125362 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -126,7 +126,7 @@ impl Span { return Span { lo_or_index: lo2, len_with_tag_or_marker: PARENT_TAG | len as u16, - ctxt_or_parent_or_marker: parent2 as u16 + ctxt_or_parent_or_marker: parent2 as u16, }; } } diff --git a/compiler/rustc_target/src/abi/call/x86.rs b/compiler/rustc_target/src/abi/call/x86.rs index afa1b70efc2..c27f1e6ddda 100644 --- a/compiler/rustc_target/src/abi/call/x86.rs +++ b/compiler/rustc_target/src/abi/call/x86.rs @@ -72,7 +72,8 @@ where // - For backwards compatibility, arguments with natural alignment > 4 are still passed // on stack (via `byval`). For example, this includes `double`, `int64_t`, // and structs containing them, provided they lack an explicit alignment attribute. - assert!(arg.layout.align.abi >= max_repr_align, + assert!( + arg.layout.align.abi >= max_repr_align, "abi alignment {:?} less than requested alignment {max_repr_align:?}", arg.layout.align.abi, ); diff --git a/compiler/rustc_target/src/spec/abi.rs b/compiler/rustc_target/src/spec/abi.rs index a99cccd42c4..4c1f0c01a04 100644 --- a/compiler/rustc_target/src/spec/abi.rs +++ b/compiler/rustc_target/src/spec/abi.rs @@ -182,7 +182,7 @@ pub fn is_enabled( ) -> Result<(), AbiDisabled> { let s = is_stable(name); if let Err(AbiDisabled::Unstable { feature, .. }) = s { - if features.enabled(feature) || span.allows_unstable(feature) { + if features.active(feature) || span.allows_unstable(feature) { return Ok(()); } } diff --git a/compiler/rustc_target/src/spec/riscv64_linux_android.rs b/compiler/rustc_target/src/spec/riscv64_linux_android.rs index 91f5e562d8b..121237f6ba4 100644 --- a/compiler/rustc_target/src/spec/riscv64_linux_android.rs +++ b/compiler/rustc_target/src/spec/riscv64_linux_android.rs @@ -9,7 +9,7 @@ pub fn target() -> Target { options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), - features: "+m,+a,+f,+d,+c,+Zba,+Zbb,+Zbs".into(), + features: "+m,+a,+f,+d,+c,+zba,+zbb,+zbs,+v".into(), llvm_abiname: "lp64d".into(), supported_sanitizers: SanitizerSet::ADDRESS, max_atomic_width: Some(64), diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 8055c63b9f3..d87e05ad02f 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -136,12 +136,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // `assemble_candidates_after_normalizing_self_ty`, and we'd // just be registering an identical candidate here. // - // Returning `Err(NoSolution)` here is ok in `SolverMode::Coherence` - // since we'll always be registering an ambiguous candidate in + // We always return `Err(NoSolution)` here in `SolverMode::Coherence` + // since we'll always register an ambiguous candidate in // `assemble_candidates_after_normalizing_self_ty` due to normalizing // the TAIT. if let ty::Alias(ty::Opaque, opaque_ty) = goal.predicate.self_ty().kind() { if matches!(goal.param_env.reveal(), Reveal::All) + || matches!(ecx.solver_mode(), SolverMode::Coherence) || opaque_ty .def_id .as_local() diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs index fd813ca4ecb..5bc5a12a8fe 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs @@ -87,7 +87,9 @@ pub fn recompute_applicable_impls<'tcx>( if let ty::ClauseKind::Trait(trait_pred) = kind.skip_binder() && param_env_candidate_may_apply(kind.rebind(trait_pred)) { - if kind.rebind(trait_pred.trait_ref) == ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_pred.def_id())) { + if kind.rebind(trait_pred.trait_ref) + == ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_pred.def_id())) + { ambiguities.push(Ambiguity::ParamEnv(tcx.def_span(trait_pred.def_id()))) } else { ambiguities.push(Ambiguity::ParamEnv(span)) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index cc1f13a2f0f..9c9b78f4152 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -180,8 +180,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { flags.push((sym::cause, Some("MainFunctionType".to_string()))); } - // Add all types without trimmed paths. - ty::print::with_no_trimmed_paths!({ + // Add all types without trimmed paths or visible paths, ensuring they end up with + // their "canonical" def path. + ty::print::with_no_trimmed_paths!(ty::print::with_no_visible_paths!({ let generics = self.tcx.generics_of(def_id); let self_ty = trait_ref.self_ty(); // This is also included through the generics list as `Self`, @@ -296,7 +297,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { { flags.push((sym::_Self, Some("&[{integral}]".to_owned()))); } - }); + })); if let Ok(Some(command)) = OnUnimplementedDirective::of_item(self.tcx, def_id) { command.evaluate(self.tcx, trait_ref, &flags) @@ -368,7 +369,9 @@ impl<'tcx> OnUnimplementedDirective { .meta_item() .ok_or_else(|| tcx.sess.emit_err(InvalidOnClauseInOnUnimplemented { span }))?; attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |cfg| { - if let Some(value) = cfg.value && let Err(guar) = parse_value(value) { + if let Some(value) = cfg.value + && let Err(guar) = parse_value(value) + { errored = Some(guar); } true @@ -569,18 +572,22 @@ impl<'tcx> OnUnimplementedDirective { options.iter().filter_map(|(k, v)| v.clone().map(|v| (*k, v))).collect(); for command in self.subcommands.iter().chain(Some(self)).rev() { - if let Some(ref condition) = command.condition && !attr::eval_condition( - condition, - &tcx.sess.parse_sess, - Some(tcx.features()), - &mut |cfg| { - let value = cfg.value.map(|v| { - OnUnimplementedFormatString(v).format(tcx, trait_ref, &options_map) - }); - - options.contains(&(cfg.name, value)) - }, - ) { + if let Some(ref condition) = command.condition + && !attr::eval_condition( + condition, + &tcx.sess.parse_sess, + Some(tcx.features()), + &mut |cfg| { + let value = cfg.value.map(|v| { + // `with_no_visible_paths` is also used when generating the options, + // so we need to match it here. + ty::print::with_no_visible_paths!(OnUnimplementedFormatString(v).format(tcx, trait_ref, &options_map)) + }); + + options.contains(&(cfg.name, value)) + }, + ) + { debug!("evaluate: skipping {:?} due to condition", command); continue; } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 9aebe77a104..78f7f915f72 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -364,7 +364,7 @@ fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) - /// Type parameter needs more bounds. The trivial case is `T` `where T: Bound`, but /// it can also be an `impl Trait` param that needs to be decomposed to a type /// param for cleaner code. -fn suggest_restriction<'tcx>( +pub fn suggest_restriction<'tcx>( tcx: TyCtxt<'tcx>, item_id: LocalDefId, hir_generics: &hir::Generics<'tcx>, @@ -884,7 +884,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { return false; } - if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = obligation.predicate.kind().skip_binder() + if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = + obligation.predicate.kind().skip_binder() && Some(trait_pred.def_id()) == self.tcx.lang_items().sized_trait() { // Don't suggest calling to turn an unsized type into a sized type @@ -1156,15 +1157,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { && Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output() // args tuple will always be args[1] && let ty::Tuple(args) = proj.projection_ty.args.type_at(1).kind() - { - Some(( - DefIdOrName::DefId(def_id), - pred.kind().rebind(proj.term.ty().unwrap()), - pred.kind().rebind(args.as_slice()), - )) - } else { - None - } + { + Some(( + DefIdOrName::DefId(def_id), + pred.kind().rebind(proj.term.ty().unwrap()), + pred.kind().rebind(args.as_slice()), + )) + } else { + None + } }, ) } @@ -1174,43 +1175,43 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { && Some(proj.def_id) == self.tcx.lang_items().fn_once_output() // for existential projection, args are shifted over by 1 && let ty::Tuple(args) = proj.args.type_at(0).kind() - { - Some(( - DefIdOrName::Name("trait object"), - pred.rebind(proj.term.ty().unwrap()), - pred.rebind(args.as_slice()), - )) - } else { - None - } + { + Some(( + DefIdOrName::Name("trait object"), + pred.rebind(proj.term.ty().unwrap()), + pred.rebind(args.as_slice()), + )) + } else { + None + } }) } ty::Param(param) => { let generics = self.tcx.generics_of(body_id); let name = if generics.count() > param.index as usize - && let def = generics.param_at(param.index as usize, self.tcx) - && matches!(def.kind, ty::GenericParamDefKind::Type { .. }) - && def.name == param.name - { - DefIdOrName::DefId(def.def_id) - } else { - DefIdOrName::Name("type parameter") - }; + && let def = generics.param_at(param.index as usize, self.tcx) + && matches!(def.kind, ty::GenericParamDefKind::Type { .. }) + && def.name == param.name + { + DefIdOrName::DefId(def.def_id) + } else { + DefIdOrName::Name("type parameter") + }; param_env.caller_bounds().iter().find_map(|pred| { if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder() && Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output() && proj.projection_ty.self_ty() == found // args tuple will always be args[1] && let ty::Tuple(args) = proj.projection_ty.args.type_at(1).kind() - { - Some(( - name, - pred.kind().rebind(proj.term.ty().unwrap()), - pred.kind().rebind(args.as_slice()), - )) - } else { - None - } + { + Some(( + name, + pred.kind().rebind(proj.term.ty().unwrap()), + pred.kind().rebind(args.as_slice()), + )) + } else { + None + } }) } _ => None, @@ -1316,7 +1317,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref); let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) = - if let ObligationCauseCode::ItemObligation(_) | ObligationCauseCode::ExprItemObligation(..) = obligation.cause.code() + if let ObligationCauseCode::ItemObligation(_) + | ObligationCauseCode::ExprItemObligation(..) = obligation.cause.code() && let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind() { ( @@ -1618,7 +1620,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic) { let hir = self.tcx.hir(); - if let ObligationCauseCode::AwaitableExpr(Some(hir_id)) = obligation.cause.code().peel_derives() + if let ObligationCauseCode::AwaitableExpr(Some(hir_id)) = + obligation.cause.code().peel_derives() && let hir::Node::Expr(expr) = hir.get(*hir_id) { // FIXME: use `obligation.predicate.kind()...trait_ref.self_ty()` to see if we have `()` @@ -1630,7 +1633,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let Some((_, hir::Node::Expr(await_expr))) = hir.parent_iter(*hir_id).nth(1) && let Some(expr_span) = expr.span.find_ancestor_inside(await_expr.span) { - let removal_span = self.tcx + let removal_span = self + .tcx .sess .source_map() .span_extend_while(expr_span, char::is_whitespace) @@ -1654,30 +1658,28 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.span_label(*span, format!("this call returns `{}`", pred.self_ty())); } if let Some(typeck_results) = &self.typeck_results - && let ty = typeck_results.expr_ty_adjusted(base) - && let ty::FnDef(def_id, _args) = ty.kind() - && let Some(hir::Node::Item(hir::Item { ident, span, vis_span, .. })) = - hir.get_if_local(*def_id) - { - let msg = format!( - "alternatively, consider making `fn {ident}` asynchronous" + && let ty = typeck_results.expr_ty_adjusted(base) + && let ty::FnDef(def_id, _args) = ty.kind() + && let Some(hir::Node::Item(hir::Item { ident, span, vis_span, .. })) = + hir.get_if_local(*def_id) + { + let msg = format!("alternatively, consider making `fn {ident}` asynchronous"); + if vis_span.is_empty() { + err.span_suggestion_verbose( + span.shrink_to_lo(), + msg, + "async ", + Applicability::MaybeIncorrect, + ); + } else { + err.span_suggestion_verbose( + vis_span.shrink_to_hi(), + msg, + " async", + Applicability::MaybeIncorrect, ); - if vis_span.is_empty() { - err.span_suggestion_verbose( - span.shrink_to_lo(), - msg, - "async ", - Applicability::MaybeIncorrect, - ); - } else { - err.span_suggestion_verbose( - vis_span.shrink_to_hi(), - msg, - " async", - Applicability::MaybeIncorrect, - ); - } } + } } } } @@ -1791,13 +1793,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { "this expression has type `{}`, which implements `{}`", ty, trait_pred.print_modifiers_and_trait_path() - ) + ), ); err.span_suggestion( self.tcx.sess.source_map().end_point(stmt.span), "remove this semicolon", "", - Applicability::MachineApplicable + Applicability::MachineApplicable, ); return true; } @@ -1856,14 +1858,18 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let mut sugg = vec![(span.shrink_to_lo(), "Box<".to_string()), (span.shrink_to_hi(), ">".to_string())]; sugg.extend(visitor.returns.into_iter().flat_map(|expr| { - let span = expr.span.find_ancestor_in_same_ctxt(obligation.cause.span).unwrap_or(expr.span); + let span = + expr.span.find_ancestor_in_same_ctxt(obligation.cause.span).unwrap_or(expr.span); if !span.can_be_used_for_suggestions() { vec![] } else if let hir::ExprKind::Call(path, ..) = expr.kind && let hir::ExprKind::Path(hir::QPath::TypeRelative(ty, method)) = path.kind && method.ident.name == sym::new && let hir::TyKind::Path(hir::QPath::Resolved(.., box_path)) = ty.kind - && box_path.res.opt_def_id().is_some_and(|def_id| Some(def_id) == self.tcx.lang_items().owned_box()) + && box_path + .res + .opt_def_id() + .is_some_and(|def_id| Some(def_id) == self.tcx.lang_items().owned_box()) { // Don't box `Box::new` vec![] @@ -2013,15 +2019,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { { let expected_self = self.tcx.anonymize_bound_vars(pred.kind().rebind(trait_pred.self_ty())); - let expected_args = self - .tcx - .anonymize_bound_vars(pred.kind().rebind(trait_pred.trait_ref.args)); + let expected_args = + self.tcx.anonymize_bound_vars(pred.kind().rebind(trait_pred.trait_ref.args)); // Find another predicate whose self-type is equal to the expected self type, // but whose args don't match. - let other_pred = predicates.into_iter() - .enumerate() - .find(|(other_idx, (pred, _))| match pred.kind().skip_binder() { + let other_pred = predicates.into_iter().enumerate().find(|(other_idx, (pred, _))| { + match pred.kind().skip_binder() { ty::ClauseKind::Trait(trait_pred) if self.tcx.is_fn_trait(trait_pred.def_id()) && other_idx != idx @@ -2040,7 +2044,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { true } _ => false, - }); + } + }); // If we found one, then it's very likely the cause of the error. if let Some((_, (_, other_pred_span))) = other_pred { err.span_note( @@ -2647,7 +2652,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // Check for foreign traits being reachable. self.tcx.visible_parent_map(()).get(&def_id).is_some() }; - if let DefKind::Trait = tcx.def_kind(item_def_id) && !visible_item { + if let DefKind::Trait = tcx.def_kind(item_def_id) + && !visible_item + { // FIXME(estebank): extend this to search for all the types that do // implement this trait and list them. err.note(format!( @@ -2754,7 +2761,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { && let ty::ClauseKind::Trait(trait_pred) = clause && let ty::Dynamic(..) = trait_pred.self_ty().kind() { - let span = if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) + let span = if let Ok(snippet) = + self.tcx.sess.source_map().span_to_snippet(span) && snippet.starts_with("dyn ") { let pos = snippet.len() - snippet[3..].trim_start().len(); @@ -2845,8 +2853,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.note("all inline asm arguments must have a statically known size"); } ObligationCauseCode::SizedClosureCapture(closure_def_id) => { - err.note("all values captured by value by a closure must have a statically known size"); - let hir::ExprKind::Closure(closure) = self.tcx.hir().get_by_def_id(closure_def_id).expect_expr().kind else { + err.note( + "all values captured by value by a closure must have a statically known size", + ); + let hir::ExprKind::Closure(closure) = + self.tcx.hir().get_by_def_id(closure_def_id).expect_expr().kind + else { bug!("expected closure in SizedClosureCapture obligation"); }; if let hir::CaptureBy::Value = closure.capture_clause @@ -2860,7 +2872,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { None | Some(hir::GeneratorKind::Gen) => "yield", Some(hir::GeneratorKind::Async(..)) => "await", }; - err.note(format!("all values live across `{what}` must have a statically known size")); + err.note(format!( + "all values live across `{what}` must have a statically known size" + )); } ObligationCauseCode::ConstPatternStructural => { err.note("constants used for pattern-matching must derive `PartialEq` and `Eq`"); @@ -3385,15 +3399,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { trait_pred: ty::PolyTraitPredicate<'tcx>, ) { if let ObligationCauseCode::ImplDerivedObligation(_) = obligation.cause.code() - && self.tcx.is_diagnostic_item(sym::SliceIndex, trait_pred.skip_binder().trait_ref.def_id) + && self + .tcx + .is_diagnostic_item(sym::SliceIndex, trait_pred.skip_binder().trait_ref.def_id) && let ty::Slice(_) = trait_pred.skip_binder().trait_ref.args.type_at(1).kind() && let ty::Ref(_, inner_ty, _) = trait_pred.skip_binder().self_ty().kind() && let ty::Uint(ty::UintTy::Usize) = inner_ty.kind() { err.span_suggestion_verbose( obligation.cause.span.shrink_to_lo(), - "dereference this index", - '*', + "dereference this index", + '*', Applicability::MachineApplicable, ); } @@ -3415,7 +3431,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { { if let hir::Expr { kind: hir::ExprKind::Block(..), .. } = expr { let expr = expr.peel_blocks(); - let ty = typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(tcx,)); + let ty = + typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(tcx)); let span = expr.span; if Some(span) != err.span.primary_span() { err.span_label( @@ -3437,7 +3454,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let mut type_diffs = vec![]; if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = parent_code && let Some(node_args) = typeck_results.node_args_opt(call_hir_id) - && let where_clauses = self.tcx.predicates_of(def_id).instantiate(self.tcx, node_args) + && let where_clauses = + self.tcx.predicates_of(def_id).instantiate(self.tcx, node_args) && let Some(where_pred) = where_clauses.predicates.get(*idx) { if let Some(where_pred) = where_pred.as_trait_clause() @@ -3447,32 +3465,34 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let failed_pred = self.instantiate_binder_with_fresh_vars( expr.span, LateBoundRegionConversionTime::FnCall, - failed_pred + failed_pred, ); - let zipped = - iter::zip(where_pred.trait_ref.args, failed_pred.trait_ref.args); + let zipped = iter::zip(where_pred.trait_ref.args, failed_pred.trait_ref.args); for (expected, actual) in zipped { self.probe(|_| { - match self - .at(&ObligationCause::misc(expr.span, body_id), param_env) - .eq(DefineOpaqueTypes::No, expected, actual) - { + match self.at(&ObligationCause::misc(expr.span, body_id), param_env).eq( + DefineOpaqueTypes::No, + expected, + actual, + ) { Ok(_) => (), // We ignore nested obligations here for now. Err(err) => type_diffs.push(err), } }) - }; + } } else if let Some(where_pred) = where_pred.as_projection_clause() && let Some(failed_pred) = failed_pred.to_opt_poly_projection_pred() && let Some(found) = failed_pred.skip_binder().term.ty() { - type_diffs = vec![ - Sorts(ty::error::ExpectedFound { - expected: Ty::new_alias(self.tcx,ty::Projection, where_pred.skip_binder().projection_ty), - found, - }), - ]; + type_diffs = vec![Sorts(ty::error::ExpectedFound { + expected: Ty::new_alias( + self.tcx, + ty::Projection, + where_pred.skip_binder().projection_ty, + ), + found, + })]; } } if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind @@ -3586,7 +3606,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { msg, sugg, Applicability::MaybeIncorrect, - SuggestionStyle::ShowAlways + SuggestionStyle::ShowAlways, ); } } @@ -3638,9 +3658,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let hir::Node::Param(param) = parent { // ...and it is a an fn argument. let prev_ty = self.resolve_vars_if_possible( - typeck_results.node_type_opt(param.hir_id).unwrap_or(Ty::new_misc_error(tcx,)), + typeck_results + .node_type_opt(param.hir_id) + .unwrap_or(Ty::new_misc_error(tcx)), + ); + let assocs_in_this_method = self.probe_assoc_types_at_expr( + &type_diffs, + param.ty_span, + prev_ty, + param.hir_id, + param_env, ); - let assocs_in_this_method = self.probe_assoc_types_at_expr(&type_diffs, param.ty_span, prev_ty, param.hir_id, param_env); if assocs_in_this_method.iter().any(|a| a.is_some()) { assocs.push(assocs_in_this_method); print_root_expr = false; @@ -3651,7 +3679,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } // We want the type before deref coercions, otherwise we talk about `&[_]` // instead of `Vec<_>`. - if let Some(ty) = typeck_results.expr_ty_opt(expr) && print_root_expr { + if let Some(ty) = typeck_results.expr_ty_opt(expr) + && print_root_expr + { let ty = with_forced_trimmed_paths!(self.ty_to_string(ty)); // Point at the root expression // vec![1, 2, 3].iter().map(mapper).sum<i32>() @@ -4104,7 +4134,9 @@ fn hint_missing_borrow<'tcx>( let mut span = arg.span.shrink_to_lo(); let mut left = found_refs.len() - expected_refs.len(); let mut ty = arg; - while let hir::TyKind::Ref(_, mut_ty) = &ty.kind && left > 0 { + while let hir::TyKind::Ref(_, mut_ty) = &ty.kind + && left > 0 + { span = span.with_hi(mut_ty.ty.span.lo()); ty = mut_ty.ty; left -= 1; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 8adfb27a3f4..1020144a01b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -17,7 +17,7 @@ use crate::traits::{ use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::{ pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, - MultiSpan, Style, + MultiSpan, StashKey, Style, }; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace, Res}; @@ -2049,14 +2049,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // begin with in those cases. if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) { if let None = self.tainted_by_errors() { - self.emit_inference_failure_err( + let err = self.emit_inference_failure_err( obligation.cause.body_id, span, trait_ref.self_ty().skip_binder().into(), ErrorCode::E0282, false, - ) - .emit(); + ); + err.stash(span, StashKey::MaybeForgetReturn); } return; } @@ -2153,14 +2153,16 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } if let Some(ty::GenericArgKind::Type(_)) = subst.map(|subst| subst.unpack()) - && let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) + && let Some(body_id) = + self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) { let mut expr_finder = FindExprBySpan::new(span); expr_finder.visit_expr(&self.tcx.hir().body(body_id).value); if let Some(hir::Expr { - kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)), .. } - ) = expr_finder.result + kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)), + .. + }) = expr_finder.result && let [ .., trait_path_segment @ hir::PathSegment { @@ -2171,7 +2173,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ident: assoc_item_name, res: Res::Def(_, item_id), .. - } + }, ] = path.segments && data.trait_ref.def_id == *trait_id && self.tcx.trait_of_item(*item_id) == Some(*trait_id) @@ -2239,23 +2241,26 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { "/* self type */".to_string(), ) }; - let mut suggestions = vec![( - path.span.shrink_to_lo(), - format!("<{self_type} as "), - )]; + let mut suggestions = + vec![(path.span.shrink_to_lo(), format!("<{self_type} as "))]; if let Some(generic_arg) = trait_path_segment.args { - let between_span = trait_path_segment.ident.span.between(generic_arg.span_ext); + let between_span = + trait_path_segment.ident.span.between(generic_arg.span_ext); // get rid of :: between Trait and <type> // must be '::' between them, otherwise the parser won't accept the code - suggestions.push((between_span, "".to_string(),)); - suggestions.push((generic_arg.span_ext.shrink_to_hi(), ">".to_string())); + suggestions.push((between_span, "".to_string())); + suggestions + .push((generic_arg.span_ext.shrink_to_hi(), ">".to_string())); } else { - suggestions.push((trait_path_segment.ident.span.shrink_to_hi(), ">".to_string())); + suggestions.push(( + trait_path_segment.ident.span.shrink_to_hi(), + ">".to_string(), + )); } err.multipart_suggestion( message, suggestions, - Applicability::MaybeIncorrect + Applicability::MaybeIncorrect, ); } } @@ -2965,8 +2970,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ); } else if !self.same_type_modulo_infer(given_ty, expected_ty) { // Print type mismatch - let (expected_args, given_args) = - self.cmp(given_ty, expected_ty); + let (expected_args, given_args) = self.cmp(given_ty, expected_ty); err.note_expected_found( &"a closure with arguments", expected_args, diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 5823b4508d9..2d05f934393 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -584,10 +584,9 @@ fn virtual_call_violation_for_method<'tcx>( // would already have reported an error at the definition of the // auto trait. if pred_trait_ref.args.len() != 1 { - tcx.sess.diagnostic().delay_span_bug( - span, - "auto traits cannot have generic parameters", - ); + tcx.sess + .diagnostic() + .delay_span_bug(span, "auto traits cannot have generic parameters"); } return false; } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 73c2ff3c536..175cc2b116b 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1233,7 +1233,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( let projected_term = selcx.infcx.resolve_vars_if_possible(projected_term); - let result = if projected_term.has_projections() { + let mut result = if projected_term.has_projections() { let mut normalizer = AssocTypeNormalizer::new( selcx, param_env, @@ -1243,14 +1243,14 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( ); let normalized_ty = normalizer.fold(projected_term); - let mut deduped = SsoHashSet::with_capacity(projected_obligations.len()); - projected_obligations.retain(|obligation| deduped.insert(obligation.clone())); - Normalized { value: normalized_ty, obligations: projected_obligations } } else { Normalized { value: projected_term, obligations: projected_obligations } }; + let mut deduped = SsoHashSet::with_capacity(result.obligations.len()); + result.obligations.retain(|obligation| deduped.insert(obligation.clone())); + if use_cache { infcx.inner.borrow_mut().projection_cache().insert_term(cache_key, result.clone()); } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index bead8758ad6..f08cf6cef5b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -492,7 +492,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // this trait and type. } ty::Param(..) - | ty::Alias(ty::Projection | ty::Inherent, ..) + | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..) | ty::Placeholder(..) | ty::Bound(..) => { // In these cases, we don't know what the actual @@ -536,20 +536,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); } - ty::Alias(_, _) - if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(..))) => - { - // We do not generate an auto impl candidate for `impl Trait`s which already - // reference our auto trait. - // - // For example during candidate assembly for `impl Send: Send`, we don't have - // to look at the constituent types for this opaque types to figure out that this - // trivially holds. - // - // Note that this is only sound as projection candidates of opaque types - // are always applicable for auto traits. + ty::Alias(ty::Opaque, _) => { + if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(..))) { + // We do not generate an auto impl candidate for `impl Trait`s which already + // reference our auto trait. + // + // For example during candidate assembly for `impl Send: Send`, we don't have + // to look at the constituent types for this opaque types to figure out that this + // trivially holds. + // + // Note that this is only sound as projection candidates of opaque types + // are always applicable for auto traits. + } else if self.infcx.intercrate { + // We do not emit auto trait candidates for opaque types in coherence. + // Doing so can result in weird dependency cycles. + candidates.ambiguous = true; + } else { + candidates.vec.push(AutoImplCandidate) + } } - ty::Alias(_, _) => candidates.vec.push(AutoImplCandidate), ty::Bool | ty::Char diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 8871de194a6..97366a93e31 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -860,7 +860,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { subobligations, ); if let Ok(eval_rslt) = res - && (eval_rslt == EvaluatedToOk || eval_rslt == EvaluatedToOkModuloRegions) + && (eval_rslt == EvaluatedToOk + || eval_rslt == EvaluatedToOkModuloRegions) && let Some(key) = ProjectionCacheKey::from_poly_projection_predicate( self, data, diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index a76272e9d09..4ef2027d7e8 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -326,7 +326,8 @@ pub fn check_args_compatible<'tcx>( if let Some(parent) = generics.parent && let parent_generics = tcx.generics_of(parent) - && !check_args_compatible_inner(tcx, parent_generics, parent_args) { + && !check_args_compatible_inner(tcx, parent_generics, parent_args) + { return false; } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 060df772613..e7e4ee983fb 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -254,7 +254,8 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>( // projection coming from another associated type. See // `tests/ui/associated-types/point-at-type-on-obligation-failure.rs` and // `traits-assoc-type-in-supertrait-bad.rs`. - if let Some(ty::Alias(ty::Projection, projection_ty)) = proj.term.ty().map(|ty| ty.kind()) + if let Some(ty::Alias(ty::Projection, projection_ty)) = + proj.term.ty().map(|ty| ty.kind()) && let Some(&impl_item_id) = tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.def_id) && let Some(impl_item_span) = items @@ -270,8 +271,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>( // can be seen in `ui/associated-types/point-at-type-on-obligation-failure-2.rs`. debug!("extended_cause_with_original_assoc_item_obligation trait proj {:?}", pred); if let ty::Alias(ty::Projection, ty::AliasTy { def_id, .. }) = *pred.self_ty().kind() - && let Some(&impl_item_id) = - tcx.impl_item_implementor_ids(impl_def_id).get(&def_id) + && let Some(&impl_item_id) = tcx.impl_item_implementor_ids(impl_def_id).get(&def_id) && let Some(impl_item_span) = items .iter() .find(|item| item.id.owner_id.to_def_id() == impl_item_id) diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 780f7ea426f..3e140793b5a 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -192,7 +192,8 @@ fn associated_types_for_impl_traits_in_associated_fn( if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind && self.rpits.insert(item_id.owner_id.def_id) { - let opaque_item = self.tcx.hir().expect_item(item_id.owner_id.def_id).expect_opaque_ty(); + let opaque_item = + self.tcx.hir().expect_item(item_id.owner_id.def_id).expect_opaque_ty(); for bound in opaque_item.bounds { intravisit::walk_param_bound(self, bound); } diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index ec2e0daaf88..0ca7d43f6d5 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -50,73 +50,76 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' let mut impl_spans = impl_spans(tcx, def_id); tcx.arena.alloc_from_iter(tys.into_iter().map(|ty| (ty, impl_spans.next().unwrap()))) } - DefKind::AssocTy if let Some(data) = tcx.opt_rpitit_info(def_id.to_def_id()) => match data { - ty::ImplTraitInTraitData::Trait { fn_def_id, .. } => { - // We need to remap all of the late-bound lifetimes in theassumed wf types - // of the fn (which are represented as ReFree) to the early-bound lifetimes - // of the RPITIT (which are represented by ReEarlyBound owned by the opaque). - // Luckily, this is very easy to do because we already have that mapping - // stored in the HIR of this RPITIT. - // - // Side-note: We don't really need to do this remapping for early-bound - // lifetimes because they're already "linked" by the bidirectional outlives - // predicates we insert in the `explicit_predicates_of` query for RPITITs. - let mut mapping = FxHashMap::default(); - let generics = tcx.generics_of(def_id); + DefKind::AssocTy if let Some(data) = tcx.opt_rpitit_info(def_id.to_def_id()) => { + match data { + ty::ImplTraitInTraitData::Trait { fn_def_id, .. } => { + // We need to remap all of the late-bound lifetimes in theassumed wf types + // of the fn (which are represented as ReFree) to the early-bound lifetimes + // of the RPITIT (which are represented by ReEarlyBound owned by the opaque). + // Luckily, this is very easy to do because we already have that mapping + // stored in the HIR of this RPITIT. + // + // Side-note: We don't really need to do this remapping for early-bound + // lifetimes because they're already "linked" by the bidirectional outlives + // predicates we insert in the `explicit_predicates_of` query for RPITITs. + let mut mapping = FxHashMap::default(); + let generics = tcx.generics_of(def_id); - // For each captured opaque lifetime, if it's late-bound (`ReFree` in this case, - // since it has been liberated), map it back to the early-bound lifetime of - // the GAT. Since RPITITs also have all of the fn's generics, we slice only - // the end of the list corresponding to the opaque's generics. - for param in &generics.params[tcx.generics_of(fn_def_id).params.len()..] { - let orig_lt = tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()); - if matches!(*orig_lt, ty::ReFree(..)) { - mapping.insert( - orig_lt, - ty::Region::new_early_bound( - tcx, - ty::EarlyBoundRegion { - def_id: param.def_id, - index: param.index, - name: param.name, - }, - ), - ); + // For each captured opaque lifetime, if it's late-bound (`ReFree` in this case, + // since it has been liberated), map it back to the early-bound lifetime of + // the GAT. Since RPITITs also have all of the fn's generics, we slice only + // the end of the list corresponding to the opaque's generics. + for param in &generics.params[tcx.generics_of(fn_def_id).params.len()..] { + let orig_lt = + tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()); + if matches!(*orig_lt, ty::ReFree(..)) { + mapping.insert( + orig_lt, + ty::Region::new_early_bound( + tcx, + ty::EarlyBoundRegion { + def_id: param.def_id, + index: param.index, + name: param.name, + }, + ), + ); + } } + // FIXME: This could use a real folder, I guess. + let remapped_wf_tys = tcx.fold_regions( + tcx.assumed_wf_types(fn_def_id.expect_local()).to_vec(), + |region, _| { + // If `region` is a `ReFree` that is captured by the + // opaque, remap it to its corresponding the early- + // bound region. + if let Some(remapped_region) = mapping.get(®ion) { + *remapped_region + } else { + region + } + }, + ); + tcx.arena.alloc_from_iter(remapped_wf_tys) + } + // Assumed wf types for RPITITs in an impl just inherit (and instantiate) + // the assumed wf types of the trait's RPITIT GAT. + ty::ImplTraitInTraitData::Impl { .. } => { + let impl_def_id = tcx.local_parent(def_id); + let rpitit_def_id = tcx.associated_item(def_id).trait_item_def_id.unwrap(); + let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto( + tcx, + impl_def_id.to_def_id(), + tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity().args, + ); + tcx.arena.alloc_from_iter( + ty::EarlyBinder::bind(tcx.assumed_wf_types_for_rpitit(rpitit_def_id)) + .iter_instantiated_copied(tcx, args) + .chain(tcx.assumed_wf_types(impl_def_id).into_iter().copied()), + ) } - // FIXME: This could use a real folder, I guess. - let remapped_wf_tys = tcx.fold_regions( - tcx.assumed_wf_types(fn_def_id.expect_local()).to_vec(), - |region, _| { - // If `region` is a `ReFree` that is captured by the - // opaque, remap it to its corresponding the early- - // bound region. - if let Some(remapped_region) = mapping.get(®ion) { - *remapped_region - } else { - region - } - }, - ); - tcx.arena.alloc_from_iter(remapped_wf_tys) - } - // Assumed wf types for RPITITs in an impl just inherit (and instantiate) - // the assumed wf types of the trait's RPITIT GAT. - ty::ImplTraitInTraitData::Impl { .. } => { - let impl_def_id = tcx.local_parent(def_id); - let rpitit_def_id = tcx.associated_item(def_id).trait_item_def_id.unwrap(); - let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto( - tcx, - impl_def_id.to_def_id(), - tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity().args, - ); - tcx.arena.alloc_from_iter( - ty::EarlyBinder::bind(tcx.assumed_wf_types_for_rpitit(rpitit_def_id)) - .iter_instantiated_copied(tcx, args) - .chain(tcx.assumed_wf_types(impl_def_id).into_iter().copied()), - ) } - }, + } DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)), DefKind::OpaqueTy => match tcx.def_kind(tcx.local_parent(def_id)) { DefKind::TyAlias => ty::List::empty(), diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 91f1c21310e..2fbf87800bb 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -188,10 +188,7 @@ fn resolve_associated_item<'tcx>( && trait_item_id != leaf_def.item.def_id && let Some(leaf_def_item) = leaf_def.item.def_id.as_local() { - tcx.compare_impl_const(( - leaf_def_item, - trait_item_id, - ))?; + tcx.compare_impl_const((leaf_def_item, trait_item_id))?; } Some(ty::Instance::new(leaf_def.item.def_id, args)) diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 8132742d1df..cc6c8478785 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -170,29 +170,27 @@ fn layout_of_uncached<'tcx>( // fall back to structurally deducing metadata. && !pointee.references_error() { - let pointee_metadata = Ty::new_projection(tcx,metadata_def_id, [pointee]); - let metadata_ty = match tcx.try_normalize_erasing_regions( - param_env, - pointee_metadata, - ) { - Ok(metadata_ty) => metadata_ty, - Err(mut err) => { - // Usually `<Ty as Pointee>::Metadata` can't be normalized because - // its struct tail cannot be normalized either, so try to get a - // more descriptive layout error here, which will lead to less confusing - // diagnostics. - match tcx.try_normalize_erasing_regions( - param_env, - tcx.struct_tail_without_normalization(pointee), - ) { - Ok(_) => {}, - Err(better_err) => { - err = better_err; + let pointee_metadata = Ty::new_projection(tcx, metadata_def_id, [pointee]); + let metadata_ty = + match tcx.try_normalize_erasing_regions(param_env, pointee_metadata) { + Ok(metadata_ty) => metadata_ty, + Err(mut err) => { + // Usually `<Ty as Pointee>::Metadata` can't be normalized because + // its struct tail cannot be normalized either, so try to get a + // more descriptive layout error here, which will lead to less confusing + // diagnostics. + match tcx.try_normalize_erasing_regions( + param_env, + tcx.struct_tail_without_normalization(pointee), + ) { + Ok(_) => {} + Err(better_err) => { + err = better_err; + } } + return Err(error(cx, LayoutError::NormalizationFailure(pointee, err))); } - return Err(error(cx, LayoutError::NormalizationFailure(pointee, err))); - }, - }; + }; let metadata_layout = cx.layout_of(metadata_ty)?; // If the metadata is a 1-zst, then the pointer is thin. diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index c22c67bd907..e1ec159921e 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -184,9 +184,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> { fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> { if let ty::Alias(ty::Projection, unshifted_alias_ty) = *ty.kind() - && let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. } - | ty::ImplTraitInTraitData::Impl { fn_def_id, .. }) - = self.tcx.opt_rpitit_info(unshifted_alias_ty.def_id) + && let Some( + ty::ImplTraitInTraitData::Trait { fn_def_id, .. } + | ty::ImplTraitInTraitData::Impl { fn_def_id, .. }, + ) = self.tcx.opt_rpitit_info(unshifted_alias_ty.def_id) && fn_def_id == self.fn_def_id && self.seen.insert(unshifted_alias_ty.def_id) { @@ -202,7 +203,11 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> { "we shouldn't walk non-predicate binders with `impl Trait`...", ); } - ty::Region::new_late_bound(self.tcx, index.shifted_out_to_binder(self.depth), bv) + ty::Region::new_late_bound( + self.tcx, + index.shifted_out_to_binder(self.depth), + bv, + ) } else { re } @@ -211,12 +216,21 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> { // If we're lowering to associated item, install the opaque type which is just // the `type_of` of the trait's associated item. If we're using the old lowering // strategy, then just reinterpret the associated type like an opaque :^) - let default_ty = self.tcx.type_of(shifted_alias_ty.def_id).instantiate(self.tcx, shifted_alias_ty.args); - - self.predicates.push(ty::Binder::bind_with_vars( - ty::ProjectionPredicate { projection_ty: shifted_alias_ty, term: default_ty.into() }, - self.bound_vars, - ).to_predicate(self.tcx)); + let default_ty = self + .tcx + .type_of(shifted_alias_ty.def_id) + .instantiate(self.tcx, shifted_alias_ty.args); + + self.predicates.push( + ty::Binder::bind_with_vars( + ty::ProjectionPredicate { + projection_ty: shifted_alias_ty, + term: default_ty.into(), + }, + self.bound_vars, + ) + .to_predicate(self.tcx), + ); // We walk the *un-shifted* alias ty, because we're tracking the de bruijn // binder depth, and if we were to walk `shifted_alias_ty` instead, we'd diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index f371f46204f..a3b05f2435e 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -22,8 +22,8 @@ use std::fmt; use std::fmt::Debug; use self::ty::{ - GenericPredicates, Generics, ImplDef, ImplTrait, IndexedVal, Span, TraitDecl, TraitDef, Ty, - TyKind, + GenericPredicates, Generics, ImplDef, ImplTrait, IndexedVal, LineInfo, Span, TraitDecl, + TraitDef, Ty, TyKind, }; #[macro_use] @@ -108,6 +108,7 @@ pub struct Crate { } pub type DefKind = Opaque; +pub type Filename = Opaque; /// Holds information about an item in the crate. /// For now, it only stores the item DefId. Use functions inside `rustc_internal` module to @@ -196,13 +197,19 @@ pub trait Context { /// Find a crate with the given name. fn find_crates(&self, name: &str) -> Vec<Crate>; - /// Prints the name of given `DefId` + /// Returns the name of given `DefId` fn name_of_def_id(&self, def_id: DefId) -> String; - /// Prints a human readable form of `Span` - fn print_span(&self, span: Span) -> String; + /// Returns printable, human readable form of `Span` + fn span_to_string(&self, span: Span) -> String; - /// Prints the kind of given `DefId` + /// Return filename from given `Span`, for diagnostic purposes + fn get_filename(&self, span: &Span) -> Filename; + + /// Return lines corresponding to this `Span` + fn get_lines(&self, span: &Span) -> LineInfo; + + /// Returns the `kind` of given `DefId` fn def_kind(&mut self, def_id: DefId) -> DefKind; /// `Span` of an item diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index 691af15da8c..003045a4696 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -3,7 +3,7 @@ use super::{ mir::{Body, Mutability}, with, AllocId, DefId, Symbol, }; -use crate::Opaque; +use crate::{Filename, Opaque}; use std::fmt::{self, Debug, Formatter}; #[derive(Copy, Clone)] @@ -81,11 +81,33 @@ impl Debug for Span { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("Span") .field("id", &self.0) - .field("repr", &with(|cx| cx.print_span(*self))) + .field("repr", &with(|cx| cx.span_to_string(*self))) .finish() } } +impl Span { + /// Return filename for diagnostic purposes + pub fn get_filename(&self) -> Filename { + with(|c| c.get_filename(self)) + } + + /// Return lines that corespond to this `Span` + pub fn get_lines(&self) -> LineInfo { + with(|c| c.get_lines(&self)) + } +} + +#[derive(Clone, Copy, Debug)] +/// Information you get from `Span` in a struct form. +/// Line and col start from 1. +pub struct LineInfo { + pub start_line: usize, + pub start_col: usize, + pub end_line: usize, + pub end_col: usize, +} + impl IndexedVal for Span { fn to_val(index: usize) -> Self { Span(index) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 73cb746c41d..dd7876bed76 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1304,7 +1304,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> { /// assert_eq!(unsafe { &*x_ptr }, "hello"); /// ``` #[stable(feature = "rc_raw", since = "1.17.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] pub fn into_raw(this: Self) -> *const T { let ptr = Self::as_ptr(&this); mem::forget(this); @@ -1328,7 +1328,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> { /// assert_eq!(unsafe { &*x_ptr }, "hello"); /// ``` #[stable(feature = "weak_into_raw", since = "1.45.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] pub fn as_ptr(this: &Self) -> *const T { let ptr: *mut RcBox<T> = NonNull::as_ptr(this.ptr); @@ -2409,7 +2409,7 @@ impl<T> From<T> for Rc<T> { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_array", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_array", since = "1.74.0")] impl<T, const N: usize> From<[T; N]> for Rc<[T]> { /// Converts a [`[T; N]`](prim@array) into an `Rc<[T]>`. /// diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 0c6f3ef9b73..351e6c1a4b3 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1455,7 +1455,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> { /// ``` #[must_use = "losing the pointer will leak memory"] #[stable(feature = "rc_raw", since = "1.17.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] pub fn into_raw(this: Self) -> *const T { let ptr = Self::as_ptr(&this); mem::forget(this); @@ -1480,7 +1480,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> { /// ``` #[must_use] #[stable(feature = "rc_as_ptr", since = "1.45.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] pub fn as_ptr(this: &Self) -> *const T { let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr); @@ -3271,7 +3271,7 @@ impl<T> From<T> for Arc<T> { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_array", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_array", since = "1.74.0")] impl<T, const N: usize> From<[T; N]> for Arc<[T]> { /// Converts a [`[T; N]`](prim@array) into an `Arc<[T]>`. /// diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 6f0cd5316a0..3b12c1bee0b 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1258,7 +1258,7 @@ impl<T, A: Allocator> Vec<T, A> { /// [`as_mut_ptr`]: Vec::as_mut_ptr /// [`as_ptr`]: Vec::as_ptr #[stable(feature = "vec_as_ptr", since = "1.37.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] #[inline] pub fn as_ptr(&self) -> *const T { // We shadow the slice method of the same name to avoid going through @@ -1318,7 +1318,7 @@ impl<T, A: Allocator> Vec<T, A> { /// [`as_mut_ptr`]: Vec::as_mut_ptr /// [`as_ptr`]: Vec::as_ptr #[stable(feature = "vec_as_ptr", since = "1.37.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] #[inline] pub fn as_mut_ptr(&mut self) -> *mut T { // We shadow the slice method of the same name to avoid going through @@ -1956,6 +1956,7 @@ impl<T, A: Allocator> Vec<T, A> { } else { unsafe { self.len -= 1; + core::intrinsics::assume(self.len < self.capacity()); Some(ptr::read(self.as_ptr().add(self.len()))) } } @@ -3155,7 +3156,7 @@ impl<T: Clone> From<&mut [T]> for Vec<T> { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "vec_from_array_ref", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "vec_from_array_ref", since = "1.74.0")] impl<T: Clone, const N: usize> From<&[T; N]> for Vec<T> { /// Allocate a `Vec<T>` and fill it by cloning `s`'s items. /// @@ -3170,7 +3171,7 @@ impl<T: Clone, const N: usize> From<&[T; N]> for Vec<T> { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "vec_from_array_ref", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "vec_from_array_ref", since = "1.74.0")] impl<T: Clone, const N: usize> From<&mut [T; N]> for Vec<T> { /// Allocate a `Vec<T>` and fill it by cloning `s`'s items. /// diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index 59730303734..65946e09ff9 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -130,6 +130,8 @@ impl Layout { } /// The minimum byte alignment for a memory block of this layout. + /// + /// The returned alignment is guaranteed to be a power of two. #[stable(feature = "alloc_layout", since = "1.28.0")] #[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")] #[must_use = "this returns the minimum alignment, \ diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index 8815cb21fc4..321357a15bf 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -4,7 +4,7 @@ use crate::num::NonZeroUsize; use crate::{ fmt, intrinsics::transmute_unchecked, - iter::{self, ExactSizeIterator, FusedIterator, TrustedLen}, + iter::{self, ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccessNoCoerce}, mem::MaybeUninit, ops::{IndexRange, Range}, ptr, @@ -294,6 +294,12 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> { NonZeroUsize::new(remaining).map_or(Ok(()), Err) } + + #[inline] + unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item { + // SAFETY: The caller must provide an idx that is in bound of the remainder. + unsafe { self.data.as_ptr().add(self.alive.start()).add(idx).cast::<T>().read() } + } } #[stable(feature = "array_value_iter_impls", since = "1.40.0")] @@ -375,6 +381,25 @@ impl<T, const N: usize> FusedIterator for IntoIter<T, N> {} #[stable(feature = "array_value_iter_impls", since = "1.40.0")] unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, N> {} +#[doc(hidden)] +#[unstable(issue = "none", feature = "std_internals")] +#[rustc_unsafe_specialization_marker] +pub trait NonDrop {} + +// T: Copy as approximation for !Drop since get_unchecked does not advance self.alive +// and thus we can't implement drop-handling +#[unstable(issue = "none", feature = "std_internals")] +impl<T: Copy> NonDrop for T {} + +#[doc(hidden)] +#[unstable(issue = "none", feature = "std_internals")] +unsafe impl<T, const N: usize> TrustedRandomAccessNoCoerce for IntoIter<T, N> +where + T: NonDrop, +{ + const MAY_HAVE_SIDE_EFFECT: bool = false; +} + #[stable(feature = "array_value_iter_impls", since = "1.40.0")] impl<T: Clone, const N: usize> Clone for IntoIter<T, N> { fn clone(&self) -> Self { diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index db07ef7e3c9..f3d8b54d4e9 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -556,7 +556,7 @@ impl<T: ?Sized> Cell<T> { #[inline] #[stable(feature = "cell_as_ptr", since = "1.12.0")] #[rustc_const_stable(feature = "const_cell_as_ptr", since = "1.32.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] pub const fn as_ptr(&self) -> *mut T { self.value.get() } @@ -1112,7 +1112,7 @@ impl<T: ?Sized> RefCell<T> { /// ``` #[inline] #[stable(feature = "cell_as_ptr", since = "1.12.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] pub fn as_ptr(&self) -> *mut T { self.value.get() } @@ -2109,7 +2109,7 @@ impl<T: ?Sized> UnsafeCell<T> { #[inline(always)] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_unsafecell_get", since = "1.32.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] pub const fn get(&self) -> *mut T { // We can just cast the pointer from `UnsafeCell<T>` to `T` because of // #[repr(transparent)]. This exploits std's special status, there is @@ -2253,7 +2253,7 @@ impl<T: ?Sized> SyncUnsafeCell<T> { /// when casting to `&mut T`, and ensure that there are no mutations /// or mutable aliases going on when casting to `&T` #[inline] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] pub const fn get(&self) -> *mut T { self.value.get() } diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs index 2e8534f651a..3877a0c48cb 100644 --- a/library/core/src/cell/once.rs +++ b/library/core/src/cell/once.rs @@ -87,10 +87,40 @@ impl<T> OnceCell<T> { #[inline] #[stable(feature = "once_cell", since = "1.70.0")] pub fn set(&self, value: T) -> Result<(), T> { - // SAFETY: Safe because we cannot have overlapping mutable borrows - let slot = unsafe { &*self.inner.get() }; - if slot.is_some() { - return Err(value); + match self.try_insert(value) { + Ok(_) => Ok(()), + Err((_, value)) => Err(value), + } + } + + /// Sets the contents of the cell to `value` if the cell was empty, then + /// returns a reference to it. + /// + /// # Errors + /// + /// This method returns `Ok(&value)` if the cell was empty and + /// `Err(¤t_value, value)` if it was full. + /// + /// # Examples + /// + /// ``` + /// #![feature(once_cell_try_insert)] + /// + /// use std::cell::OnceCell; + /// + /// let cell = OnceCell::new(); + /// assert!(cell.get().is_none()); + /// + /// assert_eq!(cell.try_insert(92), Ok(&92)); + /// assert_eq!(cell.try_insert(62), Err((&92, 62))); + /// + /// assert!(cell.get().is_some()); + /// ``` + #[inline] + #[unstable(feature = "once_cell_try_insert", issue = "116693")] + pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> { + if let Some(old) = self.get() { + return Err((old, value)); } // SAFETY: This is the only place where we set the slot, no races @@ -98,8 +128,7 @@ impl<T> OnceCell<T> { // checked that slot is currently `None`, so this write // maintains the `inner`'s invariant. let slot = unsafe { &mut *self.inner.get() }; - *slot = Some(value); - Ok(()) + Ok(slot.insert(value)) } /// Gets the contents of the cell, initializing it with `f` @@ -183,10 +212,9 @@ impl<T> OnceCell<T> { let val = outlined_call(f)?; // Note that *some* forms of reentrant initialization might lead to // UB (see `reentrant_init` test). I believe that just removing this - // `assert`, while keeping `set/get` would be sound, but it seems + // `panic`, while keeping `try_insert` would be sound, but it seems // better to panic, rather than to silently use an old value. - assert!(self.set(val).is_ok(), "reentrant init"); - Ok(self.get().unwrap()) + if let Ok(val) = self.try_insert(val) { Ok(val) } else { panic!("reentrant init") } } /// Consumes the cell, returning the wrapped value. diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index b6b36886604..453de9754be 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -115,7 +115,7 @@ impl TryFrom<char> for u8 { /// failing if the code point is greater than U+FFFF. /// /// This corresponds to the UCS-2 encoding, as specified in ISO/IEC 10646:2003. -#[stable(feature = "u16_from_char", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "u16_from_char", since = "1.74.0")] impl TryFrom<char> for u16 { type Error = TryFromCharError; diff --git a/library/core/src/char/decode.rs b/library/core/src/char/decode.rs index dbfe251f2bb..d76f983d87c 100644 --- a/library/core/src/char/decode.rs +++ b/library/core/src/char/decode.rs @@ -2,6 +2,7 @@ use crate::error::Error; use crate::fmt; +use crate::iter::FusedIterator; /// An iterator that decodes UTF-16 encoded code points from an iterator of `u16`s. /// @@ -105,6 +106,9 @@ impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> { } } +#[stable(feature = "decode_utf16_fused_iterator", since = "CURRENT_RUSTC_VERSION")] +impl<I: Iterator<Item = u16> + FusedIterator> FusedIterator for DecodeUtf16<I> {} + impl DecodeUtf16Error { /// Returns the unpaired surrogate which caused this error. #[must_use] diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index ca4e6be71ef..227746b62c8 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -311,8 +311,7 @@ pub trait Eq: PartialEq<Self> { // // This should never be implemented by hand. #[doc(hidden)] - #[cfg_attr(bootstrap, no_coverage)] // rust-lang/rust#84605 - #[cfg_attr(not(bootstrap), coverage(off))] // + #[coverage(off)] #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn assert_receiver_is_total_eq(&self) {} @@ -322,8 +321,7 @@ pub trait Eq: PartialEq<Self> { #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics, derive_eq, structural_match)] -#[cfg_attr(bootstrap, allow_internal_unstable(no_coverage))] -#[cfg_attr(not(bootstrap), allow_internal_unstable(coverage_attribute))] +#[allow_internal_unstable(coverage_attribute)] pub macro Eq($item:item) { /* compiler built-in */ } diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index fc8d19d1a58..89125b7955e 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -573,7 +573,7 @@ pub trait Into<T>: Sized { #[rustc_diagnostic_item = "From"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented(on( - all(_Self = "&str", any(T = "alloc::string::String", T = "std::string::String")), + all(_Self = "&str", T = "alloc::string::String"), note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix", ))] pub trait From<T>: Sized { @@ -618,12 +618,11 @@ pub trait TryInto<T>: Sized { /// For example, there is no way to convert an [`i64`] into an [`i32`] /// using the [`From`] trait, because an [`i64`] may contain a value /// that an [`i32`] cannot represent and so the conversion would lose data. -/// This might be handled by truncating the [`i64`] to an [`i32`] (essentially -/// giving the [`i64`]'s value modulo [`i32::MAX`]) or by simply returning -/// [`i32::MAX`], or by some other method. The [`From`] trait is intended -/// for perfect conversions, so the `TryFrom` trait informs the -/// programmer when a type conversion could go bad and lets them -/// decide how to handle it. +/// This might be handled by truncating the [`i64`] to an [`i32`] or by +/// simply returning [`i32::MAX`], or by some other method. The [`From`] +/// trait is intended for perfect conversions, so the `TryFrom` trait +/// informs the programmer when a type conversion could go bad and lets +/// them decide how to handle it. /// /// # Generic Implementations /// diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 93a6716d7ab..e7ec1fb73cd 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -487,7 +487,7 @@ impl CStr { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_str_as_ptr", since = "1.32.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] pub const fn as_ptr(&self) -> *const c_char { self.inner.as_ptr() } diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index cab195dad9b..b26a17ec30e 100644 --- a/library/core/src/intrinsics/mir.rs +++ b/library/core/src/intrinsics/mir.rs @@ -12,8 +12,7 @@ //! //! Typical usage will look like this: //! -#![cfg_attr(bootstrap, doc = "```rust,ignore")] -#![cfg_attr(not(bootstrap), doc = "```rust")] +//! ```rust //! #![feature(core_intrinsics, custom_mir)] //! #![allow(internal_features)] //! @@ -63,8 +62,7 @@ //! //! # Examples //! -#![cfg_attr(bootstrap, doc = "```rust,ignore")] -#![cfg_attr(not(bootstrap), doc = "```rust")] +//! ```rust //! #![feature(core_intrinsics, custom_mir)] //! #![allow(internal_features)] //! @@ -106,7 +104,6 @@ //! } //! //! #[custom_mir(dialect = "runtime", phase = "optimized")] -#![cfg_attr(bootstrap, doc = "#[cfg(any())]")] // disable the following function in doctests when `bootstrap` is set //! fn push_and_pop<T>(v: &mut Vec<T>, value: T) { //! mir!( //! let _unused; @@ -319,8 +316,7 @@ define!( /// /// # Examples /// - #[cfg_attr(bootstrap, doc = "```rust,ignore")] - #[cfg_attr(not(bootstrap), doc = "```rust")] + /// ```rust /// #![allow(internal_features)] /// #![feature(custom_mir, core_intrinsics)] /// diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs index b6b0c90cb7d..77ccf508502 100644 --- a/library/core/src/iter/adapters/zip.rs +++ b/library/core/src/iter/adapters/zip.rs @@ -95,6 +95,14 @@ where } #[inline] + fn fold<Acc, F>(self, init: Acc, f: F) -> Acc + where + F: FnMut(Acc, Self::Item) -> Acc, + { + ZipImpl::fold(self, init, f) + } + + #[inline] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item where Self: TrustedRandomAccessNoCoerce, @@ -129,6 +137,9 @@ trait ZipImpl<A, B> { where A: DoubleEndedIterator + ExactSizeIterator, B: DoubleEndedIterator + ExactSizeIterator; + fn fold<Acc, F>(self, init: Acc, f: F) -> Acc + where + F: FnMut(Acc, Self::Item) -> Acc; // This has the same safety requirements as `Iterator::__iterator_get_unchecked` unsafe fn get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item where @@ -228,6 +239,14 @@ where { unreachable!("Always specialized"); } + + #[inline] + default fn fold<Acc, F>(self, init: Acc, f: F) -> Acc + where + F: FnMut(Acc, Self::Item) -> Acc, + { + SpecFold::spec_fold(self, init, f) + } } #[doc(hidden)] @@ -251,6 +270,24 @@ where // `Iterator::__iterator_get_unchecked`. unsafe { (self.a.__iterator_get_unchecked(idx), self.b.__iterator_get_unchecked(idx)) } } + + #[inline] + fn fold<Acc, F>(mut self, init: Acc, mut f: F) -> Acc + where + F: FnMut(Acc, Self::Item) -> Acc, + { + let mut accum = init; + let len = ZipImpl::size_hint(&self).0; + for i in 0..len { + // SAFETY: since Self: TrustedRandomAccessNoCoerce we can trust the size-hint to + // calculate the length and then use that to do unchecked iteration. + // fold consumes the iterator so we don't need to fixup any state. + unsafe { + accum = f(accum, self.get_unchecked(i)); + } + } + accum + } } #[doc(hidden)] @@ -590,3 +627,56 @@ unsafe impl<I: Iterator + TrustedRandomAccessNoCoerce> SpecTrustedRandomAccess f unsafe { self.__iterator_get_unchecked(index) } } } + +trait SpecFold: Iterator { + fn spec_fold<B, F>(self, init: B, f: F) -> B + where + Self: Sized, + F: FnMut(B, Self::Item) -> B; +} + +impl<A: Iterator, B: Iterator> SpecFold for Zip<A, B> { + // Adapted from default impl from the Iterator trait + #[inline] + default fn spec_fold<Acc, F>(mut self, init: Acc, mut f: F) -> Acc + where + F: FnMut(Acc, Self::Item) -> Acc, + { + let mut accum = init; + while let Some(x) = ZipImpl::next(&mut self) { + accum = f(accum, x); + } + accum + } +} + +impl<A: TrustedLen, B: TrustedLen> SpecFold for Zip<A, B> { + #[inline] + fn spec_fold<Acc, F>(mut self, init: Acc, mut f: F) -> Acc + where + F: FnMut(Acc, Self::Item) -> Acc, + { + let mut accum = init; + loop { + let (upper, more) = if let Some(upper) = ZipImpl::size_hint(&self).1 { + (upper, false) + } else { + // Per TrustedLen contract a None upper bound means more than usize::MAX items + (usize::MAX, true) + }; + + for _ in 0..upper { + let pair = + // SAFETY: TrustedLen guarantees that at least `upper` many items are available + // therefore we know they can't be None + unsafe { (self.a.next().unwrap_unchecked(), self.b.next().unwrap_unchecked()) }; + accum = f(accum, pair); + } + + if !more { + break; + } + } + accum + } +} diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index ac1fc26a1ef..c7ace58afa8 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -27,13 +27,13 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {} #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented( on( - any(_Self = "core::ops::RangeTo<Idx>", _Self = "std::ops::RangeTo<Idx>"), + _Self = "core::ops::range::RangeTo<Idx>", label = "if you meant to iterate until a value, add a starting value", note = "`..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a \ bounded `Range`: `0..end`" ), on( - any(_Self = "core::ops::RangeToInclusive<Idx>", _Self = "std::ops::RangeToInclusive<Idx>"), + _Self = "core::ops::range::RangeToInclusive<Idx>", label = "if you meant to iterate until a value (including it), add a starting value", note = "`..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant \ to have a bounded `RangeInclusive`: `0..=end`" @@ -44,7 +44,7 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {} ), on(_Self = "&[]", label = "`{Self}` is not an iterator; try calling `.iter()`"), on( - any(_Self = "alloc::vec::Vec<T, A>", _Self = "std::vec::Vec<T, A>"), + _Self = "alloc::vec::Vec<T, A>", label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`" ), on( @@ -52,7 +52,7 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {} label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`" ), on( - any(_Self = "alloc::string::String", _Self = "std::string::String"), + _Self = "alloc::string::String", label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`" ), on( diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 906421327cb..963545a2eb2 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -111,8 +111,6 @@ // // Library features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(no_coverage))] // rust-lang/rust#84605 -#![cfg_attr(not(bootstrap), feature(coverage_attribute))] // rust-lang/rust#84605 #![feature(char_indices_offset)] #![feature(const_align_of_val)] #![feature(const_align_of_val_raw)] @@ -174,6 +172,7 @@ #![feature(const_unsafecell_get_mut)] #![feature(const_waker)] #![feature(core_panic)] +#![feature(coverage_attribute)] #![feature(duration_consts_float)] #![feature(internal_impls_macro)] #![feature(ip)] @@ -197,7 +196,6 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(not(bootstrap), feature(effects))] #![feature(abi_unadjusted)] #![feature(adt_const_params)] #![feature(allow_internal_unsafe)] @@ -221,6 +219,7 @@ #![feature(doc_cfg)] #![feature(doc_cfg_hide)] #![feature(doc_notable_trait)] +#![feature(effects)] #![feature(exhaustive_patterns)] #![feature(extern_types)] #![feature(fundamental)] @@ -414,13 +413,13 @@ pub mod primitive; dead_code, unused_imports, unsafe_op_in_unsafe_fn, - ambiguous_glob_reexports + ambiguous_glob_reexports, + deprecated_in_future )] #[allow(rustdoc::bare_urls)] // FIXME: This annotation should be moved into rust-lang/stdarch after clashing_extern_declarations is // merged. It currently cannot because bootstrap fails as the lint hasn't been defined yet. #[allow(clashing_extern_declarations)] -#[cfg_attr(bootstrap, allow(deprecated_in_future))] #[unstable(feature = "stdsimd", issue = "48556")] mod core_arch; diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 5ed82e26a0a..f1594501d40 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -573,59 +573,59 @@ impl<T: ?Sized> Copy for &T {} #[lang = "sync"] #[rustc_on_unimplemented( on( - any(_Self = "core::cell:OnceCell<T>", _Self = "std::cell::OnceCell<T>"), + _Self = "core::cell::once::OnceCell<T>", note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::OnceLock` instead" ), on( - any(_Self = "core::cell::Cell<u8>", _Self = "std::cell::Cell<u8>"), + _Self = "core::cell::Cell<u8>", note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU8` instead", ), on( - any(_Self = "core::cell::Cell<u16>", _Self = "std::cell::Cell<u16>"), + _Self = "core::cell::Cell<u16>", note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU16` instead", ), on( - any(_Self = "core::cell::Cell<u32>", _Self = "std::cell::Cell<u32>"), + _Self = "core::cell::Cell<u32>", note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU32` instead", ), on( - any(_Self = "core::cell::Cell<u64>", _Self = "std::cell::Cell<u64>"), + _Self = "core::cell::Cell<u64>", note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU64` instead", ), on( - any(_Self = "core::cell::Cell<usize>", _Self = "std::cell::Cell<usize>"), + _Self = "core::cell::Cell<usize>", note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicUsize` instead", ), on( - any(_Self = "core::cell::Cell<i8>", _Self = "std::cell::Cell<i8>"), + _Self = "core::cell::Cell<i8>", note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI8` instead", ), on( - any(_Self = "core::cell::Cell<i16>", _Self = "std::cell::Cell<i16>"), + _Self = "core::cell::Cell<i16>", note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI16` instead", ), on( - any(_Self = "core::cell::Cell<i32>", _Self = "std::cell::Cell<i32>"), + _Self = "core::cell::Cell<i32>", note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead", ), on( - any(_Self = "core::cell::Cell<i64>", _Self = "std::cell::Cell<i64>"), + _Self = "core::cell::Cell<i64>", note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI64` instead", ), on( - any(_Self = "core::cell::Cell<isize>", _Self = "std::cell::Cell<isize>"), + _Self = "core::cell::Cell<isize>", note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicIsize` instead", ), on( - any(_Self = "core::cell::Cell<bool>", _Self = "std::cell::Cell<bool>"), + _Self = "core::cell::Cell<bool>", note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicBool` instead", ), on( - any(_Self = "core::cell::Cell<T>", _Self = "std::cell::Cell<T>"), + _Self = "core::cell::Cell<T>", note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`", ), on( - any(_Self = "core::cell::RefCell<T>", _Self = "std::cell::RefCell<T>"), + _Self = "core::cell::RefCell<T>", note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead", ), message = "`{Self}` cannot be shared between threads safely", diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index d1b1eb7624b..a79a204e2c6 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1051,7 +1051,7 @@ pub const fn copy<T: Copy>(x: &T) -> T { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_stable(feature = "const_transmute_copy", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_transmute_copy", since = "1.74.0")] pub const unsafe fn transmute_copy<Src, Dst>(src: &Src) -> Dst { assert!( size_of::<Src>() >= size_of::<Dst>(), diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index 6a36dfec098..b7eca9b168a 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -1,6 +1,8 @@ use crate::cmp::Ordering; use crate::fmt::{self, Write}; +use crate::iter; use crate::mem::transmute; +use crate::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not}; use super::display_buffer::DisplayBuffer; @@ -410,9 +412,12 @@ impl IpAddr { /// # Examples /// /// ``` - /// #![feature(ip)] /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; /// + /// let localhost_v4 = Ipv4Addr::new(127, 0, 0, 1); + /// + /// assert_eq!(IpAddr::V4(localhost_v4).to_canonical(), localhost_v4); + /// assert_eq!(IpAddr::V6(localhost_v4.to_ipv6_mapped()).to_canonical(), localhost_v4); /// assert_eq!(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)).to_canonical().is_loopback(), true); /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1)).is_loopback(), false); /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1)).to_canonical().is_loopback(), true); @@ -420,11 +425,11 @@ impl IpAddr { #[inline] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "const_ip", issue = "76205")] - #[unstable(feature = "ip", issue = "27709")] + #[stable(feature = "ip_to_canonical", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ip_to_canonical", since = "CURRENT_RUSTC_VERSION")] pub const fn to_canonical(&self) -> IpAddr { match self { - &v4 @ IpAddr::V4(_) => v4, + IpAddr::V4(_) => *self, IpAddr::V6(v6) => v6.to_canonical(), } } @@ -1748,11 +1753,11 @@ impl Ipv6Addr { /// Some(Ipv4Addr::new(192, 10, 2, 255))); /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4_mapped(), None); /// ``` - #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] - #[stable(feature = "ipv6_to_ipv4_mapped", since = "1.63.0")] + #[inline] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[inline] + #[stable(feature = "ipv6_to_ipv4_mapped", since = "1.63.0")] + #[rustc_const_stable(feature = "const_ipv6_to_ipv4_mapped", since = "CURRENT_RUSTC_VERSION")] pub const fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> { match self.octets() { [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, a, b, c, d] => { @@ -1817,11 +1822,11 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1).is_loopback(), false); /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1).to_canonical().is_loopback(), true); /// ``` - #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] - #[unstable(feature = "ip", issue = "27709")] + #[inline] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[inline] + #[stable(feature = "ip_to_canonical", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ip_to_canonical", since = "CURRENT_RUSTC_VERSION")] pub const fn to_canonical(&self) -> IpAddr { if let Some(mapped) = self.to_ipv4_mapped() { return IpAddr::V4(mapped); @@ -2122,3 +2127,132 @@ impl From<[u16; 8]> for IpAddr { IpAddr::V6(Ipv6Addr::from(segments)) } } + +#[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")] +impl Not for Ipv4Addr { + type Output = Ipv4Addr; + + #[inline] + fn not(mut self) -> Ipv4Addr { + for octet in &mut self.octets { + *octet = !*octet; + } + self + } +} + +#[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")] +impl Not for &'_ Ipv4Addr { + type Output = Ipv4Addr; + + #[inline] + fn not(self) -> Ipv4Addr { + !*self + } +} + +#[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")] +impl Not for Ipv6Addr { + type Output = Ipv6Addr; + + #[inline] + fn not(mut self) -> Ipv6Addr { + for octet in &mut self.octets { + *octet = !*octet; + } + self + } +} + +#[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")] +impl Not for &'_ Ipv6Addr { + type Output = Ipv6Addr; + + #[inline] + fn not(self) -> Ipv6Addr { + !*self + } +} + +macro_rules! bitop_impls { + ($( + $(#[$attr:meta])* + impl ($BitOp:ident, $BitOpAssign:ident) for $ty:ty = ($bitop:ident, $bitop_assign:ident); + )*) => { + $( + $(#[$attr])* + impl $BitOpAssign for $ty { + fn $bitop_assign(&mut self, rhs: $ty) { + for (lhs, rhs) in iter::zip(&mut self.octets, rhs.octets) { + lhs.$bitop_assign(rhs); + } + } + } + + $(#[$attr])* + impl $BitOpAssign<&'_ $ty> for $ty { + fn $bitop_assign(&mut self, rhs: &'_ $ty) { + self.$bitop_assign(*rhs); + } + } + + $(#[$attr])* + impl $BitOp for $ty { + type Output = $ty; + + #[inline] + fn $bitop(mut self, rhs: $ty) -> $ty { + self.$bitop_assign(rhs); + self + } + } + + $(#[$attr])* + impl $BitOp<&'_ $ty> for $ty { + type Output = $ty; + + #[inline] + fn $bitop(mut self, rhs: &'_ $ty) -> $ty { + self.$bitop_assign(*rhs); + self + } + } + + $(#[$attr])* + impl $BitOp<$ty> for &'_ $ty { + type Output = $ty; + + #[inline] + fn $bitop(self, rhs: $ty) -> $ty { + let mut lhs = *self; + lhs.$bitop_assign(rhs); + lhs + } + } + + $(#[$attr])* + impl $BitOp<&'_ $ty> for &'_ $ty { + type Output = $ty; + + #[inline] + fn $bitop(self, rhs: &'_ $ty) -> $ty { + let mut lhs = *self; + lhs.$bitop_assign(*rhs); + lhs + } + } + )* + }; +} + +bitop_impls! { + #[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")] + impl (BitAnd, BitAndAssign) for Ipv4Addr = (bitand, bitand_assign); + #[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")] + impl (BitOr, BitOrAssign) for Ipv4Addr = (bitor, bitor_assign); + + #[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")] + impl (BitAnd, BitAndAssign) for Ipv6Addr = (bitand, bitand_assign); + #[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")] + impl (BitOr, BitOrAssign) for Ipv6Addr = (bitor, bitor_assign); +} diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 4232319fecb..8b127132c1c 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -47,7 +47,7 @@ mod nonzero; mod saturating; mod wrapping; -#[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "saturating_int_impl", since = "1.74.0")] pub use saturating::Saturating; #[stable(feature = "rust1", since = "1.0.0")] pub use wrapping::Wrapping; diff --git a/library/core/src/num/saturating.rs b/library/core/src/num/saturating.rs index 5757e7498ad..d040539ebe5 100644 --- a/library/core/src/num/saturating.rs +++ b/library/core/src/num/saturating.rs @@ -31,50 +31,48 @@ use crate::ops::{Sub, SubAssign}; /// /// assert_eq!(u32::MAX, (max + one).0); /// ``` -#[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "saturating_int_impl", since = "1.74.0")] #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)] #[repr(transparent)] #[rustc_diagnostic_item = "Saturating"] -pub struct Saturating<T>( - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] pub T, -); +pub struct Saturating<T>(#[stable(feature = "saturating_int_impl", since = "1.74.0")] pub T); -#[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "saturating_int_impl", since = "1.74.0")] impl<T: fmt::Debug> fmt::Debug for Saturating<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } -#[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "saturating_int_impl", since = "1.74.0")] impl<T: fmt::Display> fmt::Display for Saturating<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } -#[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "saturating_int_impl", since = "1.74.0")] impl<T: fmt::Binary> fmt::Binary for Saturating<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } -#[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "saturating_int_impl", since = "1.74.0")] impl<T: fmt::Octal> fmt::Octal for Saturating<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } -#[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "saturating_int_impl", since = "1.74.0")] impl<T: fmt::LowerHex> fmt::LowerHex for Saturating<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } -#[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "saturating_int_impl", since = "1.74.0")] impl<T: fmt::UpperHex> fmt::UpperHex for Saturating<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) @@ -210,7 +208,7 @@ impl<T: fmt::UpperHex> fmt::UpperHex for Saturating<T> { // FIXME(30524): impl Op<T> for Saturating<T>, impl OpAssign<T> for Saturating<T> macro_rules! saturating_impl { ($($t:ty)*) => ($( - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl Add for Saturating<$t> { type Output = Saturating<$t>; @@ -220,9 +218,9 @@ macro_rules! saturating_impl { } } forward_ref_binop! { impl Add, add for Saturating<$t>, Saturating<$t>, - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] } + #[stable(feature = "saturating_int_impl", since = "1.74.0")] } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl AddAssign for Saturating<$t> { #[inline] fn add_assign(&mut self, other: Saturating<$t>) { @@ -231,7 +229,7 @@ macro_rules! saturating_impl { } forward_ref_op_assign! { impl AddAssign, add_assign for Saturating<$t>, Saturating<$t> } - #[stable(feature = "saturating_int_assign_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_assign_impl", since = "1.74.0")] impl AddAssign<$t> for Saturating<$t> { #[inline] fn add_assign(&mut self, other: $t) { @@ -240,7 +238,7 @@ macro_rules! saturating_impl { } forward_ref_op_assign! { impl AddAssign, add_assign for Saturating<$t>, $t } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl Sub for Saturating<$t> { type Output = Saturating<$t>; @@ -250,9 +248,9 @@ macro_rules! saturating_impl { } } forward_ref_binop! { impl Sub, sub for Saturating<$t>, Saturating<$t>, - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] } + #[stable(feature = "saturating_int_impl", since = "1.74.0")] } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl SubAssign for Saturating<$t> { #[inline] fn sub_assign(&mut self, other: Saturating<$t>) { @@ -261,7 +259,7 @@ macro_rules! saturating_impl { } forward_ref_op_assign! { impl SubAssign, sub_assign for Saturating<$t>, Saturating<$t> } - #[stable(feature = "saturating_int_assign_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_assign_impl", since = "1.74.0")] impl SubAssign<$t> for Saturating<$t> { #[inline] fn sub_assign(&mut self, other: $t) { @@ -270,7 +268,7 @@ macro_rules! saturating_impl { } forward_ref_op_assign! { impl SubAssign, sub_assign for Saturating<$t>, $t } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl Mul for Saturating<$t> { type Output = Saturating<$t>; @@ -280,9 +278,9 @@ macro_rules! saturating_impl { } } forward_ref_binop! { impl Mul, mul for Saturating<$t>, Saturating<$t>, - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] } + #[stable(feature = "saturating_int_impl", since = "1.74.0")] } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl MulAssign for Saturating<$t> { #[inline] fn mul_assign(&mut self, other: Saturating<$t>) { @@ -291,7 +289,7 @@ macro_rules! saturating_impl { } forward_ref_op_assign! { impl MulAssign, mul_assign for Saturating<$t>, Saturating<$t> } - #[stable(feature = "saturating_int_assign_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_assign_impl", since = "1.74.0")] impl MulAssign<$t> for Saturating<$t> { #[inline] fn mul_assign(&mut self, other: $t) { @@ -317,7 +315,7 @@ macro_rules! saturating_impl { /// #[doc = concat!("let _ = Saturating(0", stringify!($t), ") / Saturating(0);")] /// ``` - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl Div for Saturating<$t> { type Output = Saturating<$t>; @@ -327,10 +325,10 @@ macro_rules! saturating_impl { } } forward_ref_binop! { impl Div, div for Saturating<$t>, Saturating<$t>, - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] } + #[stable(feature = "saturating_int_impl", since = "1.74.0")] } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl DivAssign for Saturating<$t> { #[inline] fn div_assign(&mut self, other: Saturating<$t>) { @@ -339,7 +337,7 @@ macro_rules! saturating_impl { } forward_ref_op_assign! { impl DivAssign, div_assign for Saturating<$t>, Saturating<$t> } - #[stable(feature = "saturating_int_assign_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_assign_impl", since = "1.74.0")] impl DivAssign<$t> for Saturating<$t> { #[inline] fn div_assign(&mut self, other: $t) { @@ -348,7 +346,7 @@ macro_rules! saturating_impl { } forward_ref_op_assign! { impl DivAssign, div_assign for Saturating<$t>, $t } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl Rem for Saturating<$t> { type Output = Saturating<$t>; @@ -358,9 +356,9 @@ macro_rules! saturating_impl { } } forward_ref_binop! { impl Rem, rem for Saturating<$t>, Saturating<$t>, - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] } + #[stable(feature = "saturating_int_impl", since = "1.74.0")] } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl RemAssign for Saturating<$t> { #[inline] fn rem_assign(&mut self, other: Saturating<$t>) { @@ -369,7 +367,7 @@ macro_rules! saturating_impl { } forward_ref_op_assign! { impl RemAssign, rem_assign for Saturating<$t>, Saturating<$t> } - #[stable(feature = "saturating_int_assign_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_assign_impl", since = "1.74.0")] impl RemAssign<$t> for Saturating<$t> { #[inline] fn rem_assign(&mut self, other: $t) { @@ -378,7 +376,7 @@ macro_rules! saturating_impl { } forward_ref_op_assign! { impl RemAssign, rem_assign for Saturating<$t>, $t } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl Not for Saturating<$t> { type Output = Saturating<$t>; @@ -388,9 +386,9 @@ macro_rules! saturating_impl { } } forward_ref_unop! { impl Not, not for Saturating<$t>, - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] } + #[stable(feature = "saturating_int_impl", since = "1.74.0")] } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl BitXor for Saturating<$t> { type Output = Saturating<$t>; @@ -400,9 +398,9 @@ macro_rules! saturating_impl { } } forward_ref_binop! { impl BitXor, bitxor for Saturating<$t>, Saturating<$t>, - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] } + #[stable(feature = "saturating_int_impl", since = "1.74.0")] } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl BitXorAssign for Saturating<$t> { #[inline] fn bitxor_assign(&mut self, other: Saturating<$t>) { @@ -411,7 +409,7 @@ macro_rules! saturating_impl { } forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Saturating<$t>, Saturating<$t> } - #[stable(feature = "saturating_int_assign_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_assign_impl", since = "1.74.0")] impl BitXorAssign<$t> for Saturating<$t> { #[inline] fn bitxor_assign(&mut self, other: $t) { @@ -420,7 +418,7 @@ macro_rules! saturating_impl { } forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Saturating<$t>, $t } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl BitOr for Saturating<$t> { type Output = Saturating<$t>; @@ -430,9 +428,9 @@ macro_rules! saturating_impl { } } forward_ref_binop! { impl BitOr, bitor for Saturating<$t>, Saturating<$t>, - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] } + #[stable(feature = "saturating_int_impl", since = "1.74.0")] } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl BitOrAssign for Saturating<$t> { #[inline] fn bitor_assign(&mut self, other: Saturating<$t>) { @@ -441,7 +439,7 @@ macro_rules! saturating_impl { } forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Saturating<$t>, Saturating<$t> } - #[stable(feature = "saturating_int_assign_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_assign_impl", since = "1.74.0")] impl BitOrAssign<$t> for Saturating<$t> { #[inline] fn bitor_assign(&mut self, other: $t) { @@ -450,7 +448,7 @@ macro_rules! saturating_impl { } forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Saturating<$t>, $t } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl BitAnd for Saturating<$t> { type Output = Saturating<$t>; @@ -460,9 +458,9 @@ macro_rules! saturating_impl { } } forward_ref_binop! { impl BitAnd, bitand for Saturating<$t>, Saturating<$t>, - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] } + #[stable(feature = "saturating_int_impl", since = "1.74.0")] } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl BitAndAssign for Saturating<$t> { #[inline] fn bitand_assign(&mut self, other: Saturating<$t>) { @@ -471,7 +469,7 @@ macro_rules! saturating_impl { } forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Saturating<$t>, Saturating<$t> } - #[stable(feature = "saturating_int_assign_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_assign_impl", since = "1.74.0")] impl BitAndAssign<$t> for Saturating<$t> { #[inline] fn bitand_assign(&mut self, other: $t) { @@ -499,7 +497,7 @@ macro_rules! saturating_int_impl { /// #[doc = concat!("assert_eq!(<Saturating<", stringify!($t), ">>::MIN, Saturating(", stringify!($t), "::MIN));")] /// ``` - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] pub const MIN: Self = Self(<$t>::MIN); /// Returns the largest value that can be represented by this integer type. @@ -513,7 +511,7 @@ macro_rules! saturating_int_impl { /// #[doc = concat!("assert_eq!(<Saturating<", stringify!($t), ">>::MAX, Saturating(", stringify!($t), "::MAX));")] /// ``` - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] pub const MAX: Self = Self(<$t>::MAX); /// Returns the size of this integer type in bits. @@ -527,7 +525,7 @@ macro_rules! saturating_int_impl { /// #[doc = concat!("assert_eq!(<Saturating<", stringify!($t), ">>::BITS, ", stringify!($t), "::BITS);")] /// ``` - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] pub const BITS: u32 = <$t>::BITS; /// Returns the number of ones in the binary representation of `self`. @@ -548,8 +546,8 @@ macro_rules! saturating_int_impl { #[doc(alias = "popcnt")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] pub const fn count_ones(self) -> u32 { self.0.count_ones() } @@ -568,8 +566,8 @@ macro_rules! saturating_int_impl { #[inline] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] pub const fn count_zeros(self) -> u32 { self.0.count_zeros() } @@ -590,8 +588,8 @@ macro_rules! saturating_int_impl { #[inline] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] pub const fn trailing_zeros(self) -> u32 { self.0.trailing_zeros() } @@ -618,8 +616,8 @@ macro_rules! saturating_int_impl { #[inline] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] pub const fn rotate_left(self, n: u32) -> Self { Saturating(self.0.rotate_left(n)) } @@ -646,8 +644,8 @@ macro_rules! saturating_int_impl { #[inline] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] pub const fn rotate_right(self, n: u32) -> Self { Saturating(self.0.rotate_right(n)) } @@ -672,8 +670,8 @@ macro_rules! saturating_int_impl { #[inline] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] pub const fn swap_bytes(self) -> Self { Saturating(self.0.swap_bytes()) } @@ -699,8 +697,8 @@ macro_rules! saturating_int_impl { /// assert_eq!(m, Saturating(-22016)); /// ``` #[inline] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn reverse_bits(self) -> Self { @@ -729,8 +727,8 @@ macro_rules! saturating_int_impl { /// ``` #[inline] #[must_use] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] pub const fn from_be(x: Self) -> Self { Saturating(<$t>::from_be(x.0)) } @@ -757,8 +755,8 @@ macro_rules! saturating_int_impl { /// ``` #[inline] #[must_use] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] pub const fn from_le(x: Self) -> Self { Saturating(<$t>::from_le(x.0)) } @@ -784,8 +782,8 @@ macro_rules! saturating_int_impl { /// } /// ``` #[inline] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn to_be(self) -> Self { @@ -813,8 +811,8 @@ macro_rules! saturating_int_impl { /// } /// ``` #[inline] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn to_le(self) -> Self { @@ -842,8 +840,8 @@ macro_rules! saturating_int_impl { /// assert_eq!(Saturating(3i8).pow(6), Saturating(127)); /// ``` #[inline] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn pow(self, exp: u32) -> Self { @@ -872,8 +870,8 @@ macro_rules! saturating_int_impl_signed { /// assert_eq!(n.leading_zeros(), 3); /// ``` #[inline] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn leading_zeros(self) -> u32 { @@ -897,8 +895,8 @@ macro_rules! saturating_int_impl_signed { #[doc = concat!("assert_eq!(Saturating(", stringify!($t), "::MIN).abs(), Saturating(", stringify!($t), "::MAX));")] /// ``` #[inline] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn abs(self) -> Saturating<$t> { @@ -923,8 +921,8 @@ macro_rules! saturating_int_impl_signed { #[doc = concat!("assert_eq!(Saturating(-10", stringify!($t), ").signum(), Saturating(-1));")] /// ``` #[inline] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn signum(self) -> Saturating<$t> { @@ -946,8 +944,8 @@ macro_rules! saturating_int_impl_signed { /// ``` #[must_use] #[inline] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] pub const fn is_positive(self) -> bool { self.0.is_positive() } @@ -967,14 +965,14 @@ macro_rules! saturating_int_impl_signed { /// ``` #[must_use] #[inline] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] pub const fn is_negative(self) -> bool { self.0.is_negative() } } - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] impl Neg for Saturating<$t> { type Output = Self; #[inline] @@ -983,7 +981,7 @@ macro_rules! saturating_int_impl_signed { } } forward_ref_unop! { impl Neg, neg for Saturating<$t>, - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] } + #[stable(feature = "saturating_int_impl", since = "1.74.0")] } )*) } @@ -1006,8 +1004,8 @@ macro_rules! saturating_int_impl_unsigned { /// assert_eq!(n.leading_zeros(), 2); /// ``` #[inline] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn leading_zeros(self) -> u32 { @@ -1028,8 +1026,8 @@ macro_rules! saturating_int_impl_unsigned { /// ``` #[must_use] #[inline] - #[rustc_const_stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")] + #[stable(feature = "saturating_int_impl", since = "1.74.0")] pub const fn is_power_of_two(self) -> bool { self.0.is_power_of_two() } diff --git a/library/core/src/ops/index.rs b/library/core/src/ops/index.rs index f4649be54d5..6ceee463729 100644 --- a/library/core/src/ops/index.rs +++ b/library/core/src/ops/index.rs @@ -153,7 +153,7 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" ), on( - any(_Self = "alloc::string::String", _Self = "std::string::String"), + _Self = "alloc::string::String", note = "you can use `.chars().nth()` or `.bytes().nth()` see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" ), diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs index 17625daccbc..3f8c8efd416 100644 --- a/library/core/src/ops/try_trait.rs +++ b/library/core/src/ops/try_trait.rs @@ -226,14 +226,8 @@ pub trait Try: FromResidual { on( all( from_desugaring = "QuestionMark", - any( - _Self = "core::result::Result<T, E>", - _Self = "std::result::Result<T, E>", - ), - any( - R = "core::option::Option<core::convert::Infallible>", - R = "std::option::Option<std::convert::Infallible>", - ) + _Self = "core::result::Result<T, E>", + R = "core::option::Option<core::convert::Infallible>", ), message = "the `?` operator can only be used on `Result`s, not `Option`s, \ in {ItemContext} that returns `Result`", @@ -243,10 +237,7 @@ pub trait Try: FromResidual { on( all( from_desugaring = "QuestionMark", - any( - _Self = "core::result::Result<T, E>", - _Self = "std::result::Result<T, E>", - ) + _Self = "core::result::Result<T, E>", ), // There's a special error message in the trait selection code for // `From` in `?`, so this is not shown for result-in-result errors, @@ -259,14 +250,8 @@ pub trait Try: FromResidual { on( all( from_desugaring = "QuestionMark", - any( - _Self = "core::option::Option<T>", - _Self = "std::option::Option<T>", - ), - any( - R = "core::result::Result<T, E>", - R = "std::result::Result<T, E>", - ) + _Self = "core::option::Option<T>", + R = "core::result::Result<T, E>", ), message = "the `?` operator can only be used on `Option`s, not `Result`s, \ in {ItemContext} that returns `Option`", @@ -276,10 +261,7 @@ pub trait Try: FromResidual { on( all( from_desugaring = "QuestionMark", - any( - _Self = "core::option::Option<T>", - _Self = "std::option::Option<T>", - ) + _Self = "core::option::Option<T>", ), // `Option`-in-`Option` always works, as there's only one possible // residual, so this can also be phrased strongly. @@ -291,14 +273,8 @@ pub trait Try: FromResidual { on( all( from_desugaring = "QuestionMark", - any( - _Self = "core::ops::ControlFlow<B, C>", - _Self = "std::ops::ControlFlow<B, C>", - ), - any( - R = "core::ops::ControlFlow<B, C>", - R = "std::ops::ControlFlow<B, C>", - ) + _Self = "core::ops::control_flow::ControlFlow<B, C>", + R = "core::ops::control_flow::ControlFlow<B, C>", ), message = "the `?` operator in {ItemContext} that returns `ControlFlow<B, _>` \ can only be used on other `ControlFlow<B, _>`s (with the same Break type)", @@ -309,10 +285,7 @@ pub trait Try: FromResidual { on( all( from_desugaring = "QuestionMark", - any( - _Self = "core::ops::ControlFlow<B, C>", - _Self = "std::ops::ControlFlow<B, C>", - ) + _Self = "core::ops::control_flow::ControlFlow<B, C>", // `R` is not a `ControlFlow`, as that case was matched previously ), message = "the `?` operator can only be used on `ControlFlow`s \ diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 1a32cf92ffb..39a5e8d9fe2 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -229,7 +229,6 @@ fn panic_cannot_unwind() -> ! { /// pass to `panic_nounwind`. /// This function is called directly by the codegen backend, and must not have /// any extra arguments (including those synthesized by track_caller). -#[cfg(not(bootstrap))] #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[lang = "panic_in_cleanup"] // needed by codegen for panic in nounwind function diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 9af8f1228f0..a3e4f0fb90a 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -842,7 +842,7 @@ impl<T: ?Sized> *const T { where T: Sized, { - match intrinsics::ptr_guaranteed_cmp(self as _, other as _) { + match intrinsics::ptr_guaranteed_cmp(self, other) { 2 => None, other => Some(other == 1), } diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 5039ff53d03..84b179df8c1 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -699,7 +699,7 @@ where #[inline(always)] #[must_use] #[unstable(feature = "ptr_from_ref", issue = "106116")] -#[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] +#[rustc_never_returns_null_ptr] #[rustc_diagnostic_item = "ptr_from_ref"] pub const fn from_ref<T: ?Sized>(r: &T) -> *const T { r @@ -712,7 +712,7 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T { #[inline(always)] #[must_use] #[unstable(feature = "ptr_from_ref", issue = "106116")] -#[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] +#[rustc_never_returns_null_ptr] pub const fn from_mut<T: ?Sized>(r: &mut T) -> *mut T { r } diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 5f5a10bbdf3..ae673b7799f 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -339,7 +339,7 @@ impl<T: ?Sized> NonNull<T> { /// ``` #[stable(feature = "nonnull", since = "1.25.0")] #[rustc_const_stable(feature = "const_nonnull_as_ptr", since = "1.32.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] #[must_use] #[inline(always)] pub const fn as_ptr(self) -> *mut T { @@ -599,7 +599,7 @@ impl<T> NonNull<[T]> { #[must_use] #[unstable(feature = "slice_ptr_get", issue = "74265")] #[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] pub const fn as_mut_ptr(self) -> *mut T { self.as_non_null_ptr().as_ptr() } diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 5dc53caba0d..4cfccd2e3ce 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -10,7 +10,7 @@ use crate::ops; impl [u8] { /// Checks if all bytes in this slice are within the ASCII range. #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_slice_is_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_slice_is_ascii", since = "1.74.0")] #[must_use] #[inline] pub const fn is_ascii(&self) -> bool { diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index d313e8e012f..1da3a87e117 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -152,10 +152,7 @@ mod private_slice_index { #[rustc_on_unimplemented( on(T = "str", label = "string indices are ranges of `usize`",), on( - all( - any(T = "str", T = "&str", T = "alloc::string::String", T = "std::string::String"), - _Self = "{integer}" - ), + all(any(T = "str", T = "&str", T = "alloc::string::String"), _Self = "{integer}"), note = "you can use `.chars().nth()` or `.bytes().nth()`\n\ for more information, see chapter 8 in The Book: \ <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index f58c91a2484..45080eda2ce 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -730,7 +730,7 @@ impl<T> [T] { /// [`as_mut_ptr`]: slice::as_mut_ptr #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_as_ptr", since = "1.32.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] #[inline(always)] #[must_use] pub const fn as_ptr(&self) -> *const T { @@ -761,7 +761,7 @@ impl<T> [T] { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[rustc_allow_const_fn_unstable(const_mut_refs)] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] #[inline(always)] #[must_use] pub const fn as_mut_ptr(&mut self) -> *mut T { diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 899d572f0e3..6aba9b64509 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -386,7 +386,7 @@ impl str { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rustc_str_as_ptr", since = "1.32.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] #[must_use] #[inline(always)] pub const fn as_ptr(&self) -> *const u8 { @@ -402,7 +402,7 @@ impl str { /// It is your responsibility to make sure that the string slice only gets /// modified in a way that it remains valid UTF-8. #[stable(feature = "str_as_mut_ptr", since = "1.36.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] #[must_use] #[inline(always)] pub fn as_mut_ptr(&mut self) -> *mut u8 { @@ -2324,7 +2324,7 @@ impl str { /// assert!(!non_ascii.is_ascii()); /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_slice_is_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_slice_is_ascii", since = "1.74.0")] #[must_use] #[inline] pub const fn is_ascii(&self) -> bool { diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 1271dcc78e0..de41bd1a116 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -1026,7 +1026,7 @@ impl AtomicBool { #[inline] #[stable(feature = "atomic_as_ptr", since = "1.70.0")] #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] pub const fn as_ptr(&self) -> *mut bool { self.v.get().cast() } @@ -1972,7 +1972,7 @@ impl<T> AtomicPtr<T> { #[inline] #[stable(feature = "atomic_as_ptr", since = "1.70.0")] #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] pub const fn as_ptr(&self) -> *mut *mut T { self.p.get() } @@ -2922,7 +2922,7 @@ macro_rules! atomic_int { #[inline] #[stable(feature = "atomic_as_ptr", since = "1.70.0")] #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")] - #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] + #[rustc_never_returns_null_ptr] pub const fn as_ptr(&self) -> *mut $int_type { self.v.get() } diff --git a/library/core/tests/iter/adapters/zip.rs b/library/core/tests/iter/adapters/zip.rs index 585cfbb90e4..c3508be8598 100644 --- a/library/core/tests/iter/adapters/zip.rs +++ b/library/core/tests/iter/adapters/zip.rs @@ -184,7 +184,11 @@ fn test_zip_nested_sideffectful() { let it = xs.iter_mut().map(|x| *x = 1).enumerate().zip(&ys); it.count(); } - assert_eq!(&xs, &[1, 1, 1, 1, 1, 0]); + let length_aware = &xs == &[1, 1, 1, 1, 0, 0]; + let probe_first = &xs == &[1, 1, 1, 1, 1, 0]; + + // either implementation is valid according to zip documentation + assert!(length_aware || probe_first); } #[test] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 965132bdedb..3b57f864e20 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } -libc = { version = "0.2.148", default-features = false, features = ['rustc-dep-of-std'], public = true } +libc = { version = "0.2.149", default-features = false, features = ['rustc-dep-of-std'], public = true } compiler_builtins = { version = "0.1.100" } profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 93b9bf0cc20..fa9d48771b6 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -179,7 +179,7 @@ impl OsString { /// /// [conversions]: super#conversions #[inline] - #[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "os_str_bytes", since = "1.74.0")] pub unsafe fn from_encoded_bytes_unchecked(bytes: Vec<u8>) -> Self { OsString { inner: Buf::from_encoded_bytes_unchecked(bytes) } } @@ -217,7 +217,7 @@ impl OsString { /// /// [`std::ffi`]: crate::ffi #[inline] - #[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "os_str_bytes", since = "1.74.0")] pub fn into_encoded_bytes(self) -> Vec<u8> { self.inner.into_encoded_bytes() } @@ -768,7 +768,7 @@ impl OsStr { /// /// [conversions]: super#conversions #[inline] - #[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "os_str_bytes", since = "1.74.0")] pub unsafe fn from_encoded_bytes_unchecked(bytes: &[u8]) -> &Self { Self::from_inner(Slice::from_encoded_bytes_unchecked(bytes)) } @@ -958,7 +958,7 @@ impl OsStr { /// /// [`std::ffi`]: crate::ffi #[inline] - #[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "os_str_bytes", since = "1.74.0")] pub fn as_encoded_bytes(&self) -> &[u8] { self.inner.as_encoded_bytes() } diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index d74f0f00e46..f0c4be2327c 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1707,3 +1707,38 @@ fn test_file_times() { assert_eq!(metadata.created().unwrap(), created); } } + +#[test] +#[cfg(windows)] +fn windows_unix_socket_exists() { + use crate::sys::{c, net}; + use crate::{mem, ptr}; + + let tmp = tmpdir(); + let socket_path = tmp.join("socket"); + + // std doesn't current support Unix sockets on Windows so manually create one here. + net::init(); + unsafe { + let socket = c::WSASocketW( + c::AF_UNIX as i32, + c::SOCK_STREAM, + 0, + ptr::null_mut(), + 0, + c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT, + ); + assert_ne!(socket, c::INVALID_SOCKET); + let mut addr = c::SOCKADDR_UN { sun_family: c::AF_UNIX, sun_path: mem::zeroed() }; + let bytes = socket_path.as_os_str().as_encoded_bytes(); + addr.sun_path[..bytes.len()].copy_from_slice(bytes); + let len = mem::size_of_val(&addr) as i32; + let result = c::bind(socket, ptr::addr_of!(addr).cast::<c::SOCKADDR>(), len); + c::closesocket(socket); + assert_eq!(result, 0); + } + // Make sure all ways of testing a file exist work for a Unix socket. + assert_eq!(socket_path.exists(), true); + assert_eq!(socket_path.try_exists().unwrap(), true); + assert_eq!(socket_path.metadata().is_ok(), true); +} diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 5966416e32a..b63091deac2 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -536,7 +536,7 @@ impl Error { /// // errors can also be created from other errors /// let custom_error2 = Error::other(custom_error); /// ``` - #[stable(feature = "io_error_other", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_other", since = "1.74.0")] pub fn other<E>(error: E) -> Error where E: Into<Box<dyn error::Error + Send + Sync>>, diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs index a7428776d8f..f438325560f 100644 --- a/library/std/src/io/impls.rs +++ b/library/std/src/io/impls.rs @@ -475,6 +475,24 @@ impl<A: Allocator> Read for VecDeque<u8, A> { } } +/// BufRead is implemented for `VecDeque<u8>` by reading bytes from the front of the `VecDeque`. +#[stable(feature = "vecdeque_buf_read", since = "CURRENT_RUSTC_VERSION")] +impl<A: Allocator> BufRead for VecDeque<u8, A> { + /// Returns the contents of the "front" slice as returned by + /// [`as_slices`][`VecDeque::as_slices`]. If the contained byte slices of the `VecDeque` are + /// discontiguous, multiple calls to `fill_buf` will be needed to read the entire content. + #[inline] + fn fill_buf(&mut self) -> io::Result<&[u8]> { + let (front, _) = self.as_slices(); + Ok(front) + } + + #[inline] + fn consume(&mut self, amt: usize) { + self.drain(..amt); + } +} + /// Write is implemented for `VecDeque<u8>` by appending to the `VecDeque`, growing it as needed. #[stable(feature = "vecdeque_read_write", since = "1.63.0")] impl<A: Allocator> Write for VecDeque<u8, A> { diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index e6431abcf82..c0a72948112 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -2777,6 +2777,7 @@ pub struct Bytes<R> { impl<R: Read> Iterator for Bytes<R> { type Item = Result<u8>; + #[inline] fn next(&mut self) -> Option<Result<u8>> { let mut byte = 0; loop { @@ -2789,6 +2790,7 @@ impl<R: Read> Iterator for Bytes<R> { } } + #[inline] fn size_hint(&self) -> (usize, Option<usize>) { SizeHint::size_hint(&self.inner) } diff --git a/library/std/src/num.rs b/library/std/src/num.rs index 9e021b23fec..3cd5fa458e0 100644 --- a/library/std/src/num.rs +++ b/library/std/src/num.rs @@ -12,7 +12,7 @@ mod tests; #[cfg(test)] mod benches; -#[stable(feature = "saturating_int_impl", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "saturating_int_impl", since = "1.74.0")] pub use core::num::Saturating; #[stable(feature = "rust1", since = "1.0.0")] pub use core::num::Wrapping; diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 5d9f7430ca2..ac551030492 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -438,7 +438,7 @@ impl From<crate::process::ChildStdin> for OwnedFd { /// /// The provided file descriptor must point to a pipe /// with the `CLOEXEC` flag set. -#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "child_stream_from_fd", since = "1.74.0")] impl From<OwnedFd> for process::ChildStdin { #[inline] fn from(fd: OwnedFd) -> process::ChildStdin { @@ -468,7 +468,7 @@ impl From<crate::process::ChildStdout> for OwnedFd { /// /// The provided file descriptor must point to a pipe /// with the `CLOEXEC` flag set. -#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "child_stream_from_fd", since = "1.74.0")] impl From<OwnedFd> for process::ChildStdout { #[inline] fn from(fd: OwnedFd) -> process::ChildStdout { @@ -498,7 +498,7 @@ impl From<crate::process::ChildStderr> for OwnedFd { /// /// The provided file descriptor must point to a pipe /// with the `CLOEXEC` flag set. -#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "child_stream_from_fd", since = "1.74.0")] impl From<OwnedFd> for process::ChildStderr { #[inline] fn from(fd: OwnedFd) -> process::ChildStderr { diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index 94173825c4a..d00e79476f3 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -110,7 +110,7 @@ impl IntoRawHandle for process::ChildStderr { /// /// The provided handle must be asynchronous, as reading and /// writing from and to it is implemented using asynchronous APIs. -#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "child_stream_from_fd", since = "1.74.0")] impl From<OwnedHandle> for process::ChildStdin { fn from(handle: OwnedHandle) -> process::ChildStdin { let handle = sys::handle::Handle::from_inner(handle); @@ -123,7 +123,7 @@ impl From<OwnedHandle> for process::ChildStdin { /// /// The provided handle must be asynchronous, as reading and /// writing from and to it is implemented using asynchronous APIs. -#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "child_stream_from_fd", since = "1.74.0")] impl From<OwnedHandle> for process::ChildStdout { fn from(handle: OwnedHandle) -> process::ChildStdout { let handle = sys::handle::Handle::from_inner(handle); @@ -136,7 +136,7 @@ impl From<OwnedHandle> for process::ChildStdout { /// /// The provided handle must be asynchronous, as reading and /// writing from and to it is implemented using asynchronous APIs. -#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "child_stream_from_fd", since = "1.74.0")] impl From<OwnedHandle> for process::ChildStderr { fn from(handle: OwnedHandle) -> process::ChildStderr { let handle = sys::handle::Handle::from_inner(handle); diff --git a/library/std/src/process.rs b/library/std/src/process.rs index e148635f581..ad29eeb6a0b 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -1500,7 +1500,7 @@ impl From<fs::File> for Stdio { } } -#[stable(feature = "stdio_from_stdio", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "stdio_from_stdio", since = "1.74.0")] impl From<io::Stdout> for Stdio { /// Redirect command stdout/stderr to our stdout /// @@ -1531,7 +1531,7 @@ impl From<io::Stdout> for Stdio { } } -#[stable(feature = "stdio_from_stdio", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "stdio_from_stdio", since = "1.74.0")] impl From<io::Stderr> for Stdio { /// Redirect command stdout/stderr to our stderr /// @@ -1594,7 +1594,7 @@ impl From<io::Stderr> for Stdio { pub struct ExitStatus(imp::ExitStatus); /// The default value is one which indicates successful completion. -#[stable(feature = "process-exitcode-default", since = "1.73.0")] +#[stable(feature = "process_exitstatus_default", since = "1.73.0")] impl Default for ExitStatus { fn default() -> Self { // Ideally this would be done by ExitCode::default().into() but that is complicated. @@ -1960,6 +1960,14 @@ impl ExitCode { } } +/// The default value is [`ExitCode::SUCCESS`] +#[stable(feature = "process_exitcode_default", since = "CURRENT_RUSTC_VERSION")] +impl Default for ExitCode { + fn default() -> Self { + ExitCode::SUCCESS + } +} + #[stable(feature = "process_exitcode", since = "1.61.0")] impl From<u8> for ExitCode { /// Construct an `ExitCode` from an arbitrary u8 value. diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index e2b7b893cb5..f4963090795 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -126,11 +126,48 @@ impl<T> OnceLock<T> { #[inline] #[stable(feature = "once_cell", since = "1.70.0")] pub fn set(&self, value: T) -> Result<(), T> { + match self.try_insert(value) { + Ok(_) => Ok(()), + Err((_, value)) => Err(value), + } + } + + /// Sets the contents of this cell to `value` if the cell was empty, then + /// returns a reference to it. + /// + /// May block if another thread is currently attempting to initialize the cell. The cell is + /// guaranteed to contain a value when set returns, though not necessarily the one provided. + /// + /// Returns `Ok(&value)` if the cell was empty and `Err(¤t_value, value)` if it was full. + /// + /// # Examples + /// + /// ``` + /// #![feature(once_cell_try_insert)] + /// + /// use std::sync::OnceLock; + /// + /// static CELL: OnceLock<i32> = OnceLock::new(); + /// + /// fn main() { + /// assert!(CELL.get().is_none()); + /// + /// std::thread::spawn(|| { + /// assert_eq!(CELL.try_insert(92), Ok(&92)); + /// }).join().unwrap(); + /// + /// assert_eq!(CELL.try_insert(62), Err((&92, 62))); + /// assert_eq!(CELL.get(), Some(&92)); + /// } + /// ``` + #[inline] + #[unstable(feature = "once_cell_try_insert", issue = "116693")] + pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> { let mut value = Some(value); - self.get_or_init(|| value.take().unwrap()); + let res = self.get_or_init(|| value.take().unwrap()); match value { - None => Ok(()), - Some(value) => Err(value), + None => Ok(res), + Some(value) => Err((res, value)), } } diff --git a/library/std/src/sys/uefi/args.rs b/library/std/src/sys/uefi/args.rs new file mode 100644 index 00000000000..4ff7be748e9 --- /dev/null +++ b/library/std/src/sys/uefi/args.rs @@ -0,0 +1,158 @@ +use r_efi::protocols::loaded_image; + +use crate::env::current_exe; +use crate::ffi::OsString; +use crate::fmt; +use crate::iter::Iterator; +use crate::mem::size_of; +use crate::sys::uefi::helpers; +use crate::vec; + +pub struct Args { + parsed_args_list: vec::IntoIter<OsString>, +} + +pub fn args() -> Args { + let lazy_current_exe = || Vec::from([current_exe().map(Into::into).unwrap_or_default()]); + + // Each loaded image has an image handle that supports `EFI_LOADED_IMAGE_PROTOCOL`. Thus, this + // will never fail. + let protocol = + helpers::image_handle_protocol::<loaded_image::Protocol>(loaded_image::PROTOCOL_GUID) + .unwrap(); + + let lp_size = unsafe { (*protocol.as_ptr()).load_options_size } as usize; + // Break if we are sure that it cannot be UTF-16 + if lp_size < size_of::<u16>() || lp_size % size_of::<u16>() != 0 { + return Args { parsed_args_list: lazy_current_exe().into_iter() }; + } + let lp_size = lp_size / size_of::<u16>(); + + let lp_cmd_line = unsafe { (*protocol.as_ptr()).load_options as *const u16 }; + if !lp_cmd_line.is_aligned() { + return Args { parsed_args_list: lazy_current_exe().into_iter() }; + } + let lp_cmd_line = unsafe { crate::slice::from_raw_parts(lp_cmd_line, lp_size) }; + + Args { + parsed_args_list: parse_lp_cmd_line(lp_cmd_line) + .unwrap_or_else(lazy_current_exe) + .into_iter(), + } +} + +impl fmt::Debug for Args { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.parsed_args_list.as_slice().fmt(f) + } +} + +impl Iterator for Args { + type Item = OsString; + + fn next(&mut self) -> Option<OsString> { + self.parsed_args_list.next() + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.parsed_args_list.size_hint() + } +} + +impl ExactSizeIterator for Args { + fn len(&self) -> usize { + self.parsed_args_list.len() + } +} + +impl DoubleEndedIterator for Args { + fn next_back(&mut self) -> Option<OsString> { + self.parsed_args_list.next_back() + } +} + +/// Implements the UEFI command-line argument parsing algorithm. +/// +/// This implementation is based on what is defined in Section 3.4 of +/// [UEFI Shell Specification](https://uefi.org/sites/default/files/resources/UEFI_Shell_Spec_2_0.pdf) +/// +/// Return None in the following cases: +/// - Invalid UTF-16 (unpaired surrogate) +/// - Empty/improper arguments +fn parse_lp_cmd_line(code_units: &[u16]) -> Option<Vec<OsString>> { + const QUOTE: char = '"'; + const SPACE: char = ' '; + const CARET: char = '^'; + const NULL: char = '\0'; + + let mut ret_val = Vec::new(); + let mut code_units_iter = char::decode_utf16(code_units.iter().cloned()).peekable(); + + // The executable name at the beginning is special. + let mut in_quotes = false; + let mut cur = String::new(); + while let Some(w) = code_units_iter.next() { + let w = w.ok()?; + match w { + // break on NULL + NULL => break, + // A quote mark always toggles `in_quotes` no matter what because + // there are no escape characters when parsing the executable name. + QUOTE => in_quotes = !in_quotes, + // If not `in_quotes` then whitespace ends argv[0]. + SPACE if !in_quotes => break, + // In all other cases the code unit is taken literally. + _ => cur.push(w), + } + } + + // If exe name is missing, the cli args are invalid + if cur.is_empty() { + return None; + } + + ret_val.push(OsString::from(cur)); + // Skip whitespace. + while code_units_iter.next_if_eq(&Ok(SPACE)).is_some() {} + + // Parse the arguments according to these rules: + // * All code units are taken literally except space, quote and caret. + // * When not `in_quotes`, space separate arguments. Consecutive spaces are + // treated as a single separator. + // * A space `in_quotes` is taken literally. + // * A quote toggles `in_quotes` mode unless it's escaped. An escaped quote is taken literally. + // * A quote can be escaped if preceded by caret. + // * A caret can be escaped if preceded by caret. + let mut cur = String::new(); + let mut in_quotes = false; + while let Some(w) = code_units_iter.next() { + let w = w.ok()?; + match w { + // break on NULL + NULL => break, + // If not `in_quotes`, a space or tab ends the argument. + SPACE if !in_quotes => { + ret_val.push(OsString::from(&cur[..])); + cur.truncate(0); + + // Skip whitespace. + while code_units_iter.next_if_eq(&Ok(SPACE)).is_some() {} + } + // Caret can escape quotes or carets + CARET if in_quotes => { + if let Some(x) = code_units_iter.next() { + cur.push(x.ok()?); + } + } + // If quote then flip `in_quotes` + QUOTE => in_quotes = !in_quotes, + // Everything else is always taken literally. + _ => cur.push(w), + } + } + // Push the final argument, if any. + if !cur.is_empty() || in_quotes { + ret_val.push(OsString::from(cur)); + } + Some(ret_val) +} diff --git a/library/std/src/sys/uefi/helpers.rs b/library/std/src/sys/uefi/helpers.rs index 126661bfc96..9837cc89f2d 100644 --- a/library/std/src/sys/uefi/helpers.rs +++ b/library/std/src/sys/uefi/helpers.rs @@ -139,3 +139,10 @@ pub(crate) unsafe fn close_event(evt: NonNull<crate::ffi::c_void>) -> io::Result if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } + +/// Get the Protocol for current system handle. +/// Note: Some protocols need to be manually freed. It is the callers responsibility to do so. +pub(crate) fn image_handle_protocol<T>(protocol_guid: Guid) -> Option<NonNull<T>> { + let system_handle = uefi::env::try_image_handle()?; + open_protocol(system_handle, protocol_guid).ok() +} diff --git a/library/std/src/sys/uefi/mod.rs b/library/std/src/sys/uefi/mod.rs index 097396ae993..4edc00e3ea0 100644 --- a/library/std/src/sys/uefi/mod.rs +++ b/library/std/src/sys/uefi/mod.rs @@ -13,7 +13,6 @@ //! [`OsString`]: crate::ffi::OsString pub mod alloc; -#[path = "../unsupported/args.rs"] pub mod args; #[path = "../unix/cmath.rs"] pub mod cmath; diff --git a/library/std/src/sys/unix/process/mod.rs b/library/std/src/sys/unix/process/mod.rs index 0cf163d9fb8..947ef4c8aef 100644 --- a/library/std/src/sys/unix/process/mod.rs +++ b/library/std/src/sys/unix/process/mod.rs @@ -6,6 +6,9 @@ pub use crate::sys_common::process::CommandEnvs; #[cfg_attr(any(target_os = "espidf", target_os = "horizon"), allow(unused))] mod process_common; +#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))] +mod process_unsupported; + cfg_if::cfg_if! { if #[cfg(target_os = "fuchsia")] { #[path = "process_fuchsia.rs"] @@ -15,8 +18,9 @@ cfg_if::cfg_if! { #[path = "process_vxworks.rs"] mod process_inner; } else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))] { - #[path = "process_unsupported.rs"] - mod process_inner; + mod process_inner { + pub use super::process_unsupported::*; + } } else { #[path = "process_unix.rs"] mod process_inner; diff --git a/library/std/src/sys/unix/process/process_unsupported.rs b/library/std/src/sys/unix/process/process_unsupported.rs index 325d3f23be7..2fbb3192265 100644 --- a/library/std/src/sys/unix/process/process_unsupported.rs +++ b/library/std/src/sys/unix/process/process_unsupported.rs @@ -63,12 +63,12 @@ pub struct ExitStatusError(NonZero_c_int); impl Into<ExitStatus> for ExitStatusError { fn into(self) -> ExitStatus { - ExitStatus(self.0.into()) + ExitStatus::from(c_int::from(self.0)) } } impl ExitStatusError { pub fn code(self) -> Option<NonZeroI32> { - ExitStatus(self.0.into()).code().map(|st| st.try_into().unwrap()) + ExitStatus::from(c_int::from(self.0)).code().map(|st| st.try_into().unwrap()) } } diff --git a/library/std/src/sys/unix/process/process_unsupported/wait_status.rs b/library/std/src/sys/unix/process/process_unsupported/wait_status.rs index 3c649db1a35..72b7ae18cff 100644 --- a/library/std/src/sys/unix/process/process_unsupported/wait_status.rs +++ b/library/std/src/sys/unix/process/process_unsupported/wait_status.rs @@ -1,10 +1,13 @@ //! Emulated wait status for non-Unix #[cfg(unix) platforms //! //! Separate module to facilitate testing against a real Unix implementation. +use core::ffi::NonZero_c_int; use crate::ffi::c_int; use crate::fmt; +use super::ExitStatusError; + /// Emulated wait status for use by `process_unsupported.rs` /// /// Uses the "traditional unix" encoding. For use on platfors which are `#[cfg(unix)]` @@ -40,6 +43,19 @@ impl ExitStatus { if (w & 0x7f) == 0 { Some((w & 0xff00) >> 8) } else { None } } + #[allow(unused)] + pub fn exit_ok(&self) -> Result<(), ExitStatusError> { + // This assumes that WIFEXITED(status) && WEXITSTATUS==0 corresponds to status==0. This is + // true on all actual versions of Unix, is widely assumed, and is specified in SuS + // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not + // true for a platform pretending to be Unix, the tests (our doctests, and also + // process_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too. + match NonZero_c_int::try_from(self.wait_status) { + /* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)), + /* was zero, couldn't convert */ Err(_) => Ok(()), + } + } + pub fn signal(&self) -> Option<i32> { let signal = self.wait_status & 0x007f; if signal > 0 && signal < 0x7f { Some(signal) } else { None } diff --git a/library/std/src/sys/windows/c/windows_sys.lst b/library/std/src/sys/windows/c/windows_sys.lst index 0aca37e2d45..dad4a4223b2 100644 --- a/library/std/src/sys/windows/c/windows_sys.lst +++ b/library/std/src/sys/windows/c/windows_sys.lst @@ -1964,6 +1964,7 @@ Windows.Win32.Networking.WinSock.ADDRESS_FAMILY Windows.Win32.Networking.WinSock.ADDRINFOA Windows.Win32.Networking.WinSock.AF_INET Windows.Win32.Networking.WinSock.AF_INET6 +Windows.Win32.Networking.WinSock.AF_UNIX Windows.Win32.Networking.WinSock.AF_UNSPEC Windows.Win32.Networking.WinSock.bind Windows.Win32.Networking.WinSock.closesocket @@ -2058,6 +2059,7 @@ Windows.Win32.Networking.WinSock.SOCK_RDM Windows.Win32.Networking.WinSock.SOCK_SEQPACKET Windows.Win32.Networking.WinSock.SOCK_STREAM Windows.Win32.Networking.WinSock.SOCKADDR +Windows.Win32.Networking.WinSock.SOCKADDR_UN Windows.Win32.Networking.WinSock.SOCKET Windows.Win32.Networking.WinSock.SOCKET_ERROR Windows.Win32.Networking.WinSock.SOL_SOCKET diff --git a/library/std/src/sys/windows/c/windows_sys.rs b/library/std/src/sys/windows/c/windows_sys.rs index 851d15915c7..20b44966a39 100644 --- a/library/std/src/sys/windows/c/windows_sys.rs +++ b/library/std/src/sys/windows/c/windows_sys.rs @@ -847,6 +847,7 @@ impl ::core::clone::Clone for ADDRINFOA { } pub const AF_INET: ADDRESS_FAMILY = 2u16; pub const AF_INET6: ADDRESS_FAMILY = 23u16; +pub const AF_UNIX: u16 = 1u16; pub const AF_UNSPEC: ADDRESS_FAMILY = 0u16; pub const ALL_PROCESSOR_GROUPS: u32 = 65535u32; #[repr(C)] @@ -3813,6 +3814,17 @@ impl ::core::clone::Clone for SOCKADDR { *self } } +#[repr(C)] +pub struct SOCKADDR_UN { + pub sun_family: ADDRESS_FAMILY, + pub sun_path: [u8; 108], +} +impl ::core::marker::Copy for SOCKADDR_UN {} +impl ::core::clone::Clone for SOCKADDR_UN { + fn clone(&self) -> Self { + *self + } +} pub type SOCKET = usize; pub const SOCKET_ERROR: i32 = -1i32; pub const SOCK_DGRAM: WINSOCK_SOCKET_TYPE = 2i32; diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index 0113196b824..6ded683aade 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -1515,6 +1515,13 @@ pub fn try_exists(path: &Path) -> io::Result<bool> { // as the file existing. _ if e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as i32) => Ok(true), + // `ERROR_CANT_ACCESS_FILE` means that a file exists but that the + // reparse point could not be handled by `CreateFile`. + // This can happen for special files such as: + // * Unix domain sockets which you need to `connect` to + // * App exec links which require using `CreateProcess` + _ if e.raw_os_error() == Some(c::ERROR_CANT_ACCESS_FILE as i32) => Ok(true), + // Other errors such as `ERROR_ACCESS_DENIED` may indicate that the // file exists. However, these types of errors are usually more // permanent so we report them here. diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index 09994e47f0a..def94acd457 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -29,9 +29,9 @@ use crate::fmt; /// within a thread, and values that implement [`Drop`] get destructed when a /// thread exits. Some caveats apply, which are explained below. /// -/// A `LocalKey`'s initializer cannot recursively depend on itself, and using -/// a `LocalKey` in this way will cause the initializer to infinitely recurse -/// on the first call to `with`. +/// A `LocalKey`'s initializer cannot recursively depend on itself. Using a +/// `LocalKey` in this way may cause panics, aborts or infinite recursion on +/// the first call to `with`. /// /// # Examples /// diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index f5220e361b3..96a0eb75582 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -126,9 +126,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.2.2" +version = "4.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36774babb166352bb4f7b9cb16f781ffa3439d2a8f12cd31bea85a38c888fea3" +checksum = "e3ae8ba90b9d8b007efe66e55e48fb936272f5ca00349b5b0e89877520d35ea7" dependencies = [ "clap", ] diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 9bf26948af3..006a992eb3c 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -5,6 +5,9 @@ edition = "2021" build = "build.rs" default-run = "bootstrap" +[features] +build-metrics = ["sysinfo"] + [lib] path = "lib.rs" doctest = false @@ -31,12 +34,18 @@ test = false [dependencies] build_helper = { path = "../tools/build_helper" } +cc = "1.0.69" +clap = { version = "4.2.4", default-features = false, features = ["std", "usage", "help", "derive", "error-context"] } +clap_complete = "4.4.3" cmake = "0.1.38" filetime = "0.2" -cc = "1.0.69" -libc = "0.2" hex = "0.4" +ignore = "0.4.10" +libc = "0.2" object = { version = "0.32.0", default-features = false, features = ["archive", "coff", "read_core", "unaligned"] } +once_cell = "1.7.2" +opener = "0.5" +semver = "1.0.17" serde = "1.0.137" # Directly use serde_derive rather than through the derive feature of serde to allow building both # in parallel and to allow serde_json and toml to start building as soon as serde has been built. @@ -46,17 +55,11 @@ sha2 = "0.10" tar = "0.4" termcolor = "1.2.0" toml = "0.5" -ignore = "0.4.10" -opener = "0.5" -once_cell = "1.7.2" -xz2 = "0.1" walkdir = "2" +xz2 = "0.1" # Dependencies needed by the build-metrics feature sysinfo = { version = "0.26.0", optional = true } -clap = { version = "4.2.4", default-features = false, features = ["std", "usage", "help", "derive", "error-context"] } -clap_complete = "4.2.2" -semver = "1.0.17" # Solaris doesn't support flock() and thus fd-lock is not option now [target.'cfg(not(target_os = "solaris"))'.dependencies] @@ -80,9 +83,6 @@ features = [ [dev-dependencies] pretty_assertions = "1.4" -[features] -build-metrics = ["sysinfo"] - # We care a lot about bootstrap's compile times, so don't include debuginfo for # dependencies, only bootstrap itself. [profile.dev] diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index b7fd2aa9637..6cc5162120a 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -193,6 +193,12 @@ fn main() { eprintln!("{prefix} libdir: {libdir:?}"); } + if env::var_os("RUSTC_BOLT_LINK_FLAGS").is_some() { + if let Some("rustc_driver") = crate_name { + cmd.arg("-Clink-args=-Wl,-q"); + } + } + let start = Instant::now(); let (child, status) = { let errmsg = format!("\nFailed to run:\n{cmd:?}\n-------------"); diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index 80e66622e8b..0294102286e 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -22,7 +22,6 @@ fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config ..Config::parse(&["check".to_owned()]) }); submodule_build.update_submodule(Path::new("src/doc/book")); - submodule_build.update_submodule(Path::new("src/tools/rust-analyzer")); config.submodules = Some(false); config.ninja_in_file = false; diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 6821ded1458..623fa5fa111 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -906,6 +906,11 @@ impl Step for Rustc { cargo.arg("-p").arg(krate); } + if builder.build.config.enable_bolt_settings && compiler.stage == 1 { + // Relocations are required for BOLT to work. + cargo.env("RUSTC_BOLT_LINK_FLAGS", "1"); + } + let _guard = builder.msg_sysroot_tool( Kind::Build, compiler.stage, diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 1755c3166de..759d874a089 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -234,6 +234,7 @@ pub struct Config { pub llvm_profile_use: Option<String>, pub llvm_profile_generate: bool, pub llvm_libunwind_default: Option<LlvmLibunwind>, + pub enable_bolt_settings: bool, pub reproducible_artifacts: Vec<String>, @@ -1128,6 +1129,7 @@ impl Config { config.free_args = std::mem::take(&mut flags.free_args); config.llvm_profile_use = flags.llvm_profile_use; config.llvm_profile_generate = flags.llvm_profile_generate; + config.enable_bolt_settings = flags.enable_bolt_settings; // Infer the rest of the configuration. diff --git a/src/bootstrap/config/tests.rs b/src/bootstrap/config/tests.rs index d091f33eee4..ae8363b6de9 100644 --- a/src/bootstrap/config/tests.rs +++ b/src/bootstrap/config/tests.rs @@ -3,7 +3,12 @@ use crate::config::TomlConfig; use super::{Config, Flags}; use clap::CommandFactory; use serde::Deserialize; -use std::{env, path::Path}; +use std::{ + env, + fs::{remove_file, File}, + io::Write, + path::Path, +}; fn parse(config: &str) -> Config { Config::parse_inner(&["check".to_owned(), "--config=/does/not/exist".to_owned()], |&_| { @@ -196,3 +201,19 @@ fn rust_optimize() { fn invalid_rust_optimize() { parse("rust.optimize = \"a\""); } + +#[test] +fn verify_file_integrity() { + let config = parse(""); + + let tempfile = config.tempdir().join(".tmp-test-file"); + File::create(&tempfile).unwrap().write_all(b"dummy value").unwrap(); + assert!(tempfile.exists()); + + assert!( + config + .verify(&tempfile, "7e255dd9542648a8779268a0f268b891a198e9828e860ed23f826440e786eae5") + ); + + remove_file(tempfile).unwrap(); +} diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 05556d2f679..7bb59e5a611 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1002,11 +1002,15 @@ impl Step for PlainSourceTarball { channel::write_commit_info_file(&plain_dst_src, info); } - // If we're building from git sources, we need to vendor a complete distribution. - if builder.rust_info().is_managed_git_subrepository() { - // Ensure we have the submodules checked out. - builder.update_submodule(Path::new("src/tools/cargo")); - builder.update_submodule(Path::new("src/tools/rust-analyzer")); + // If we're building from git or tarball sources, we need to vendor + // a complete distribution. + if builder.rust_info().is_managed_git_subrepository() + || builder.rust_info().is_from_tarball() + { + if builder.rust_info().is_managed_git_subrepository() { + // Ensure we have the submodules checked out. + builder.update_submodule(Path::new("src/tools/cargo")); + } // Vendor all Cargo dependencies let mut cmd = Command::new(&builder.initial_cargo); diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index 8e9614ec89a..2a0dec75599 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -320,25 +320,43 @@ impl Config { } /// Returns whether the SHA256 checksum of `path` matches `expected`. - fn verify(&self, path: &Path, expected: &str) -> bool { + pub(crate) fn verify(&self, path: &Path, expected: &str) -> bool { use sha2::Digest; self.verbose(&format!("verifying {}", path.display())); + + if self.dry_run() { + return false; + } + let mut hasher = sha2::Sha256::new(); - // FIXME: this is ok for rustfmt (4.1 MB large at time of writing), but it seems memory-intensive for rustc and larger components. - // Consider using streaming IO instead? - let contents = if self.dry_run() { vec![] } else { t!(fs::read(path)) }; - hasher.update(&contents); - let found = hex::encode(hasher.finalize().as_slice()); - let verified = found == expected; - if !verified && !self.dry_run() { + + let file = t!(File::open(path)); + let mut reader = BufReader::new(file); + + loop { + let buffer = t!(reader.fill_buf()); + let l = buffer.len(); + // break if EOF + if l == 0 { + break; + } + hasher.update(buffer); + reader.consume(l); + } + + let checksum = hex::encode(hasher.finalize().as_slice()); + let verified = checksum == expected; + + if !verified { println!( "invalid checksum: \n\ - found: {found}\n\ + found: {checksum}\n\ expected: {expected}", ); } - return verified; + + verified } } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index e0291e407b3..5a6a5f37fc6 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -152,6 +152,9 @@ pub struct Flags { /// generate PGO profile with llvm built for rustc #[arg(global(true), long)] pub llvm_profile_generate: bool, + /// Enable BOLT link flags + #[arg(global(true), long)] + pub enable_bolt_settings: bool, /// Additional reproducible artifacts that should be added to the reproducible artifacts archive. #[arg(global(true), long)] pub reproducible_artifact: Vec<String>, diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 5c78015e560..a9a81cb25f6 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -138,18 +138,9 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[ (Some(Mode::Std), "freebsd13", None), (Some(Mode::Std), "backtrace_in_libstd", None), /* Extra values not defined in the built-in targets yet, but used in std */ - // #[cfg(bootstrap)] - (Some(Mode::Std), "target_vendor", Some(&["unikraft"])), (Some(Mode::Std), "target_env", Some(&["libnx"])), - // #[cfg(bootstrap)] hurd - (Some(Mode::Std), "target_os", Some(&["teeos", "hurd"])), - (Some(Mode::Rustc), "target_os", Some(&["hurd"])), - // #[cfg(bootstrap)] mips32r6, mips64r6 - ( - Some(Mode::Std), - "target_arch", - Some(&["asmjs", "spirv", "nvptx", "xtensa", "mips32r6", "mips64r6", "csky"]), - ), + // (Some(Mode::Std), "target_os", Some(&[])), + (Some(Mode::Std), "target_arch", Some(&["asmjs", "spirv", "nvptx", "xtensa"])), /* Extra names used by dependencies */ // FIXME: Used by serde_json, but we should not be triggering on external dependencies. (Some(Mode::Rustc), "no_btreemap_remove_entry", None), @@ -368,6 +359,10 @@ impl Build { // https://github.com/rust-lang/rust/blob/a8a33cf27166d3eabaffc58ed3799e054af3b0c6/src/bootstrap/bootstrap.py#L796-L797 let is_sudo = match env::var_os("SUDO_USER") { Some(_sudo_user) => { + // SAFETY: getuid() system call is always successful and no return value is reserved + // to indicate an error. + // + // For more context, see https://man7.org/linux/man-pages/man2/geteuid.2.html let uid = unsafe { libc::getuid() }; uid == 0 } diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index 4082f5bb9b1..f253f5225a1 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -1,8 +1,6 @@ use std::path::PathBuf; use std::process::Command; -use clap_complete::shells; - use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::config::TargetSelection; use crate::dist::distdir; @@ -268,23 +266,29 @@ impl Step for GenerateWindowsSys { #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct GenerateCompletions; +macro_rules! generate_completions { + ( $( ( $shell:ident, $filename:expr ) ),* ) => { + $( + if let Some(comp) = get_completion($shell, &$filename) { + std::fs::write(&$filename, comp).expect(&format!("writing {} completion", stringify!($shell))); + } + )* + }; +} + impl Step for GenerateCompletions { type Output = (); /// Uses `clap_complete` to generate shell completions. fn run(self, builder: &Builder<'_>) { - // FIXME(clubby789): enable zsh when clap#4898 is fixed - let [bash, fish, powershell] = ["x.py.sh", "x.py.fish", "x.py.ps1"] - .map(|filename| builder.src.join("src/etc/completions").join(filename)); - if let Some(comp) = get_completion(shells::Bash, &bash) { - std::fs::write(&bash, comp).expect("writing bash completion"); - } - if let Some(comp) = get_completion(shells::Fish, &fish) { - std::fs::write(&fish, comp).expect("writing fish completion"); - } - if let Some(comp) = get_completion(shells::PowerShell, &powershell) { - std::fs::write(&powershell, comp).expect("writing powershell completion"); - } + use clap_complete::shells::{Bash, Fish, PowerShell, Zsh}; + + generate_completions!( + (Bash, builder.src.join("src/etc/completions/x.py.sh")), + (Zsh, builder.src.join("src/etc/completions/x.py.zsh")), + (Fish, builder.src.join("src/etc/completions/x.py.fish")), + (PowerShell, builder.src.join("src/etc/completions/x.py.ps1")) + ); } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index ba030f0f525..fb8ec0355c2 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1135,13 +1135,14 @@ help: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to builder.ensure(ExpandYamlAnchors); builder.info("x.py completions check"); - let [bash, fish, powershell] = ["x.py.sh", "x.py.fish", "x.py.ps1"] + let [bash, zsh, fish, powershell] = ["x.py.sh", "x.py.zsh", "x.py.fish", "x.py.ps1"] .map(|filename| builder.src.join("src/etc/completions").join(filename)); if builder.config.cmd.bless() { builder.ensure(crate::run::GenerateCompletions); } else if crate::flags::get_completion(shells::Bash, &bash).is_some() || crate::flags::get_completion(shells::Fish, &fish).is_some() || crate::flags::get_completion(shells::PowerShell, &powershell).is_some() + || crate::flags::get_completion(shells::Zsh, &zsh).is_some() { eprintln!( "x.py completions were changed; run `x.py run generate-completions` to update them" @@ -2940,10 +2941,6 @@ impl Step for TestHelpers { let _guard = builder.msg_unstaged(Kind::Build, "test helpers", target); t!(fs::create_dir_all(&dst)); let mut cfg = cc::Build::new(); - // FIXME: Workaround for https://github.com/emscripten-core/emscripten/issues/9013 - if target.contains("emscripten") { - cfg.pic(false); - } // We may have found various cross-compilers a little differently due to our // extra configuration, so inform cc of these compilers. Note, though, that diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh index 6da3f89220e..3b3ec5da74b 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh @@ -27,10 +27,15 @@ sed -i'' 's|ftp://gcc\.gnu\.org/|https://gcc.gnu.org/|g' ./contrib/download_prer ./contrib/download_prerequisites mkdir ../gcc-build cd ../gcc-build + +# '-fno-reorder-blocks-and-partition' is required to +# enable BOLT optimization of the C++ standard library, +# which is included in librustc_driver.so hide_output ../gcc-$GCC/configure \ --prefix=/rustroot \ --enable-languages=c,c++ \ - --disable-gnu-unique-object + --disable-gnu-unique-object \ + --enable-cxx-flags='-fno-reorder-blocks-and-partition' hide_output make -j$(nproc) hide_output make install ln -s gcc /rustroot/bin/cc diff --git a/src/doc/rustc/src/platform-support/android.md b/src/doc/rustc/src/platform-support/android.md index 4ef74295e0f..9ddf00e3a50 100644 --- a/src/doc/rustc/src/platform-support/android.md +++ b/src/doc/rustc/src/platform-support/android.md @@ -45,3 +45,19 @@ The riscv64-linux-android target is supported as a Tier 3 target. A list of all supported targets can be found [here](../platform-support.html) + +## Architecture Notes + +### riscv64-linux-android + +Currently the `riscv64-linux-android` target requires the following architecture features/extensions: + +* `a` (atomics) +* `d` (double-precision floating-point) +* `c` (compressed instruction set) +* `f` (single-precision floating-point) +* `m` (multiplication and division) +* `v` (vector) +* `Zba` (address calculation instructions) +* `Zbb` (base instructions) +* `Zbs` (single-bit instructions) diff --git a/src/doc/rustc/src/platform-support/unknown-uefi.md b/src/doc/rustc/src/platform-support/unknown-uefi.md index 370939520dc..1230ea22bd9 100644 --- a/src/doc/rustc/src/platform-support/unknown-uefi.md +++ b/src/doc/rustc/src/platform-support/unknown-uefi.md @@ -268,6 +268,8 @@ cargo build --target x86_64-unknown-uefi -Zbuild-std=std,panic_abort #### stdio - Uses `Simple Text Input Protocol` and `Simple Text Output Protocol`. - Note: UEFI uses CRLF for new line. This means Enter key is registered as CR instead of LF. +#### args +- Uses `EFI_LOADED_IMAGE_PROTOCOL->LoadOptions` ## Example: Hello World With std The following code features a valid UEFI application, including `stdio` and `alloc` (`OsString` and `Vec`): diff --git a/src/doc/rustdoc/src/advanced-features.md b/src/doc/rustdoc/src/advanced-features.md index dbf0baec04c..1733c8fc9a2 100644 --- a/src/doc/rustdoc/src/advanced-features.md +++ b/src/doc/rustdoc/src/advanced-features.md @@ -110,3 +110,23 @@ https://doc.rust-lang.org/stable/std/?search=%s&go_to_first=true This URL adds the `go_to_first=true` query parameter which can be appended to any `rustdoc` search URL to automatically go to the first result. + +## `#[repr(transparent)]`: Documenting the transparent representation + +You can read more about `#[repr(transparent)]` itself in the [Rust Reference][repr-trans-ref] and +in the [Rustonomicon][repr-trans-nomicon]. + +Since this representation is only considered part of the public ABI if the single field with non-trivial +size or alignment is public and if the documentation does not state otherwise, Rustdoc helpfully displays +the attribute if and only if the non-1-ZST field is public or at least one field is public in case all +fields are 1-ZST fields. The term *1-ZST* refers to types that are one-aligned and zero-sized. + +It would seem that one can manually hide the attribute with `#[cfg_attr(not(doc), repr(transparent))]` +if one wishes to declare the representation as private even if the non-1-ZST field is public. +However, due to [current limitations][cross-crate-cfg-doc], this method is not always guaranteed to work. +Therefore, if you would like to do so, you should always write it down in prose independently of whether +you use `cfg_attr` or not. + +[repr-trans-ref]: https://doc.rust-lang.org/reference/type-layout.html#the-transparent-representation +[repr-trans-nomicon]: https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent +[cross-crate-cfg-doc]: https://github.com/rust-lang/rust/issues/114952 diff --git a/src/doc/unstable-book/src/language-features/string-deref-patterns.md b/src/doc/unstable-book/src/language-features/string-deref-patterns.md new file mode 100644 index 00000000000..3723830751e --- /dev/null +++ b/src/doc/unstable-book/src/language-features/string-deref-patterns.md @@ -0,0 +1,45 @@ +# `string_deref_patterns` + +The tracking issue for this feature is: [#87121] + +[#87121]: https://github.com/rust-lang/rust/issues/87121 + +------------------------ + +This feature permits pattern matching `String` to `&str` through [its `Deref` implementation]. + +```rust +#![feature(string_deref_patterns)] + +pub enum Value { + String(String), + Number(u32), +} + +pub fn is_it_the_answer(value: Value) -> bool { + match value { + Value::String("42") => true, + Value::Number(42) => true, + _ => false, + } +} +``` + +Without this feature other constructs such as match guards have to be used. + +```rust +# pub enum Value { +# String(String), +# Number(u32), +# } +# +pub fn is_it_the_answer(value: Value) -> bool { + match value { + Value::String(s) if s == "42" => true, + Value::Number(42) => true, + _ => false, + } +} +``` + +[its `Deref` implementation]: https://doc.rust-lang.org/std/string/struct.String.html#impl-Deref-for-String diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index 151c4120ddf..85fcc37fd81 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -12,10 +12,10 @@ complete -c x.py -n "__fish_use_subcommand" -l keep-stage -d 'stage(s) to keep w complete -c x.py -n "__fish_use_subcommand" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_use_subcommand" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_use_subcommand" -s j -l jobs -d 'number of jobs to run in parallel' -r -f -complete -c x.py -n "__fish_use_subcommand" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_use_subcommand" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" complete -c x.py -n "__fish_use_subcommand" -l error-format -d 'rustc error format' -r -f -complete -c x.py -n "__fish_use_subcommand" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" -complete -c x.py -n "__fish_use_subcommand" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_use_subcommand" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_use_subcommand" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" complete -c x.py -n "__fish_use_subcommand" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F complete -c x.py -n "__fish_use_subcommand" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_use_subcommand" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F @@ -27,6 +27,7 @@ complete -c x.py -n "__fish_use_subcommand" -l include-default-paths -d 'include complete -c x.py -n "__fish_use_subcommand" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_use_subcommand" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_use_subcommand" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_use_subcommand" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_use_subcommand" -s h -l help -d 'Print help' complete -c x.py -n "__fish_use_subcommand" -f -a "build" -d 'Compile either the compiler or libraries' complete -c x.py -n "__fish_use_subcommand" -f -a "check" -d 'Compile either the compiler or libraries, using cargo check' @@ -56,10 +57,10 @@ complete -c x.py -n "__fish_seen_subcommand_from build" -l keep-stage -d 'stage( complete -c x.py -n "__fish_seen_subcommand_from build" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from build" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from build" -s j -l jobs -d 'number of jobs to run in parallel' -r -f -complete -c x.py -n "__fish_seen_subcommand_from build" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from build" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" complete -c x.py -n "__fish_seen_subcommand_from build" -l error-format -d 'rustc error format' -r -f -complete -c x.py -n "__fish_seen_subcommand_from build" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" -complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from build" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" complete -c x.py -n "__fish_seen_subcommand_from build" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from build" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F @@ -71,6 +72,7 @@ complete -c x.py -n "__fish_seen_subcommand_from build" -l include-default-paths complete -c x.py -n "__fish_seen_subcommand_from build" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_seen_subcommand_from build" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from build" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from build" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_seen_subcommand_from check" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_seen_subcommand_from check" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" @@ -86,10 +88,10 @@ complete -c x.py -n "__fish_seen_subcommand_from check" -l keep-stage -d 'stage( complete -c x.py -n "__fish_seen_subcommand_from check" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from check" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from check" -s j -l jobs -d 'number of jobs to run in parallel' -r -f -complete -c x.py -n "__fish_seen_subcommand_from check" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from check" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" complete -c x.py -n "__fish_seen_subcommand_from check" -l error-format -d 'rustc error format' -r -f -complete -c x.py -n "__fish_seen_subcommand_from check" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" -complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from check" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" complete -c x.py -n "__fish_seen_subcommand_from check" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from check" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F @@ -102,6 +104,7 @@ complete -c x.py -n "__fish_seen_subcommand_from check" -l include-default-paths complete -c x.py -n "__fish_seen_subcommand_from check" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_seen_subcommand_from check" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from check" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from check" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_seen_subcommand_from clippy" -s A -d 'clippy lints to allow' -r complete -c x.py -n "__fish_seen_subcommand_from clippy" -s D -d 'clippy lints to deny' -r @@ -121,10 +124,10 @@ complete -c x.py -n "__fish_seen_subcommand_from clippy" -l keep-stage -d 'stage complete -c x.py -n "__fish_seen_subcommand_from clippy" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from clippy" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from clippy" -s j -l jobs -d 'number of jobs to run in parallel' -r -f -complete -c x.py -n "__fish_seen_subcommand_from clippy" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" complete -c x.py -n "__fish_seen_subcommand_from clippy" -l error-format -d 'rustc error format' -r -f -complete -c x.py -n "__fish_seen_subcommand_from clippy" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" -complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" complete -c x.py -n "__fish_seen_subcommand_from clippy" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from clippy" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F @@ -137,6 +140,7 @@ complete -c x.py -n "__fish_seen_subcommand_from clippy" -l include-default-path complete -c x.py -n "__fish_seen_subcommand_from clippy" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_seen_subcommand_from clippy" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from clippy" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_seen_subcommand_from fix" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_seen_subcommand_from fix" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" @@ -152,10 +156,10 @@ complete -c x.py -n "__fish_seen_subcommand_from fix" -l keep-stage -d 'stage(s) complete -c x.py -n "__fish_seen_subcommand_from fix" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from fix" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from fix" -s j -l jobs -d 'number of jobs to run in parallel' -r -f -complete -c x.py -n "__fish_seen_subcommand_from fix" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from fix" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" complete -c x.py -n "__fish_seen_subcommand_from fix" -l error-format -d 'rustc error format' -r -f -complete -c x.py -n "__fish_seen_subcommand_from fix" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" -complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from fix" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" complete -c x.py -n "__fish_seen_subcommand_from fix" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from fix" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F @@ -167,6 +171,7 @@ complete -c x.py -n "__fish_seen_subcommand_from fix" -l include-default-paths - complete -c x.py -n "__fish_seen_subcommand_from fix" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_seen_subcommand_from fix" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from fix" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from fix" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_seen_subcommand_from fmt" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_seen_subcommand_from fmt" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" @@ -182,10 +187,10 @@ complete -c x.py -n "__fish_seen_subcommand_from fmt" -l keep-stage -d 'stage(s) complete -c x.py -n "__fish_seen_subcommand_from fmt" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from fmt" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from fmt" -s j -l jobs -d 'number of jobs to run in parallel' -r -f -complete -c x.py -n "__fish_seen_subcommand_from fmt" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" complete -c x.py -n "__fish_seen_subcommand_from fmt" -l error-format -d 'rustc error format' -r -f -complete -c x.py -n "__fish_seen_subcommand_from fmt" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" -complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" complete -c x.py -n "__fish_seen_subcommand_from fmt" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from fmt" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F @@ -198,6 +203,7 @@ complete -c x.py -n "__fish_seen_subcommand_from fmt" -l include-default-paths - complete -c x.py -n "__fish_seen_subcommand_from fmt" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_seen_subcommand_from fmt" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from fmt" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_seen_subcommand_from doc" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_seen_subcommand_from doc" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" @@ -213,10 +219,10 @@ complete -c x.py -n "__fish_seen_subcommand_from doc" -l keep-stage -d 'stage(s) complete -c x.py -n "__fish_seen_subcommand_from doc" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from doc" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from doc" -s j -l jobs -d 'number of jobs to run in parallel' -r -f -complete -c x.py -n "__fish_seen_subcommand_from doc" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from doc" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" complete -c x.py -n "__fish_seen_subcommand_from doc" -l error-format -d 'rustc error format' -r -f -complete -c x.py -n "__fish_seen_subcommand_from doc" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" -complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from doc" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" complete -c x.py -n "__fish_seen_subcommand_from doc" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from doc" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F @@ -230,6 +236,7 @@ complete -c x.py -n "__fish_seen_subcommand_from doc" -l include-default-paths - complete -c x.py -n "__fish_seen_subcommand_from doc" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_seen_subcommand_from doc" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from doc" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from doc" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_seen_subcommand_from test" -l skip -d 'skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times' -r -F complete -c x.py -n "__fish_seen_subcommand_from test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r @@ -251,10 +258,10 @@ complete -c x.py -n "__fish_seen_subcommand_from test" -l keep-stage -d 'stage(s complete -c x.py -n "__fish_seen_subcommand_from test" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from test" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from test" -s j -l jobs -d 'number of jobs to run in parallel' -r -f -complete -c x.py -n "__fish_seen_subcommand_from test" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from test" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" complete -c x.py -n "__fish_seen_subcommand_from test" -l error-format -d 'rustc error format' -r -f -complete -c x.py -n "__fish_seen_subcommand_from test" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" -complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from test" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" complete -c x.py -n "__fish_seen_subcommand_from test" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from test" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F @@ -273,6 +280,7 @@ complete -c x.py -n "__fish_seen_subcommand_from test" -l include-default-paths complete -c x.py -n "__fish_seen_subcommand_from test" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_seen_subcommand_from test" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from test" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_seen_subcommand_from bench" -l test-args -r complete -c x.py -n "__fish_seen_subcommand_from bench" -l config -d 'TOML configuration file for build' -r -F @@ -289,10 +297,10 @@ complete -c x.py -n "__fish_seen_subcommand_from bench" -l keep-stage -d 'stage( complete -c x.py -n "__fish_seen_subcommand_from bench" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from bench" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from bench" -s j -l jobs -d 'number of jobs to run in parallel' -r -f -complete -c x.py -n "__fish_seen_subcommand_from bench" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from bench" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" complete -c x.py -n "__fish_seen_subcommand_from bench" -l error-format -d 'rustc error format' -r -f -complete -c x.py -n "__fish_seen_subcommand_from bench" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" -complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from bench" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" complete -c x.py -n "__fish_seen_subcommand_from bench" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from bench" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F @@ -304,6 +312,7 @@ complete -c x.py -n "__fish_seen_subcommand_from bench" -l include-default-paths complete -c x.py -n "__fish_seen_subcommand_from bench" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_seen_subcommand_from bench" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from bench" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from bench" -s h -l help -d 'Print help' complete -c x.py -n "__fish_seen_subcommand_from clean" -l stage -d 'Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used' -r complete -c x.py -n "__fish_seen_subcommand_from clean" -l config -d 'TOML configuration file for build' -r -F @@ -319,10 +328,10 @@ complete -c x.py -n "__fish_seen_subcommand_from clean" -l keep-stage -d 'stage( complete -c x.py -n "__fish_seen_subcommand_from clean" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from clean" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from clean" -s j -l jobs -d 'number of jobs to run in parallel' -r -f -complete -c x.py -n "__fish_seen_subcommand_from clean" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from clean" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" complete -c x.py -n "__fish_seen_subcommand_from clean" -l error-format -d 'rustc error format' -r -f -complete -c x.py -n "__fish_seen_subcommand_from clean" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" -complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from clean" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" complete -c x.py -n "__fish_seen_subcommand_from clean" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from clean" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F @@ -335,6 +344,7 @@ complete -c x.py -n "__fish_seen_subcommand_from clean" -l include-default-paths complete -c x.py -n "__fish_seen_subcommand_from clean" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_seen_subcommand_from clean" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from clean" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from clean" -s h -l help -d 'Print help' complete -c x.py -n "__fish_seen_subcommand_from dist" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_seen_subcommand_from dist" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" @@ -350,10 +360,10 @@ complete -c x.py -n "__fish_seen_subcommand_from dist" -l keep-stage -d 'stage(s complete -c x.py -n "__fish_seen_subcommand_from dist" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from dist" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from dist" -s j -l jobs -d 'number of jobs to run in parallel' -r -f -complete -c x.py -n "__fish_seen_subcommand_from dist" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from dist" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" complete -c x.py -n "__fish_seen_subcommand_from dist" -l error-format -d 'rustc error format' -r -f -complete -c x.py -n "__fish_seen_subcommand_from dist" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" -complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from dist" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" complete -c x.py -n "__fish_seen_subcommand_from dist" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from dist" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F @@ -365,6 +375,7 @@ complete -c x.py -n "__fish_seen_subcommand_from dist" -l include-default-paths complete -c x.py -n "__fish_seen_subcommand_from dist" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_seen_subcommand_from dist" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from dist" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from dist" -s h -l help -d 'Print help' complete -c x.py -n "__fish_seen_subcommand_from install" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_seen_subcommand_from install" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" @@ -380,10 +391,10 @@ complete -c x.py -n "__fish_seen_subcommand_from install" -l keep-stage -d 'stag complete -c x.py -n "__fish_seen_subcommand_from install" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from install" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from install" -s j -l jobs -d 'number of jobs to run in parallel' -r -f -complete -c x.py -n "__fish_seen_subcommand_from install" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from install" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" complete -c x.py -n "__fish_seen_subcommand_from install" -l error-format -d 'rustc error format' -r -f -complete -c x.py -n "__fish_seen_subcommand_from install" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" -complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from install" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" complete -c x.py -n "__fish_seen_subcommand_from install" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from install" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F @@ -395,6 +406,7 @@ complete -c x.py -n "__fish_seen_subcommand_from install" -l include-default-pat complete -c x.py -n "__fish_seen_subcommand_from install" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_seen_subcommand_from install" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from install" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from install" -s h -l help -d 'Print help' complete -c x.py -n "__fish_seen_subcommand_from run" -l args -d 'arguments for the tool' -r complete -c x.py -n "__fish_seen_subcommand_from run" -l config -d 'TOML configuration file for build' -r -F @@ -411,10 +423,10 @@ complete -c x.py -n "__fish_seen_subcommand_from run" -l keep-stage -d 'stage(s) complete -c x.py -n "__fish_seen_subcommand_from run" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from run" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from run" -s j -l jobs -d 'number of jobs to run in parallel' -r -f -complete -c x.py -n "__fish_seen_subcommand_from run" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from run" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" complete -c x.py -n "__fish_seen_subcommand_from run" -l error-format -d 'rustc error format' -r -f -complete -c x.py -n "__fish_seen_subcommand_from run" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" -complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from run" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" complete -c x.py -n "__fish_seen_subcommand_from run" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from run" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F @@ -426,6 +438,7 @@ complete -c x.py -n "__fish_seen_subcommand_from run" -l include-default-paths - complete -c x.py -n "__fish_seen_subcommand_from run" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_seen_subcommand_from run" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from run" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from run" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_seen_subcommand_from setup" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_seen_subcommand_from setup" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" @@ -441,10 +454,10 @@ complete -c x.py -n "__fish_seen_subcommand_from setup" -l keep-stage -d 'stage( complete -c x.py -n "__fish_seen_subcommand_from setup" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from setup" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from setup" -s j -l jobs -d 'number of jobs to run in parallel' -r -f -complete -c x.py -n "__fish_seen_subcommand_from setup" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from setup" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" complete -c x.py -n "__fish_seen_subcommand_from setup" -l error-format -d 'rustc error format' -r -f -complete -c x.py -n "__fish_seen_subcommand_from setup" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" -complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from setup" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" complete -c x.py -n "__fish_seen_subcommand_from setup" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from setup" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F @@ -456,6 +469,7 @@ complete -c x.py -n "__fish_seen_subcommand_from setup" -l include-default-paths complete -c x.py -n "__fish_seen_subcommand_from setup" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_seen_subcommand_from setup" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from setup" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from setup" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_seen_subcommand_from suggest" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_seen_subcommand_from suggest" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" @@ -471,10 +485,10 @@ complete -c x.py -n "__fish_seen_subcommand_from suggest" -l keep-stage -d 'stag complete -c x.py -n "__fish_seen_subcommand_from suggest" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from suggest" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from suggest" -s j -l jobs -d 'number of jobs to run in parallel' -r -f -complete -c x.py -n "__fish_seen_subcommand_from suggest" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" complete -c x.py -n "__fish_seen_subcommand_from suggest" -l error-format -d 'rustc error format' -r -f -complete -c x.py -n "__fish_seen_subcommand_from suggest" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" -complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" complete -c x.py -n "__fish_seen_subcommand_from suggest" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from suggest" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F @@ -487,4 +501,5 @@ complete -c x.py -n "__fish_seen_subcommand_from suggest" -l include-default-pat complete -c x.py -n "__fish_seen_subcommand_from suggest" -l dry-run -d 'dry run; don\'t build anything' complete -c x.py -n "__fish_seen_subcommand_from suggest" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from suggest" -s h -l help -d 'Print help (see more with \'--help\')' diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index cafb8eed12d..07e1b0ace9d 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -53,6 +53,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('build', 'build', [CompletionResultType]::ParameterValue, 'Compile either the compiler or libraries') @@ -104,6 +105,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break @@ -142,15 +144,16 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'x.py;clippy' { - [CompletionResult]::new('-A', 'A', [CompletionResultType]::ParameterName, 'clippy lints to allow') - [CompletionResult]::new('-D', 'D', [CompletionResultType]::ParameterName, 'clippy lints to deny') - [CompletionResult]::new('-W', 'W', [CompletionResultType]::ParameterName, 'clippy lints to warn on') - [CompletionResult]::new('-F', 'F', [CompletionResultType]::ParameterName, 'clippy lints to forbid') + [CompletionResult]::new('-A', 'A ', [CompletionResultType]::ParameterName, 'clippy lints to allow') + [CompletionResult]::new('-D', 'D ', [CompletionResultType]::ParameterName, 'clippy lints to deny') + [CompletionResult]::new('-W', 'W ', [CompletionResultType]::ParameterName, 'clippy lints to warn on') + [CompletionResult]::new('-F', 'F ', [CompletionResultType]::ParameterName, 'clippy lints to forbid') [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') @@ -184,6 +187,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break @@ -221,6 +225,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break @@ -259,6 +264,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break @@ -298,6 +304,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break @@ -348,6 +355,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break @@ -386,6 +394,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') break @@ -424,6 +433,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') break @@ -461,6 +471,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') break @@ -498,6 +509,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') break @@ -536,6 +548,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break @@ -573,6 +586,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break @@ -611,6 +625,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh index 3c57e71bdb7..241bc058e7b 100644 --- a/src/etc/completions/x.py.sh +++ b/src/etc/completions/x.py.sh @@ -61,7 +61,7 @@ _x.py() { case "${cmd}" in x.py) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test bench clean dist install run setup suggest" + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test bench clean dist install run setup suggest" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -171,7 +171,7 @@ _x.py() { return 0 ;; x.py__bench) - opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -285,7 +285,7 @@ _x.py() { return 0 ;; x.py__build) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -395,7 +395,7 @@ _x.py() { return 0 ;; x.py__check) - opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -505,7 +505,7 @@ _x.py() { return 0 ;; x.py__clean) - opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -615,7 +615,7 @@ _x.py() { return 0 ;; x.py__clippy) - opts="-A -D -W -F -v -i -j -h --fix --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-A -D -W -F -v -i -j -h --fix --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -741,7 +741,7 @@ _x.py() { return 0 ;; x.py__dist) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -851,7 +851,7 @@ _x.py() { return 0 ;; x.py__doc) - opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -961,7 +961,7 @@ _x.py() { return 0 ;; x.py__fix) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1071,7 +1071,7 @@ _x.py() { return 0 ;; x.py__fmt) - opts="-v -i -j -h --check --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --check --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1181,7 +1181,7 @@ _x.py() { return 0 ;; x.py__install) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1291,7 +1291,7 @@ _x.py() { return 0 ;; x.py__run) - opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1405,7 +1405,7 @@ _x.py() { return 0 ;; x.py__setup) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [<PROFILE>|hook|vscode|link] [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [<PROFILE>|hook|vscode|link] [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1515,7 +1515,7 @@ _x.py() { return 0 ;; x.py__suggest) - opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1625,7 +1625,7 @@ _x.py() { return 0 ;; x.py__test) - opts="-v -i -j -h --no-fail-fast --skip --test-args --rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --no-fail-fast --skip --test-args --rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1761,4 +1761,4 @@ _x.py() { esac } -complete -F _x.py -o bashdefault -o default x.py +complete -F _x.py -o nosort -o bashdefault -o default x.py diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh new file mode 100644 index 00000000000..89959701a06 --- /dev/null +++ b/src/etc/completions/x.py.zsh @@ -0,0 +1,751 @@ +#compdef x.py + +autoload -U is-at-least + +_x.py() { + typeset -A opt_args + typeset -a _arguments_options + local ret=1 + + if is-at-least 5.2; then + _arguments_options=(-s -S -C) + else + _arguments_options=(-s -C) + fi + + local context curcontext="$curcontext" state line + _arguments "${_arguments_options[@]}" \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--json-output[use message-format=json]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'-h[Print help]' \ +'--help[Print help]' \ +'::paths -- paths for the subcommand:_files' \ +'::free_args -- arguments passed to subcommands:' \ +":: :_x.py_commands" \ +"*::: :->bootstrap" \ +&& ret=0 + case $state in + (bootstrap) + words=($line[3] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:x.py-command-$line[3]:" + case $line[3] in + (build) +_arguments "${_arguments_options[@]}" \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--json-output[use message-format=json]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 +;; +(check) +_arguments "${_arguments_options[@]}" \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'--all-targets[Check all targets]' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--json-output[use message-format=json]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 +;; +(clippy) +_arguments "${_arguments_options[@]}" \ +'*-A+[clippy lints to allow]:LINT: ' \ +'*-D+[clippy lints to deny]:LINT: ' \ +'*-W+[clippy lints to warn on]:LINT: ' \ +'*-F+[clippy lints to forbid]:LINT: ' \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'--fix[]' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--json-output[use message-format=json]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 +;; +(fix) +_arguments "${_arguments_options[@]}" \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--json-output[use message-format=json]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 +;; +(fmt) +_arguments "${_arguments_options[@]}" \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'--check[check formatting instead of applying]' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--json-output[use message-format=json]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 +;; +(doc) +_arguments "${_arguments_options[@]}" \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'--open[open the docs in a browser]' \ +'--json[render the documentation in JSON format in addition to the usual HTML format]' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--json-output[use message-format=json]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 +;; +(test) +_arguments "${_arguments_options[@]}" \ +'*--skip=[skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times]:SUBSTRING:_files' \ +'*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS: ' \ +'*--rustc-args=[extra options to pass the compiler when running tests]:ARGS: ' \ +'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell)]:EXTRA_CHECKS: ' \ +'--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE: ' \ +'--pass=[force {check,build,run}-pass tests to this mode]:check | build | run: ' \ +'--run=[whether to execute run-* tests]:auto | always | never: ' \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'--no-fail-fast[run all tests regardless of failure]' \ +'--no-doc[do not run doc tests]' \ +'--doc[only run doc tests]' \ +'--bless[whether to automatically update stderr/stdout files]' \ +'--force-rerun[rerun tests even if the inputs are unchanged]' \ +'--only-modified[only run tests that result has been changed]' \ +'--rustfix-coverage[enable this to generate a Rustfix coverage file, which is saved in \`/<build_base>/rustfix_missing_coverage.txt\`]' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--json-output[use message-format=json]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 +;; +(bench) +_arguments "${_arguments_options[@]}" \ +'*--test-args=[]:TEST_ARGS: ' \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--json-output[use message-format=json]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'-h[Print help]' \ +'--help[Print help]' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 +;; +(clean) +_arguments "${_arguments_options[@]}" \ +'--stage=[Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used]:N: ' \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'--all[Clean the entire build directory (not used by default)]' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--json-output[use message-format=json]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'-h[Print help]' \ +'--help[Print help]' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 +;; +(dist) +_arguments "${_arguments_options[@]}" \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--json-output[use message-format=json]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'-h[Print help]' \ +'--help[Print help]' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 +;; +(install) +_arguments "${_arguments_options[@]}" \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--json-output[use message-format=json]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'-h[Print help]' \ +'--help[Print help]' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" \ +'*--args=[arguments for the tool]:ARGS: ' \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--json-output[use message-format=json]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 +;; +(setup) +_arguments "${_arguments_options[@]}" \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--json-output[use message-format=json]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'::profile -- Either the profile for `config.toml` or another setup action. May be omitted to set up interactively:_files' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 +;; +(suggest) +_arguments "${_arguments_options[@]}" \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'--run[run suggested tests]' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--json-output[use message-format=json]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 +;; + esac + ;; +esac +} + +(( $+functions[_x.py_commands] )) || +_x.py_commands() { + local commands; commands=( +'build:Compile either the compiler or libraries' \ +'check:Compile either the compiler or libraries, using cargo check' \ +'clippy:Run Clippy (uses rustup/cargo-installed clippy binary)' \ +'fix:Run cargo fix' \ +'fmt:Run rustfmt' \ +'doc:Build documentation' \ +'test:Build and run some test suites' \ +'bench:Build and run some benchmarks' \ +'clean:Clean out build directories' \ +'dist:Build distribution artifacts' \ +'install:Install distribution artifacts' \ +'run:Run tools contained in this repository' \ +'setup:Set up the environment for development' \ +'suggest:Suggest a subset of tests to run, based on modified files' \ + ) + _describe -t commands 'x.py commands' commands "$@" +} +(( $+functions[_x.py__bench_commands] )) || +_x.py__bench_commands() { + local commands; commands=() + _describe -t commands 'x.py bench commands' commands "$@" +} +(( $+functions[_x.py__build_commands] )) || +_x.py__build_commands() { + local commands; commands=() + _describe -t commands 'x.py build commands' commands "$@" +} +(( $+functions[_x.py__check_commands] )) || +_x.py__check_commands() { + local commands; commands=() + _describe -t commands 'x.py check commands' commands "$@" +} +(( $+functions[_x.py__clean_commands] )) || +_x.py__clean_commands() { + local commands; commands=() + _describe -t commands 'x.py clean commands' commands "$@" +} +(( $+functions[_x.py__clippy_commands] )) || +_x.py__clippy_commands() { + local commands; commands=() + _describe -t commands 'x.py clippy commands' commands "$@" +} +(( $+functions[_x.py__dist_commands] )) || +_x.py__dist_commands() { + local commands; commands=() + _describe -t commands 'x.py dist commands' commands "$@" +} +(( $+functions[_x.py__doc_commands] )) || +_x.py__doc_commands() { + local commands; commands=() + _describe -t commands 'x.py doc commands' commands "$@" +} +(( $+functions[_x.py__fix_commands] )) || +_x.py__fix_commands() { + local commands; commands=() + _describe -t commands 'x.py fix commands' commands "$@" +} +(( $+functions[_x.py__fmt_commands] )) || +_x.py__fmt_commands() { + local commands; commands=() + _describe -t commands 'x.py fmt commands' commands "$@" +} +(( $+functions[_x.py__install_commands] )) || +_x.py__install_commands() { + local commands; commands=() + _describe -t commands 'x.py install commands' commands "$@" +} +(( $+functions[_x.py__run_commands] )) || +_x.py__run_commands() { + local commands; commands=() + _describe -t commands 'x.py run commands' commands "$@" +} +(( $+functions[_x.py__setup_commands] )) || +_x.py__setup_commands() { + local commands; commands=() + _describe -t commands 'x.py setup commands' commands "$@" +} +(( $+functions[_x.py__suggest_commands] )) || +_x.py__suggest_commands() { + local commands; commands=() + _describe -t commands 'x.py suggest commands' commands "$@" +} +(( $+functions[_x.py__test_commands] )) || +_x.py__test_commands() { + local commands; commands=() + _describe -t commands 'x.py test commands' commands "$@" +} + +if [ "$funcstack[1]" = "_x.py" ]; then + _x.py "$@" +else + compdef _x.py x.py +fi diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 29912b95703..38935b7d1bb 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -10,7 +10,7 @@ path = "lib.rs" arrayvec = { version = "0.7", default-features = false } askama = { version = "0.12", default-features = false, features = ["config"] } itertools = "0.10.1" -minifier = "0.2.2" +minifier = "0.2.3" once_cell = "1.10.0" regex = "1" rustdoc-json-types = { path = "../rustdoc-json-types" } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 517a51867cf..2a54266676d 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -713,12 +713,16 @@ impl Item { Some(tcx.visibility(def_id)) } - pub(crate) fn attributes(&self, tcx: TyCtxt<'_>, keep_as_is: bool) -> Vec<String> { + pub(crate) fn attributes( + &self, + tcx: TyCtxt<'_>, + cache: &Cache, + keep_as_is: bool, + ) -> Vec<String> { const ALLOWED_ATTRIBUTES: &[Symbol] = - &[sym::export_name, sym::link_section, sym::no_mangle, sym::repr, sym::non_exhaustive]; + &[sym::export_name, sym::link_section, sym::no_mangle, sym::non_exhaustive]; use rustc_abi::IntegerType; - use rustc_middle::ty::ReprFlags; let mut attrs: Vec<String> = self .attrs @@ -739,20 +743,38 @@ impl Item { } }) .collect(); - if let Some(def_id) = self.def_id() && - !def_id.is_local() && - // This check is needed because `adt_def` will panic if not a compatible type otherwise... - matches!(self.type_(), ItemType::Struct | ItemType::Enum | ItemType::Union) + if !keep_as_is + && let Some(def_id) = self.def_id() + && let ItemType::Struct | ItemType::Enum | ItemType::Union = self.type_() { - let repr = tcx.adt_def(def_id).repr(); + let adt = tcx.adt_def(def_id); + let repr = adt.repr(); let mut out = Vec::new(); - if repr.flags.contains(ReprFlags::IS_C) { + if repr.c() { out.push("C"); } - if repr.flags.contains(ReprFlags::IS_TRANSPARENT) { - out.push("transparent"); + if repr.transparent() { + // Render `repr(transparent)` iff the non-1-ZST field is public or at least one + // field is public in case all fields are 1-ZST fields. + let render_transparent = cache.document_private + || adt + .all_fields() + .find(|field| { + let ty = + field.ty(tcx, ty::GenericArgs::identity_for_item(tcx, field.did)); + tcx.layout_of(tcx.param_env(field.did).and(ty)) + .is_ok_and(|layout| !layout.is_1zst()) + }) + .map_or_else( + || adt.all_fields().any(|field| field.vis.is_public()), + |field| field.vis.is_public(), + ); + + if render_transparent { + out.push("transparent"); + } } - if repr.flags.contains(ReprFlags::IS_SIMD) { + if repr.simd() { out.push("simd"); } let pack_s; @@ -777,10 +799,9 @@ impl Item { }; out.push(&int_s); } - if out.is_empty() { - return Vec::new(); + if !out.is_empty() { + attrs.push(format!("#[repr({})]", out.join(", "))); } - attrs.push(format!("#[repr({})]", out.join(", "))); } attrs } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 3e6066c78fb..9066061f1a2 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -262,6 +262,7 @@ pub(crate) fn create_config( locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES, lint_caps, parse_sess_created: None, + hash_untracked_state: None, register_lints: Some(Box::new(crate::lint::register_lints)), override_queries: Some(|_sess, providers| { // We do not register late module lints, so this only runs `MissingDoc`. diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 741d329fb19..db69cf5752d 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -104,6 +104,7 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> { locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES, lint_caps, parse_sess_created: None, + hash_untracked_state: None, register_lints: Some(Box::new(crate::lint::register_lints)), override_queries: None, make_codegen_backend: None, diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 49817f5eb64..89e29d8b59b 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -868,10 +868,10 @@ fn assoc_method( let (indent, indent_str, end_newline) = if parent == ItemType::Trait { header_len += 4; let indent_str = " "; - write!(w, "{}", render_attributes_in_pre(meth, indent_str, tcx)); + write!(w, "{}", render_attributes_in_pre(meth, indent_str, cx)); (4, indent_str, Ending::NoNewline) } else { - render_attributes_in_code(w, meth, tcx); + render_attributes_in_code(w, meth, cx); (0, "", Ending::Newline) }; w.reserve(header_len + "<a href=\"\" class=\"fn\">{".len() + "</a>".len()); @@ -1047,13 +1047,13 @@ fn render_assoc_item( // When an attribute is rendered inside a `<pre>` tag, it is formatted using // a whitespace prefix and newline. -fn render_attributes_in_pre<'a, 'b: 'a>( +fn render_attributes_in_pre<'a, 'tcx: 'a>( it: &'a clean::Item, prefix: &'a str, - tcx: TyCtxt<'b>, -) -> impl fmt::Display + Captures<'a> + Captures<'b> { + cx: &'a Context<'tcx>, +) -> impl fmt::Display + Captures<'a> + Captures<'tcx> { crate::html::format::display_fn(move |f| { - for a in it.attributes(tcx, false) { + for a in it.attributes(cx.tcx(), cx.cache(), false) { writeln!(f, "{prefix}{a}")?; } Ok(()) @@ -1062,8 +1062,8 @@ fn render_attributes_in_pre<'a, 'b: 'a>( // When an attribute is rendered inside a <code> tag, it is formatted using // a div to produce a newline after it. -fn render_attributes_in_code(w: &mut impl fmt::Write, it: &clean::Item, tcx: TyCtxt<'_>) { - for attr in it.attributes(tcx, false) { +fn render_attributes_in_code(w: &mut impl fmt::Write, it: &clean::Item, cx: &Context<'_>) { + for attr in it.attributes(cx.tcx(), cx.cache(), false) { write!(w, "<div class=\"code-attribute\">{attr}</div>").unwrap(); } } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index cd31493bf3f..f6432dc61ae 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -120,8 +120,7 @@ macro_rules! item_template_methods { fn render_attributes_in_pre<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { display_fn(move |f| { let (item, cx) = self.item_and_mut_cx(); - let tcx = cx.tcx(); - let v = render_attributes_in_pre(item, "", tcx); + let v = render_attributes_in_pre(item, "", &cx); write!(f, "{v}") }) } @@ -659,7 +658,7 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle w, "{attrs}{vis}{constness}{asyncness}{unsafety}{abi}fn \ {name}{generics}{decl}{notable_traits}{where_clause}", - attrs = render_attributes_in_pre(it, "", tcx), + attrs = render_attributes_in_pre(it, "", cx), vis = visibility, constness = constness, asyncness = asyncness, @@ -694,7 +693,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: write!( w, "{attrs}{vis}{unsafety}{is_auto}trait {name}{generics}{bounds}", - attrs = render_attributes_in_pre(it, "", tcx), + attrs = render_attributes_in_pre(it, "", cx), vis = visibility_print_with_space(it.visibility(tcx), it.item_id, cx), unsafety = t.unsafety(tcx).print_with_space(), is_auto = if t.is_auto(tcx) { "auto " } else { "" }, @@ -1173,7 +1172,7 @@ fn item_trait_alias( write!( w, "{attrs}trait {name}{generics}{where_b} = {bounds};", - attrs = render_attributes_in_pre(it, "", cx.tcx()), + attrs = render_attributes_in_pre(it, "", cx), name = it.name.unwrap(), generics = t.generics.print(cx), where_b = print_where_clause(&t.generics, cx, 0, Ending::Newline), @@ -1201,7 +1200,7 @@ fn item_opaque_ty( write!( w, "{attrs}type {name}{generics}{where_clause} = impl {bounds};", - attrs = render_attributes_in_pre(it, "", cx.tcx()), + attrs = render_attributes_in_pre(it, "", cx), name = it.name.unwrap(), generics = t.generics.print(cx), where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline), @@ -1226,7 +1225,7 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c write!( w, "{attrs}{vis}type {name}{generics}{where_clause} = {type_};", - attrs = render_attributes_in_pre(it, "", cx.tcx()), + attrs = render_attributes_in_pre(it, "", cx), vis = visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx), name = it.name.unwrap(), generics = t.generics.print(cx), @@ -1415,7 +1414,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: let tcx = cx.tcx(); let count_variants = e.variants().count(); wrap_item(w, |w| { - render_attributes_in_code(w, it, tcx); + render_attributes_in_code(w, it, cx); write!( w, "{}enum {}{}", @@ -1734,7 +1733,7 @@ fn item_primitive(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Ite fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &clean::Constant) { wrap_item(w, |w| { let tcx = cx.tcx(); - render_attributes_in_code(w, it, tcx); + render_attributes_in_code(w, it, cx); write!( w, @@ -1783,7 +1782,7 @@ fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &cle fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean::Struct) { wrap_item(w, |w| { - render_attributes_in_code(w, it, cx.tcx()); + render_attributes_in_code(w, it, cx); render_struct(w, it, Some(&s.generics), s.ctor_kind, &s.fields, "", true, cx); }); @@ -1843,7 +1842,7 @@ fn item_fields( fn item_static(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Item, s: &clean::Static) { wrap_item(w, |buffer| { - render_attributes_in_code(buffer, it, cx.tcx()); + render_attributes_in_code(buffer, it, cx); write!( buffer, "{vis}static {mutability}{name}: {typ}", @@ -1861,7 +1860,7 @@ fn item_static(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Item, fn item_foreign_type(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Item) { wrap_item(w, |buffer| { buffer.write_str("extern {\n").unwrap(); - render_attributes_in_code(buffer, it, cx.tcx()); + render_attributes_in_code(buffer, it, cx); write!( buffer, " {}type {};\n}}", diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 1420d108664..17e2172a270 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -18,6 +18,7 @@ use rustdoc_json_types::*; use crate::clean::{self, ItemId}; use crate::formats::item_type::ItemType; +use crate::formats::FormatRenderer; use crate::json::JsonRenderer; use crate::passes::collect_intra_doc_links::UrlFragment; @@ -41,7 +42,7 @@ impl JsonRenderer<'_> { }) .collect(); let docs = item.opt_doc_value(); - let attrs = item.attributes(self.tcx, true); + let attrs = item.attributes(self.tcx, self.cache(), true); let span = item.span(self.tcx); let visibility = item.visibility(self.tcx); let clean::Item { name, item_id, .. } = item; diff --git a/src/stage0.json b/src/stage0.json index 201f9a0c612..32dc8a2f83c 100644 --- a/src/stage0.json +++ b/src/stage0.json @@ -17,381 +17,385 @@ "tool is executed." ], "compiler": { - "date": "2023-08-22", + "date": "2023-10-04", "version": "beta" }, "rustfmt": { - "date": "2023-08-22", + "date": "2023-10-04", "version": "nightly" }, "checksums_sha256": { - "dist/2023-08-22/cargo-beta-aarch64-apple-darwin.tar.gz": "3a683934876a9794ee7ddbcf7cbf5d804d111fe02b324aa0a0321ec9cdfa8cfe", - "dist/2023-08-22/cargo-beta-aarch64-apple-darwin.tar.xz": "6543aef16521f2d7b4b6eb9e69e003dd8adc3f35a3af7d9d35a6fe8580ccc407", - "dist/2023-08-22/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "c8f7ec0b5b796c5218372ffd717728b3d70b56e6ac9002e351ef165c45455f66", - "dist/2023-08-22/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "d6778d5c515222a53a446ced90fe249613a537538ef2cb5aa5bdd807043907ca", - "dist/2023-08-22/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "c077c1851e22ae9b13bb2cb6227602b57427916a7412a63365711c10a8c05df6", - "dist/2023-08-22/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "a33dbbc00ef63ed18e48e42328f25932d1adf62531ed614c650d5e16ba68efac", - "dist/2023-08-22/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "0a68d407c8301f5dadb99cab2583c4e036539b52f46936995fb3ece4ab009551", - "dist/2023-08-22/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "577bb44224b03d5e50f511176a2a28cc900fd39ca581c7ccdd8c098c1ca48e9a", - "dist/2023-08-22/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "5cfea3f60889c5ea51398427fd34166f94c57718a65556abbc942decdf23366b", - "dist/2023-08-22/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "546b0f2b40edfede8176d68ec8278f7908d606f7f22daf3837fcc5beb5a04284", - "dist/2023-08-22/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "362157d5d3d6ccfd7734f2fbc6e3af28b85c7fec7bb1ca7c82fd5cb786c877c2", - "dist/2023-08-22/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "05c51f3d4479a6f5ad562406e13e33cfd1c193a1d48190210fa2cea48da019f9", - "dist/2023-08-22/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "ead8d3d836f57d6dd02a1643446c9d8a34bf20d64e1bc402181ac8e44848c877", - "dist/2023-08-22/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "ee127cafb6411ef6a4f7cacf2ea90b69b86201f488abd9acb3e82d22fbf56dec", - "dist/2023-08-22/cargo-beta-i686-pc-windows-gnu.tar.gz": "141bfa0ab5bac465ff7cdd91adbc2c293e78cabe458f2d425c6c0ae9b2659d66", - "dist/2023-08-22/cargo-beta-i686-pc-windows-gnu.tar.xz": "dc90fcd745217c237fd570a8ada5c45773066cf58e26bcb87476d5775da32906", - "dist/2023-08-22/cargo-beta-i686-pc-windows-msvc.tar.gz": "07fd85b164a96ef666099fddd03add274e70b11d9343344c627adfcd5c5d4d48", - "dist/2023-08-22/cargo-beta-i686-pc-windows-msvc.tar.xz": "96fcc0fca2870cf3d4ee8ca167b059b9e4d09bb81c88517cccdd1a082f5aa233", - "dist/2023-08-22/cargo-beta-i686-unknown-linux-gnu.tar.gz": "cc9f41d9de949b08964c6604eb75fc2fb3b79d939e9134c54698aaf4fb701dc3", - "dist/2023-08-22/cargo-beta-i686-unknown-linux-gnu.tar.xz": "e5c557c9704ccd9d5d39d3dad5537c3ef152d0b997806f9d9ad0bb91a2ef2fd7", - "dist/2023-08-22/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz": "ce2082ae94f4ab525e500374ac57bc13d32f8ec1a7dd9896bcd9c9d9c5e3eaf4", - "dist/2023-08-22/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz": "ff18d5b23fd463be8461c27a0ee4a4662f1be1d57f69358597faf915ae42d92a", - "dist/2023-08-22/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "4eb7ee68f3932b4519c9c4fb55b8e79ec0a1dd0a40b17cfaf2c0685201280e74", - "dist/2023-08-22/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "95aebdc6896767735e6e8b5e9ec31511fae8281bd258757f25cf9b91230e2a61", - "dist/2023-08-22/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "758fd95274033cd40809988da287a72de426267a2fc399d46992a97177f08264", - "dist/2023-08-22/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "c33c0da9d12fcf19ef145d22f5e8046bcf0df344f325932d620c11620e87b880", - "dist/2023-08-22/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "71485becac68eb4c47627152a1958226a8b1815f8c5121ef8e4886109a1da559", - "dist/2023-08-22/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "c03bc6285489d415c5f520c268430edd5edff9aa2c0bd3ceecacf4e916edc4b4", - "dist/2023-08-22/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "a0f18fe47623d2c30008cf9becdc4dc781b397efe3cf163fd6c4459ae824e641", - "dist/2023-08-22/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "8b67e2d9ff285903baa094a23c1a4bd9a959ab6f99193c93a9c1695fcde6ffa8", - "dist/2023-08-22/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "399ecc7f0d6f0efd9ae2c4bf382ea45f0054f4baa87a415e2f4cb9998fee8f24", - "dist/2023-08-22/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "465b456e2c34f9066f9ecae13f8e6608cc8cebe3218036794996ed9643a20c3e", - "dist/2023-08-22/cargo-beta-x86_64-apple-darwin.tar.gz": "297bdd5712507eb14c39e37128a24960cacab0319a885fef205b5b31978f4100", - "dist/2023-08-22/cargo-beta-x86_64-apple-darwin.tar.xz": "5a4bcf28c268bdc7a863e7c89595522ad0b6a6ebb3ed3408adc57670c76b5d21", - "dist/2023-08-22/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "f70ce4727665a4cc5f9d7dba8ae91a50a5ab9b834b88eb525a8b213fec25624f", - "dist/2023-08-22/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "7349e7a7c20fd38332a27119ef72f09b8b54ac3c7bc937547f478c3f2bc619f0", - "dist/2023-08-22/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "de204ef0efe760c974ed2f58a3cee7532a1275bbb146f7a648360cee5548b2fb", - "dist/2023-08-22/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "b1f77cd3deeb33f2cb24a568c4530e3cffd6194c8f1363baad356d12f3aa6899", - "dist/2023-08-22/cargo-beta-x86_64-unknown-freebsd.tar.gz": "56a2770793bb768684a84b4d99d8287bb04365c4017c3c0802d36a37e33281af", - "dist/2023-08-22/cargo-beta-x86_64-unknown-freebsd.tar.xz": "c9ae52f1212ff635f3300befbd33e575c308e14ff13f0ac30d5d97a3797788f1", - "dist/2023-08-22/cargo-beta-x86_64-unknown-illumos.tar.gz": "8e5ad86ea47eb4901cc7efae579c855a1b3eeee889c7e39fa248eea4465ac6fb", - "dist/2023-08-22/cargo-beta-x86_64-unknown-illumos.tar.xz": "56b3d2363c98537bd70d5e54b1caa446446edfd9fbf3efafd1f1e5ed24985c02", - "dist/2023-08-22/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "61bb143b2a7969fecb28755227e258d2018d8344c5325b2709b3d3b34aeb6bd8", - "dist/2023-08-22/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "6a5ff803aa4e57e35175fb62cea3687f26a55e9ec6bb0e9066fce27c4f4df727", - "dist/2023-08-22/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "2af897d7e7a9b09d645dde71b81a1757e5ebdeaa0291d5c50ddc95d3b9fe08eb", - "dist/2023-08-22/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "41fac61a6ca64490400807dfdcb96076926e61174ec295e8c6534b41e5541e71", - "dist/2023-08-22/cargo-beta-x86_64-unknown-netbsd.tar.gz": "29d324fb629b1aadc67d207b9a4e3156674a762970131399b10a7d8a6de152bb", - "dist/2023-08-22/cargo-beta-x86_64-unknown-netbsd.tar.xz": "a1f216345774fa9b812ebe3f8adaa4e0be152d095e73f289fa70d53d04d27fda", - "dist/2023-08-22/rust-std-beta-aarch64-apple-darwin.tar.gz": "0b45d8fba14876a6323c8adc8368916f8581c868d63c10ab65c0e50f4c021a32", - "dist/2023-08-22/rust-std-beta-aarch64-apple-darwin.tar.xz": "f471a9373c16260f8ed8b467c6065847a788864289d979efb406e99976d14dc2", - "dist/2023-08-22/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "3c0e3226b47a8742061587050048db97843e6c96b08930ada010c07fe06c89e6", - "dist/2023-08-22/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "7739c05595dadb2f021881b0e38d16cfbd705b0a5d31ac395b8fabb2244c8050", - "dist/2023-08-22/rust-std-beta-aarch64-apple-ios.tar.gz": "261b76a4f1ba923477163a868b539781911c7d0bc8dc944530d806eeb6634cde", - "dist/2023-08-22/rust-std-beta-aarch64-apple-ios.tar.xz": "c16102bef9f2d4fdf3c970e2f4e8316b4b2540b43855860be7828209b63c8fb3", - "dist/2023-08-22/rust-std-beta-aarch64-linux-android.tar.gz": "2b6e30df92c4b0c6e464ab59a37865ac91b4c4c4863b06f2bc872d50e2799bd1", - "dist/2023-08-22/rust-std-beta-aarch64-linux-android.tar.xz": "dc8e6fd9d6952969c97af01358034c9ea21182fd5061dc92527aae73b4305bff", - "dist/2023-08-22/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "773e9b29d36ea66a79df8cbfe0ea28ec77b31b1b042563584a1830d814eec269", - "dist/2023-08-22/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "e40c8120fc1850818ffbd151d152b317f7d306fc27d8305bfc376cf55d7a5863", - "dist/2023-08-22/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "c61713b4a7f96a6813f96672811de1d979e732db07c177e7a031bc7a3f22781d", - "dist/2023-08-22/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "1f54408288a19041e58114766263928ec7bee7815c392d25bb1abb5ba2107b13", - "dist/2023-08-22/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "90be82b6fa985c80ee709113c6fae68c0a6055a6b3b63b84e34d98d1f192dfbd", - "dist/2023-08-22/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "a2367d58c58aab240049fd5819f7a1862365c8ccdbdbe43cb94fc74ec4b424e8", - "dist/2023-08-22/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "2525b581645aeb8c07129a7680f7ef76e87af4633fd533ac991fd4868049b72e", - "dist/2023-08-22/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "6dcca8f5b63968ebc6adc066d76a4ef53112f52dd160f135b0a029832fe25060", - "dist/2023-08-22/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "8f07966490ea30beea51e79dd158c41699cc0cc5a5b3cfe211f3452b2d1265ad", - "dist/2023-08-22/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "9cf5cceb96eb5e2bd6bf05ab663a92db637c7af3c58bb921ea75b61b9075ecab", - "dist/2023-08-22/rust-std-beta-aarch64-unknown-none.tar.gz": "41622341bffd5352c4248535f952f721638ad9e0ebc74b5452f41dd6ee261017", - "dist/2023-08-22/rust-std-beta-aarch64-unknown-none.tar.xz": "cd149fd111b65631e2535ae79dc0fbc4ae69d6ebd25d4f91751f76699be74f2f", - "dist/2023-08-22/rust-std-beta-aarch64-unknown-uefi.tar.gz": "b884565f46a93bd75bbb86a5565d5c6fbba925372d00b8fbb5782f6948f1c6ed", - "dist/2023-08-22/rust-std-beta-aarch64-unknown-uefi.tar.xz": "24c4e88d966a7437a9008a02101c0eb333a78fade9e71113491b586b89d80bbe", - "dist/2023-08-22/rust-std-beta-arm-linux-androideabi.tar.gz": "9b47e40f002a9c8134fa96f3c8566a5ccb5543903804254c59d7102dcde59725", - "dist/2023-08-22/rust-std-beta-arm-linux-androideabi.tar.xz": "96d2b153979301ec03b04b2a35052e2be1edf67693dbef43bdd46eec258604ed", - "dist/2023-08-22/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "4f4b08d6773721b796c8a4928061647285e7b06e5a93472fa3578d7f5f96ac83", - "dist/2023-08-22/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "61b62b29fe465550e07e62eddf786086c3a38a7e98c533cc86a689b657061fd6", - "dist/2023-08-22/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "22091e84c962c9291481454825401693b757ee5cc2332a2a3d8a95c93bb8bd6b", - "dist/2023-08-22/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "48e273442bc827d22b177e8b33b1be897da20389ead5cce2de2bb4c936ebc845", - "dist/2023-08-22/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "74c06121290814a97c82a0dbb8160721d27210d58a3a4b1b5818daca8265fc01", - "dist/2023-08-22/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "e15a6a3372901716856e606b369392d270dff0b3293988e5c621b86b384f3dc1", - "dist/2023-08-22/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "e1acaa191877b3debb6b0b59c3aa47937f0113fc3084dbe193944916fd4e810f", - "dist/2023-08-22/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "e94f16fbd527f39c1b9b3f09b977d7fd07547bdcf00385a2a3a235130c82140b", - "dist/2023-08-22/rust-std-beta-armebv7r-none-eabi.tar.gz": "26fb63d61f57b3ae18d5c014430ed9311cad890d88b8560b1094f2d1f674a394", - "dist/2023-08-22/rust-std-beta-armebv7r-none-eabi.tar.xz": "ff7d3403858c5e77da1da28c7ad81085151dc0c004189a331d3e5f3d8a2d93f9", - "dist/2023-08-22/rust-std-beta-armebv7r-none-eabihf.tar.gz": "f7a2b8e8810a19540186d6c9677c487bdac387a94dc6268cbff778dd93ac1b3a", - "dist/2023-08-22/rust-std-beta-armebv7r-none-eabihf.tar.xz": "b4a7c4b6d47dd3a57b1e05afeabb381d624ba1ebf8e789aa10f00a7efc6b329a", - "dist/2023-08-22/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "ce7810ab026a6dea1732d983238df88d21ca94ef10f78a06ec2e366149a6ed76", - "dist/2023-08-22/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "b31641f975c76f63f8c43402db571edb3b335b5dbae1b95c6362d3515d5d28d1", - "dist/2023-08-22/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "75438e97bf98c48c448ea8b96fba21a5f31c919f2da8c8fe048bd54950964ffe", - "dist/2023-08-22/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "c8e1c0f109722ca0918dcba00544692abf8d04a98f86b586b513f06d77111c4f", - "dist/2023-08-22/rust-std-beta-armv7-linux-androideabi.tar.gz": "fdc3d9960d0ff11c03e9c7d0c997aba7a5e480b860410a422035f69359d12451", - "dist/2023-08-22/rust-std-beta-armv7-linux-androideabi.tar.xz": "a2acf41ea19e582b99fcbf56e37eb35e9a309bc6183553cbaf12b9dff976dab8", - "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "81d1d1459526343aa5ab66432eab7dc9557d0c07550cbdafbbf5e402be7eb833", - "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "baa369b9c1df4820f6a8593193bb5376002c79e81dc0681c2329a45ea664a87b", - "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "b9e06051b2705ce2680723e3209ed0099a05cf2f2c71342e1176c16e485ee66e", - "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "5633759d31f4b390f2f9b5f63a0dc7f027a2dbe1241fe7089c06931c360a5f46", - "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "141232d8b440588d181c2d550151879ad6bae9a5af7875e6428bac6e65f6d8e6", - "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "5a82fe0b4e9476b642134071858288e47137aa26de88bc892580ab777650094b", - "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "8d9821484c5bbe8c51d7d54859fb8bc475ea6cc2f863fadb29b2973daf3535e7", - "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "e68834499329dac318fd51c49dd23836c3a6db0eca746869f8dc38d286b5f8ec", - "dist/2023-08-22/rust-std-beta-armv7a-none-eabi.tar.gz": "3353d69ace1f00b7c9d6291144a0ce73edefc5e7498fcb04dcc336edcb3030f4", - "dist/2023-08-22/rust-std-beta-armv7a-none-eabi.tar.xz": "d783d9ab96541426a5cdb2e6e866d0b9b1492e64030011aa3503b6558a4b3acc", - "dist/2023-08-22/rust-std-beta-armv7r-none-eabi.tar.gz": "28b6a82549de0a84323ff7db7104da9f978d2044997681b2ecfd6fbc7e14f806", - "dist/2023-08-22/rust-std-beta-armv7r-none-eabi.tar.xz": "f32aa5def56e3ff083d380de063ff5239f19b2b2ff8648f1f092512a621c8291", - "dist/2023-08-22/rust-std-beta-armv7r-none-eabihf.tar.gz": "f7a57d763304b64e732b46dab90bcf93c712e5e0e5b558ac20033658f4b27e2f", - "dist/2023-08-22/rust-std-beta-armv7r-none-eabihf.tar.xz": "4b74d5e31d3317b0f5519693005ad4c2b3b5093531deae630ab210e177f5b41f", - "dist/2023-08-22/rust-std-beta-asmjs-unknown-emscripten.tar.gz": "691200324336964bb254c98350f6d2c0e545a42d7c6903c76a7812b068cc18b9", - "dist/2023-08-22/rust-std-beta-asmjs-unknown-emscripten.tar.xz": "c2c0ddf54f7dcb60c069117c7139c2c1f57e8f9976447651df2dc9c6507b3ef9", - "dist/2023-08-22/rust-std-beta-i586-pc-windows-msvc.tar.gz": "971a6f1507ac8e47a9e2435f9f0fc5a24f77393c6ae189057bae8cd1ac35d5da", - "dist/2023-08-22/rust-std-beta-i586-pc-windows-msvc.tar.xz": "4af5f8c029f2486073ac4b71725526cc1ef4f3861ba652190cb940273fb2ebbf", - "dist/2023-08-22/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "4676906af1dca83ae3dba5972444ca2b15a755223ae999ec9eb66072125b9d60", - "dist/2023-08-22/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "a2b556a5afe3c69e91eed6d7c6ff31971598eeb35c227b7aca46548b80eff7fa", - "dist/2023-08-22/rust-std-beta-i586-unknown-linux-musl.tar.gz": "e8501702dca37516dd8b567c277b74d19a2e1142ca4c97b881b3428aa3a0bdfd", - "dist/2023-08-22/rust-std-beta-i586-unknown-linux-musl.tar.xz": "a0fd2fcd9a0844fd4063b80189a342d77e6d0c087fb240e28ffbd1b98813ec13", - "dist/2023-08-22/rust-std-beta-i686-linux-android.tar.gz": "ed1445ae201aa69997b850037b98beff658e92a25e860ab525617836de366d72", - "dist/2023-08-22/rust-std-beta-i686-linux-android.tar.xz": "e9be5e895d4e61d3130a502ae3aae8b796028fe8334f161659e90c8feb38d8d0", - "dist/2023-08-22/rust-std-beta-i686-pc-windows-gnu.tar.gz": "41666fb8c03e1403f67f6fb595b1c21c522faac78ed8a9664d476f69825d15ed", - "dist/2023-08-22/rust-std-beta-i686-pc-windows-gnu.tar.xz": "64db89392d6aabdaf39d810f3aa8692a50ad68214db5ae08565462e8ebb1ddde", - "dist/2023-08-22/rust-std-beta-i686-pc-windows-msvc.tar.gz": "cf1e94aa60bd9c273216df658b9cc7c947b3f8b47f1eb4f7df63c07a328ec0a9", - "dist/2023-08-22/rust-std-beta-i686-pc-windows-msvc.tar.xz": "e69ca7df48d927d6fdd40b4de3e5c8d402aac9aa29e7f3cbbd45d3227a4a438d", - "dist/2023-08-22/rust-std-beta-i686-unknown-freebsd.tar.gz": "ec23333c6c7af11adcd8a01c6f722a6103c92a925c197a1f2797780ae1b84c42", - "dist/2023-08-22/rust-std-beta-i686-unknown-freebsd.tar.xz": "301c39d275e3b1d32076364c627cb4953ed200dcf092d4a7925ac662a165ca48", - "dist/2023-08-22/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "722ffca25c78d9a83632773ab0bc36e0b999cea66f767dfd2e15171790c14cc9", - "dist/2023-08-22/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "384ab84d4a8d6fa5429cd5e13a72591a50041e84e846f12105001c1defea08f8", - "dist/2023-08-22/rust-std-beta-i686-unknown-linux-musl.tar.gz": "913a316a08a15b123f6b136335886a4886de0d0cb06f02b14f82b436e34c83f8", - "dist/2023-08-22/rust-std-beta-i686-unknown-linux-musl.tar.xz": "6b440b91f3ba0319d39e73181b173d630098eec1ca76298a13afc69afd156c58", - "dist/2023-08-22/rust-std-beta-i686-unknown-uefi.tar.gz": "a32f3b2e6951316af9c557bc128b95b797586881cefa0f311e6e44779d4c6bd3", - "dist/2023-08-22/rust-std-beta-i686-unknown-uefi.tar.xz": "7deb5fff47eb1ba074f1835f9db54afbc892fce287c0ca2a2590e8bbd6d2168d", - "dist/2023-08-22/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz": "1f825781e403bbfef798a8038c3c4f800b838923b306866b21314902db06701c", - "dist/2023-08-22/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz": "a0b341d9464a8a68c7c395ff051ae384066ce0f97e0a3c50b8adf6ef253ef6d8", - "dist/2023-08-22/rust-std-beta-mips-unknown-linux-musl.tar.gz": "526041c26f3854c25b60969bf45e52d5f3d9e1548f9ea06942c0673434b115bb", - "dist/2023-08-22/rust-std-beta-mips-unknown-linux-musl.tar.xz": "c01d689e540777f8120775d05f93631e31ffcb05bdafcea2d3f1eda8af915f9e", - "dist/2023-08-22/rust-std-beta-mips64-unknown-linux-muslabi64.tar.gz": "f03f3b2767b2775e8f74d190ac1614307f2576c8966eedf710663bf39cf99027", - "dist/2023-08-22/rust-std-beta-mips64-unknown-linux-muslabi64.tar.xz": "9df204a1c45770e72c49e334ccdc47779825b1c0ae979576f40393a6ef05de2a", - "dist/2023-08-22/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.gz": "4892c903b692ea7fbd59d9dacf3ddc886fc0eb771d817c3dc906a875238d1f91", - "dist/2023-08-22/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.xz": "47cb42fd72f3dc488d30a959447698932fcc9499f50fb78e585fd208465c64c4", - "dist/2023-08-22/rust-std-beta-mipsel-unknown-linux-musl.tar.gz": "9d2b04e6ca70c95f157f9e273776bf10979090871307f67b4aed4f8532dd9905", - "dist/2023-08-22/rust-std-beta-mipsel-unknown-linux-musl.tar.xz": "70b260a23b6dc2c43041e15167de8a8589d2e33a65feada35a1ea9c3912db93e", - "dist/2023-08-22/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "a5af9e233e3fd518a2976dc75e5e79555fb9722c9b532f6d6a16c2944968f660", - "dist/2023-08-22/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "5d83a2ae7ebe2242f6370febe19fbf606d0282d57ba2dcb08b483c4cf0fb084d", - "dist/2023-08-22/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "9160571a2ec98b1fc91a10134c842c34c8370ac9990adfcf6368e90a259a4b89", - "dist/2023-08-22/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "be22e907234b415684e90af6c0a3a5ebec114511235f223de0ff2393a929cfe8", - "dist/2023-08-22/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "c73d1e7282d6f85097f13931a7ff5b66bfc807605284b35cacf2a94f9fb4ba0a", - "dist/2023-08-22/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "75e7578497fefdf7aae1b1d0a4e20855cfb06ed2f58bcea5cfdb8e71ba224c35", - "dist/2023-08-22/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "b692e3bc1199f3a7687fd8e5d6224696e56280ea989c402d88ef3da3fad2ee2a", - "dist/2023-08-22/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "61e86b7e3a9f8004bfa1a72cef3bd62eee1ee67964c747d6387d62ab8680f237", - "dist/2023-08-22/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "4d5c1935405d66a7e1a7532b165ffcddd4501fab25f346a0c57d06d7d480f370", - "dist/2023-08-22/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "a581a2224049bbeefdf81ed556960fbabe3d762abbd9ea7765425b2d9d0403cc", - "dist/2023-08-22/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "64d1a7bdd061ac16c585ae035e7b1d2f7b4ee4c2a71f491cf4ec39d3a9cf4904", - "dist/2023-08-22/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "528bd7a62c69a53c3aab2488be12de23199fb0a3aa4b117e1b906af7b06233a9", - "dist/2023-08-22/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "6808261b20282eedf3ae11e6300379ff1dafcb4fc22c0fd7eba5fb8e31fe4a97", - "dist/2023-08-22/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "2782284032eda7797d725e8986bcc5104a28f46e13c9774d8c1b115a3e192cb8", - "dist/2023-08-22/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "2e77b3d53304eae6cc8111d627f8114e4e0b759a66a696937632a95cb213302d", - "dist/2023-08-22/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "a8592a9d233085e65f87f7d5c290fb3bd3a88f9fe3492a5bad4afd5f64def27c", - "dist/2023-08-22/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "8d753ca5922d7fe6782a8dcc366447fd0062784a21f90b210c3946e6eeeb0a0e", - "dist/2023-08-22/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "29fc30370d9b08aaf9b5b36a23c463a494f673a3cc9207dd600dce9498b0c6f5", - "dist/2023-08-22/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "587e51be642bd19528ac7942b2026be31086d12dc81dc8a324ff662328b2fb1b", - "dist/2023-08-22/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "38759bbd4ad799e02c9a3c5947ca5637a2b7b716fe51e986788ea424d3dc0310", - "dist/2023-08-22/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "bf702a5aaed572fc753d27d786ccc9f83664d6b66812d9a9e8b3ba63397857de", - "dist/2023-08-22/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "187906dad30dd2da2f608e3713b6cb2ffaaf491c8109f4d381d4ba9b92e5c82d", - "dist/2023-08-22/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "368835053411c9a9ea8a96813f12724989aa6e00b160f7e75628155b038e06a5", - "dist/2023-08-22/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "f85bf85725ab2ba21e83f5d024cc1c9bccb5fe4b90760f0d34383a0cfca000cc", - "dist/2023-08-22/rust-std-beta-sparcv9-sun-solaris.tar.gz": "1f5632a33b2a94354e062821b5ed5a99810ed0d88c8e8370349c08f4541095f3", - "dist/2023-08-22/rust-std-beta-sparcv9-sun-solaris.tar.xz": "dba0efff671c805c9fa1893bc41a9076436bff1a10f8a5bfa59f5cf01e22cfe6", - "dist/2023-08-22/rust-std-beta-thumbv6m-none-eabi.tar.gz": "3d88eb30d86fe6f486f45bd36d53667f1f886636235f16ac197eb1b6287d228b", - "dist/2023-08-22/rust-std-beta-thumbv6m-none-eabi.tar.xz": "69907d0d70f4a70ca5d28cb9ce19824c6cccc85db206b6b993516980dd469a51", - "dist/2023-08-22/rust-std-beta-thumbv7em-none-eabi.tar.gz": "7bedf1b999e78505f61b409dad228877c92def1df273d58347f8379e8496c0f1", - "dist/2023-08-22/rust-std-beta-thumbv7em-none-eabi.tar.xz": "125b71e59a23077ab7b5e618a48022c467d5e9c4d8e069ed101f9d9634a9e2cf", - "dist/2023-08-22/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "6e396659da4b82f5d66168569f9f8d7283b506d56423916a6e506f489557e07a", - "dist/2023-08-22/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "830981defa1a25be5fb9e7367126802a4f3c50f251bc5b77c80693189a02fe2c", - "dist/2023-08-22/rust-std-beta-thumbv7m-none-eabi.tar.gz": "7d457a6697ea4f0786036791b0769fc581ef44c748ce76717e84f93776af4de5", - "dist/2023-08-22/rust-std-beta-thumbv7m-none-eabi.tar.xz": "03551f2cc2ed4337db19c0b6dd9d7e155988dc7a9d8ed0914ee2fdb4a0e83f9b", - "dist/2023-08-22/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "b209802836c48d3ba7b61b31b1192e2b0eaf38333c307541004c4ff2bbc83453", - "dist/2023-08-22/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "6ec3cbe221f47c412b6f45bb8a3ceb039078462be5a64c3f226595c276aa40c1", - "dist/2023-08-22/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "ef40a875465653f636270fd610def70c2b6d1fd0f3cc5622736ea3d9fccfeb1c", - "dist/2023-08-22/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "79060f7930e9e6ffa1aedfb1f5926b96541fccd4b6e861fc2b9452ef5eca77a2", - "dist/2023-08-22/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "2f33509dc88e1033cbb8b3478b1f7c27065eccb12d54b65a4cdbf331be111636", - "dist/2023-08-22/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "2b92276477d70ea1f02befe72d7a18dc65a1c727dcc5e6ca6e13b0e6d6395648", - "dist/2023-08-22/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "d4e70b2edcbbd81bd68635b067f413de2c4fae69227f70cb78d9a3a90c0cae7d", - "dist/2023-08-22/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "c01c168943c37de7b5c76a49ae329327c45e7eedd65419f47523b26a1ab7aae6", - "dist/2023-08-22/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "7cf03fca058895f05cb583248fd25526f8d54d2607cc484aac63581312162ea0", - "dist/2023-08-22/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "18c8bcd69494f91938e51b8b9cc0dac01533be3b380e5c939096eb35ba7cbe34", - "dist/2023-08-22/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "550440258ce3b993180c285ce9ad363a0e604704d92f924018bff5be68a94944", - "dist/2023-08-22/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "0622611a929a752ecf2c15e6590b6a50ec3fdfa0c7b0fc9f927be3a641ef6fee", - "dist/2023-08-22/rust-std-beta-wasm32-unknown-unknown.tar.gz": "338f5bc7db5648b9b578889bf197fdb120c7c1b6be6a6c41b1e1efab2b19d87a", - "dist/2023-08-22/rust-std-beta-wasm32-unknown-unknown.tar.xz": "6fe28fa351a51f48051010aab7399d9a9bc43b7c60fb9ec5dc8a0323f6ebfcea", - "dist/2023-08-22/rust-std-beta-wasm32-wasi-preview1-threads.tar.gz": "b2d3aeba309f689f20902e41058c400f79f28c9fd8b9b03e4bb0562d1ed9e087", - "dist/2023-08-22/rust-std-beta-wasm32-wasi-preview1-threads.tar.xz": "1d1de7bec3f1744082e0805601a6058ecc39d14064456d9910640a4f1f84604a", - "dist/2023-08-22/rust-std-beta-wasm32-wasi.tar.gz": "45ec2a9e021e7d7b521349a69f85efbac748f8b4abda6212bb0c7273f8053d0e", - "dist/2023-08-22/rust-std-beta-wasm32-wasi.tar.xz": "53bb87e58a84e5afa029d66e5dfe85a6e9ca8b5987c5543af6eb039f052b428c", - "dist/2023-08-22/rust-std-beta-x86_64-apple-darwin.tar.gz": "7acc137790fa64ebe1ff5152abd86f42c643ad6d858f130d1b210d80e98893b5", - "dist/2023-08-22/rust-std-beta-x86_64-apple-darwin.tar.xz": "b9da0c71bbe58c152f39a3f3f79308a49fcbc41944211024c097c156e124a56c", - "dist/2023-08-22/rust-std-beta-x86_64-apple-ios.tar.gz": "915831f0eb14aac95e1416fadaff2b6e0ede3f6968fb5b941986004eb389b887", - "dist/2023-08-22/rust-std-beta-x86_64-apple-ios.tar.xz": "2f7df0e1c43eb73232db1f888d42a639deb4d69e6cb09d11581b23687131f6d0", - "dist/2023-08-22/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "89203b4d908fde29b0fe45d0e1665cbcee7c34d40bdfbce6d97e31b7d608136a", - "dist/2023-08-22/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "9d006df537590eb7d1ec8014348103d3a1d91bd2e627ebcc4f179e83737b4915", - "dist/2023-08-22/rust-std-beta-x86_64-linux-android.tar.gz": "0569509106e866b3a06cc814f928481f0a06859d498440196d5994f23591b5cb", - "dist/2023-08-22/rust-std-beta-x86_64-linux-android.tar.xz": "dac7a334e980f4525b126d33e9609edcc3aad12c3fb011d715a0722d68722dd1", - "dist/2023-08-22/rust-std-beta-x86_64-pc-solaris.tar.gz": "1a34ab28dda35646171ef49f0a7274943bdaa8bc73a15261d16decec2ecb64c9", - "dist/2023-08-22/rust-std-beta-x86_64-pc-solaris.tar.xz": "55a1c71616a85144950cfd92fa7f64471396d5e2c8744bc936c3fcc209bead1b", - "dist/2023-08-22/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "d60cfada9d49c518d90dc0b4040bef383f857a15c6dd9e9983b8fdbfe8b24ea6", - "dist/2023-08-22/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "1102177596d61d23b5f9c9a93ec31fe5d9e0f271d7b49edbd47bcd59f4309ed2", - "dist/2023-08-22/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "0383b7094b6c02266c144223c868ead1edaf55517bdab7e94953f8282bc4420e", - "dist/2023-08-22/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "b2933c0d4600cdbcafd22196b70158721c0a16e864ff292fd6b919fad05355d2", - "dist/2023-08-22/rust-std-beta-x86_64-sun-solaris.tar.gz": "a5b0092f5a045601bed31bdb83dd7f15a332f7579a624f073103c67e7a57af7a", - "dist/2023-08-22/rust-std-beta-x86_64-sun-solaris.tar.xz": "1b0111216a66e7d7ae9b7b996567e932dcf7b50e202bba9281d1dfd704e26e3e", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "cc5e94874385ae0ec2a9a8dbb3efafdb88fc5134cb2be4f378298c9e413e18b4", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "9653bf3ea33bf9502eb90b72c0696af0cc90dea54e9d6e5be97783db3e8286bc", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "6193c991d35a6fc0386b42ff1944f473ffa95012ca2fb43008200d6e5cb78d78", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "3a6c169f6f09d7bda84aaffa348a1b379cfe221b567b67ad35391b9e5e3e34ca", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-illumos.tar.gz": "6299ee2cf0aaa5da48aab83230f55effeebf47a72ccd7dd27b4649629d5f3b6b", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-illumos.tar.xz": "7fc1c33439be25983b4a02c8fa4b783e3187f94f6109e4f4deaf64cb83e124b5", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "76b1bda97f8c56213d4cc39e8d8cde59f0e6a50e9ac209b70b163dc58e346f52", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "14ef16f6c0e545badc8b49b16a9ead85cb4cc2c5e6f74105fea039866eddf111", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "df96bcc3a4f3c6c028fb7252057bbf8367b73061d6cdeb50c4e28211f96d46b0", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "2fa0fae38e0b8633065313fda983503a74c436798bf7f76e1c58ca76e8767491", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "f3ec6da0eded1e8b042e1d4d8de9161e0e1af7998618315aff462892573302a1", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "34ad894da8a3e315832adf6ae7ea7bef486219bd2c1011f849a47092cde958b4", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "3ec57e0485fa7e30ef93939fecf945a24fd47bef044eb0a91652ce6d8c8e5e50", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "02fb83bd1e43d10fc6afd3113c29fdb917e87bff0f039421ce297eff91351bde", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-none.tar.gz": "97f65c1033980d6746d894d9cdef3793029d80e4820295b9a3128df497acb4ae", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-none.tar.xz": "add0537d2ae67b696896368b7aa94f7357b0b6c313097f9eec00bd8f00395a7d", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-redox.tar.gz": "7149623b9e584e41f0f6233aeb05a5aaff57a118cf13c41306e18eaf23de5929", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-redox.tar.xz": "48be526da0d8a8dadeb4e7418a49a07396e132001034282515b859eba7c64d14", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-uefi.tar.gz": "dc14c0faec4cbfa1572102aa5cb2148a58a9c120b40fcd3f092a839f58007dfc", - "dist/2023-08-22/rust-std-beta-x86_64-unknown-uefi.tar.xz": "ac0f60f26c61dcc659aa061be217d161099f404d38dd158f5a6f214143c308df", - "dist/2023-08-22/rustc-beta-aarch64-apple-darwin.tar.gz": "15b0448e87b74a06cc5f21431beb452884b836fb12ea8ccbbaaaa571bbbcd2d1", - "dist/2023-08-22/rustc-beta-aarch64-apple-darwin.tar.xz": "81044b7c60f619f58e5e21da1ccab36c2ce6da364aced4d7df403718f81f4ed2", - "dist/2023-08-22/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "c9f89bdf460cdfd50d11817aa2096de7a25d23be63f8e2e45de460bc7a221722", - "dist/2023-08-22/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "a484613c8b31462985ec6db77343298111e23b9034143fa528ebeccf00bedef5", - "dist/2023-08-22/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "1de5c389e1b60a8b585d35f44228466e1a6977b34c37067f11649aa7e703e1e4", - "dist/2023-08-22/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "424d6192234aa52a21acf10ee4339a9af293bb07e94c9cede67b4f82e421374d", - "dist/2023-08-22/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "bb7ac313a0d2c02eb59061a2d17672f0a73486cb6045e3ab43fef610fe32eacb", - "dist/2023-08-22/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "246e61b5674c3fdd2a11d033a987ead6dcc02b20301db791cfb1f31fe2bccc67", - "dist/2023-08-22/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "5380406b9921dc72ab29afcda33bb3d7dfab593c54ae3d5b3054d7a4f526befc", - "dist/2023-08-22/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "5834f4ab2100b21dd4c1313d2a58bed761543d60a0df5cc9e9d8ce1d086638f2", - "dist/2023-08-22/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "8a9aa58e47d9463aa71952c4c8e214f230c23f7c5a8c55706da02a84e31120aa", - "dist/2023-08-22/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "f832bd965354c1f6a8b982693ce66037a0a4b5eb242a915ab84a1545e90be598", - "dist/2023-08-22/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "da4fca6be3d3df88383cbd5f10556789e5f3bd16e05b4c09543edb14dcc8ce8b", - "dist/2023-08-22/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "d499d8b50ebc3af595872b359e40a41689adfe2a9ea7c7149cf556956370a5ab", - "dist/2023-08-22/rustc-beta-i686-pc-windows-gnu.tar.gz": "6e841881e0393b438e33f3c16f1d24a7036781844ac4eebf79042a33499f0f3d", - "dist/2023-08-22/rustc-beta-i686-pc-windows-gnu.tar.xz": "fe096f5ed90a3a2cf1d5da74c6b8e081b36dd868c4a1b6ea51e4a2e13cee2794", - "dist/2023-08-22/rustc-beta-i686-pc-windows-msvc.tar.gz": "b2b9485f44a0e25aaa56b3d1f82f1f6f224683800688ee4482d1c4025c337d03", - "dist/2023-08-22/rustc-beta-i686-pc-windows-msvc.tar.xz": "2c0e8c9ed8cae5e37ef60f1c5fc55f4370a260bad70cd675fa79d78737f9ca1f", - "dist/2023-08-22/rustc-beta-i686-unknown-linux-gnu.tar.gz": "27ba8f3457389683db058dbbee48b6844b9be5c0fc23711c00300b28a8b4f17b", - "dist/2023-08-22/rustc-beta-i686-unknown-linux-gnu.tar.xz": "2b45ee2cd1cb093bda5154280d0c81573fcdf512841ac5fbc1d1edb460da7c58", - "dist/2023-08-22/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz": "af5f367d0b97719ef4d3606276881015f069338d002ae3af8ad5be58f0778c2c", - "dist/2023-08-22/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz": "a37e870c5e25e9b4c3de30922461f756306424a7f85ab22da84c88b647c56100", - "dist/2023-08-22/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "7df41c44859a38a2652dd3a23524e75157283b276cb621e2c4dd04185841bd61", - "dist/2023-08-22/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "60ece70118660eff11744f6fde293b2dc27bd18a0b7d0cfd81e22c195a13a828", - "dist/2023-08-22/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "50bb7eec6172dde937dc8f9b3d6d3fcced7f896a19eb7fc82f83685a9745e293", - "dist/2023-08-22/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "23eec58bee6d42200d88b16ff0fa3977ab0223578369fc6a69787b5a52c44c62", - "dist/2023-08-22/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "051b46807d53e72a61ee38c28466620b2a03f9b5ebadde3c1c8b6dcbb35b6b7a", - "dist/2023-08-22/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "60382fa331885257998ea7fa93e55e47dddedaab04e962b21330c90ab61f4714", - "dist/2023-08-22/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "24e89e00a5e10256f41dba5f07009c2b2ea82ffdf54b6a9c3fea6b13daa2891b", - "dist/2023-08-22/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "5468061289f37b2014fcc52699ab8979a33ebeffb1c45e23a78607ec7589b3a2", - "dist/2023-08-22/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "34e892a6f59b53b2c7252045de9eabe437ff9d01accb051c74ce7912ab2fddc3", - "dist/2023-08-22/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "9fce7533f11da73efc00b31f5728ca1201c29915673b966840b2e0228f93aa74", - "dist/2023-08-22/rustc-beta-x86_64-apple-darwin.tar.gz": "41602031cb330fe01bd40e17ebf19a3925875f217604bde070e4c8536e971176", - "dist/2023-08-22/rustc-beta-x86_64-apple-darwin.tar.xz": "f19b3fa42e68810fd70a294206fdd8387dc9364fb5cde34cf87ef1ccd6aa6234", - "dist/2023-08-22/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "bbe52f430c7e9fd369341bc3c2931b79d79ee02c68d6a1a91919f5c09fff4e03", - "dist/2023-08-22/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "3f96c6b646bafb6104ce64eab83fd9c75734bd7e8b53b0b6db143b5a44fc1cb8", - "dist/2023-08-22/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "0a70402149eb92027265d5ea27c08fd14b0837a488c210f8ca7386981eea8f54", - "dist/2023-08-22/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "614228860c1f94fce353d279ee8dcb9ad3a7daa7233341c8c8e51035d6dcaefe", - "dist/2023-08-22/rustc-beta-x86_64-unknown-freebsd.tar.gz": "8a28760c696bda3e79306fc68c3c9a7b05b2a8ddc5008876f27029fdcbbc91dc", - "dist/2023-08-22/rustc-beta-x86_64-unknown-freebsd.tar.xz": "b21b5e26ccb28c2bf8a089a6f62abc4d10d6a4aabadf694aff8273150e6e7673", - "dist/2023-08-22/rustc-beta-x86_64-unknown-illumos.tar.gz": "d46020acb9676fc928c50d1042c2db820f27708e8dd7d708cbbe1056f787583a", - "dist/2023-08-22/rustc-beta-x86_64-unknown-illumos.tar.xz": "e92ded96d7663211d513c5dbefa2367d3c2e7ec3d37ff435884c25a2dc8761b4", - "dist/2023-08-22/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "65e7494ba34014b63d43e95662440b4d70c8ba2f43e6a22ada051f31a83c3620", - "dist/2023-08-22/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "960aef4123b24c63427c6d1bd92dda8417126c589def5213d972057d011caae6", - "dist/2023-08-22/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "4cd355a18503b2a3d081f77d9ac07e6cbc4d273b6cdabf4f9f05aef398cc39d6", - "dist/2023-08-22/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "97b5013d624a203c5906f5eaa82c3a47716e1612534698270082e47a06cc13d5", - "dist/2023-08-22/rustc-beta-x86_64-unknown-netbsd.tar.gz": "59da6428300c6b406da96142ada02d0fa9b3f1b5938c457ded9afc8d52c73046", - "dist/2023-08-22/rustc-beta-x86_64-unknown-netbsd.tar.xz": "c549da0eed22ec875603d42152134780f34acc40e4ba9ddd36f4f31e78a17dfb", - "dist/2023-08-22/rustc-nightly-aarch64-apple-darwin.tar.gz": "e80a43c2bbadff8b7976673d94228d7326a6e871cdf12d802f663b2773c6f187", - "dist/2023-08-22/rustc-nightly-aarch64-apple-darwin.tar.xz": "e90eb430d5485ea4f431952a68e6ceb9de8f6b92ccb64675059970b512ba539f", - "dist/2023-08-22/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "b21f280c54b5b0820f48767df4c611b7554c3bc5427194a1fe7e632cab7827ac", - "dist/2023-08-22/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "f2812b599f99858485d91b349a570bacab343db4bc622d8134a9993ce0da7471", - "dist/2023-08-22/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "059d6f34def7e471b9970713bdedf4ed3f83fc3d9b6a6f28e510b5e28d3a9413", - "dist/2023-08-22/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "95b36f95b1e697922b6dceeaceb74da030d436340cb4ba764101c218c3bcb786", - "dist/2023-08-22/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "ffdd8605187f7f6696586b7c7ab38300bb3d119e23726205d7f8a0a0bd102e90", - "dist/2023-08-22/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "7e1df24c13f88a49eae939930a8dceaa6dd6a23c1dbec16e3fa4f18c4bcced15", - "dist/2023-08-22/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "1a36c109a723388c322afa3fb7b7f64c9f38423a3894b8ebcd9aced032ba1bdb", - "dist/2023-08-22/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "f689a7d295e13a14e379efdf0c9a59f6ee5b8d4ee45e21ff68c684575c26e866", - "dist/2023-08-22/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "a60de4bbe5cb6ebb6081ba19d86f586661666cc40c74102a13b54f175930e561", - "dist/2023-08-22/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "b57f05ddd91bce96f61b24a93cbf9ce61bdf82d15976c44427797a0692388cc1", - "dist/2023-08-22/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "ce3ea06a26eb6345c98b7bad9943ce70e67e145ae5dc082e4bfde2c897c1aea0", - "dist/2023-08-22/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "5021ab61e2988e3f2f3a1531609621db7a2e1fc72eeae4338e3d16b40043d769", - "dist/2023-08-22/rustc-nightly-i686-pc-windows-gnu.tar.gz": "3bbf47ed743a313ea3d2def98173d323a13959e1bcfc8cd2f07a86997a0c2f51", - "dist/2023-08-22/rustc-nightly-i686-pc-windows-gnu.tar.xz": "578b6d37a9caca822102b3d484fb6bc32338d9ac72c423f4c1479835db446ae9", - "dist/2023-08-22/rustc-nightly-i686-pc-windows-msvc.tar.gz": "22798dc3d624f06a14908cf18658246045fd321566f786e6f75ce7a0d762a4c1", - "dist/2023-08-22/rustc-nightly-i686-pc-windows-msvc.tar.xz": "0c8d2fa9cb8a5cfab2c51792644c8ca436aef7bfc9d0c1950f9976fc4480f402", - "dist/2023-08-22/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "52a7969782803b0f15debd0df1876e033b05e93506e1d9662a98c0aa175c043b", - "dist/2023-08-22/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "69a79df0344f0279848bdbea5e8158d7a45f6d8c8966ecb5a055be064750d5a3", - "dist/2023-08-22/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz": "2fbd751601bd1cb94f064f4ff00ea1c909db059661524aa49b9e56f5ede07a52", - "dist/2023-08-22/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz": "5d51a4ac70e5b34304cd8dd05333d2d5933977e03e386bbe10cf8e43eec2e5c6", - "dist/2023-08-22/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "73f57e1a2d6056ae14ce6ab5ec7068241acfe59882bc2521de60d11d2dac3ee7", - "dist/2023-08-22/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "82faa86f7d1be9f184eec46a7c135787c37c750bb667f05bd3b872f55fbe2935", - "dist/2023-08-22/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "3f5e3ea359e2f7377b1d44d3cfb8516e23725e919deb5ebb32f96e8612ab2e6c", - "dist/2023-08-22/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "e156e85b6070a5155331eabb3c3de91279a56628b892a313561ed866b9667c93", - "dist/2023-08-22/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "83a9082d158c1093a98c75fdde9f65c729b245cf40cc06d88731e473a9ec0cba", - "dist/2023-08-22/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "61bbaf76b250a6e292d99a65a95127daa6cf0075cbdedf68033cfccd221bf8bd", - "dist/2023-08-22/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "6574e5cfac1a56cc3ec20352eebe6c6bb0825a1060df48893866909fb7005321", - "dist/2023-08-22/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "ad2240a704fca3320dccaa2bbbbe52a5b2df2556967cae4efa40334c36f66a59", - "dist/2023-08-22/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "c319fe1d20e9520b1d6c033cfd04f91286d68637caea7d2e43e335f9d9397527", - "dist/2023-08-22/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "1c52cb26303f89969190c06580206d1f5d511c91c63fccde78e515930f9da4dc", - "dist/2023-08-22/rustc-nightly-x86_64-apple-darwin.tar.gz": "db6e355efddd7aa18f3fec72d87df4b91794c8b8c07236d6d9454d5912c9994b", - "dist/2023-08-22/rustc-nightly-x86_64-apple-darwin.tar.xz": "afbfca7d7c7f8a94575269098f6166729bfb441b657ea77f7de6621e0a9a3f87", - "dist/2023-08-22/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "7bfcbbbfe4adab954e9c70b8ea6bfb9d52116782dcdeb9b5be147430c4f242e0", - "dist/2023-08-22/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "05e7e901fa944075ea20d65d81f80986c51699c2ac5c5a2cfa2e5a07c16f4b0d", - "dist/2023-08-22/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "74d07b4289dd2f382c7ef5881ed24a1f99c44b9805857d15a8d45d0c7fea623e", - "dist/2023-08-22/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "25bb5590a8107f6525c4987291f8f46360ffdf67dd47f7087a2c9e441e20296f", - "dist/2023-08-22/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "727fcc6ee093e8b105560b6f9644451aa5fb5f88e12e883a270a094ee47aa3bf", - "dist/2023-08-22/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "c33d57fc3783bead4c54352ccfa4b4f129e34e16970efdd872b562fe99e1652d", - "dist/2023-08-22/rustc-nightly-x86_64-unknown-illumos.tar.gz": "c1f4fd00eea1e5fcd64e0eecbf7daec3a39d72822b4792c12c3885bb7d34048d", - "dist/2023-08-22/rustc-nightly-x86_64-unknown-illumos.tar.xz": "ba3783813d65a4be685c3720c865365f03b9124938e02be790c438d212fa1bb1", - "dist/2023-08-22/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "7a0365317617af7b18f535f39e2a8da23cd8f1b7ff95be9af1de9b6d4ae461de", - "dist/2023-08-22/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "bdd970bee618fc6299249ec162ab7e38efdf52c77cd431ad9268f327a6f0905d", - "dist/2023-08-22/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "43f5736c02efbc0170d23124976546b3fc03b2a30582c3685cb53f7417359692", - "dist/2023-08-22/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "3abf2518323294fcc0decc9e3f01bf610116b8f42b07fa9d34769bd438ae17f9", - "dist/2023-08-22/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "1dc5af741b22db8bf16ef7eb05821ef0d5b3e518244867a2bba484a773a03b9e", - "dist/2023-08-22/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "4c2e5268a6a4537c67795c89c45a414e9b001068017aff0b6ea73c1b2e9d95c2", - "dist/2023-08-22/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "606431eea9341f6ee2079ef919d34e583678f8f1e0bcd66fa73eea9175996a77", - "dist/2023-08-22/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "b122cc0367be4b5433eba7e1b2ca919ec265cd31c5b1766e4853b947d16268b5", - "dist/2023-08-22/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "094456d974c3bff34b4ea47f159a2e12dc41c0c88ab710debfb63ecba102b6f1", - "dist/2023-08-22/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "e777f86c75261bfcc3dcb2c7e91ad4052a7e6263b59dd78d6e5a50a43cb9de1b", - "dist/2023-08-22/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "82b9bd94ef7065587471716fd7848bdfbe0d0938df7832b035d78274e51598fc", - "dist/2023-08-22/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "d8453e40ca7819830e9ef8bb3c3086a4708479cd01aa3434fa878bbdb0e21cc2", - "dist/2023-08-22/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "17e913c782aef22a021c75c204f04d290f6abfc76ac3c2fc899bf3ba2b96e8e5", - "dist/2023-08-22/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "97b145924a76dc1f0e6d2c18c65725d0bd92308ee21d779ff1d1c3a857221ad6", - "dist/2023-08-22/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "aa36dea771d819ba1f4f2997fb8e38fc02d57da7417bba9354e499c15ab56c6b", - "dist/2023-08-22/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "c5b3ab26ec79e479de1bc93ab60e48c95e6a24931bdaf8c2e9a6508fb8d8253f", - "dist/2023-08-22/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "2639378c9e51ec50ddb739bc18d12ed43e98a5dff1a1e5cfd154c0b91f233000", - "dist/2023-08-22/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "c189e78bae3474c17f693401c9f7e13f064370ecf709e69b62a140e94c772e82", - "dist/2023-08-22/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "b7e175569f174d7422756bc3c312a1dcde78b8563cc96330772b2b7ca6458685", - "dist/2023-08-22/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "0fad29a56dea92b2083d46e9a93d186f32d162461da897e2aca1b94cf8ad259a", - "dist/2023-08-22/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "35ba679d27b08bdbb381a7517b189743e1aaaccc0f0ad33fa6397d53005f1bd6", - "dist/2023-08-22/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "37cfd4697506172d2826b1a047cd1d78e24ad32e1334fd89602a6b2dd45fecc3", - "dist/2023-08-22/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "e6dbb37669c307e235b610aa292691e2f767bafc7c90dca5f9c3db70a782914f", - "dist/2023-08-22/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "1df368db6dcf9bc06ef68e5c56e1961f6fef57c07b2edbdb537c5eeccc315d5b", - "dist/2023-08-22/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "bd3694c1b40d86c5729bdafa5516a827da2d741a04a3f91f955f2d1165177324", - "dist/2023-08-22/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "0ffa91610757b4c8fce43cef6d76b0f47a442dea14dc893581134e8a0237b32b", - "dist/2023-08-22/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz": "92ec1025ed12fabd541530124b08498abf54ad14c22a11a6cd9be54fa330b0f7", - "dist/2023-08-22/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz": "850ab1756cf50b9e56dab7b2dbbbdd0dab9146fa792ce3bd59af0ec5a0c1a4fd", - "dist/2023-08-22/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "02cd3b78627002f26007ece8e64808a58c80bd4362333c1150b4901c73ae6b8c", - "dist/2023-08-22/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "f453e12fad664f6a3c76de94e34ecd4a668cc26bdec982079dc8c57c9fa85c7f", - "dist/2023-08-22/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "92d7336a7e4a6a9e06f72e72b8402af0fe60bc6da7616bcee11e810a5217ec8a", - "dist/2023-08-22/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "08a96d8600357882f7b278c7e65c8be95ec153bd7059c14847b47abb4e27a28e", - "dist/2023-08-22/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "7d80dfaaa65c1237813ca8cc8c52a878d5e4dfb99b6e5051cd679bd31ce3a4ae", - "dist/2023-08-22/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "a76b23cbad7fd5838a6297b9234a5a09cf6adf0cb377910180d30caa6de2696e", - "dist/2023-08-22/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "4f74e990e6d6e2eb80c503794e55f80e554dd2b6bfecd902ccdd19841b8e83d4", - "dist/2023-08-22/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "7323dc37bb3a0ec5979e0e0818aef876010422a539971e7fbbbb39e66bbe5a70", - "dist/2023-08-22/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "cc369508a03517983bcab4f17e391d4074b002d9f3b5ec8729375b345df6cf86", - "dist/2023-08-22/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "465d88c1ca8c5e36a579d48334c60f5ce226eb4c5a851849fe76a7d8ad803154", - "dist/2023-08-22/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "d2cb215423c824355d7d450b8d555c3f7390b08911fbf5114474869d9d8d2fb8", - "dist/2023-08-22/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "d5a4e117f8d3f1a7a88dbd1e1e71fe352fafce10770d6dc1f2644eef591bfad5", - "dist/2023-08-22/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "6601080db240890b1a9b7a2af54c576b2ab112b15b504a3475fa77b0b214b309", - "dist/2023-08-22/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "a40ed6b0fcb5bc909dcbdc93b65024f155792df980a48757b71ae391dbb427cc", - "dist/2023-08-22/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "64c4a913fd398fb49823d7687932c9defc3e4d0312967a21c90e57b5a6e2ea66", - "dist/2023-08-22/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "75e814a65ccd1b3721ff6300b83aebfcd8f402f18e02df230586604cc56efb10", - "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "186928533dc8dc7874c56bb0ce95930d7cd76c9838a9203509c01c3f0d1e88d7", - "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "4bae607aa830e898d77e20397377cad51108843480a76f6d8f076bdc27a69d7e", - "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "1610cd254b57537c592f5d9c8d5522d03a25405db4862c18759001ced85169d6", - "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "2cd850cadef23f7061e88e3aed20cdbcd772badb11792f34110facb681c9846a", - "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "db5b9f91e2350d337c19c07c4f30419ef1a222cb7f9ad1f95c851ad2a78993fc", - "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "b7abfba5b3c7c5b33bd64e5caddab8a62fc7d1298e913323a3712a2af80b01da", - "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "bcaa9389f053f133c1bbf96a50035de0d2c1e4132a9f8deb5edf83da9da75616", - "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "1e2cec2188e9dcbcb23b81a9a0f22eb70143a207438853b702d5d2d90786a92a", - "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "afd7e619f99ebdc2095f3a0db4a55684e1919c2cf145ff3d1e18169e6e868742", - "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "ee05ae0326941d38704abeb44c868a326966f6dbbc3fcc79585a8ca1f84a4b21" + "dist/2023-10-04/cargo-beta-aarch64-apple-darwin.tar.gz": "a684803e2f7a6c5741b89d3cc471544978ca60256e1d9621978eb190c83e6e2a", + "dist/2023-10-04/cargo-beta-aarch64-apple-darwin.tar.xz": "f6b618c037bf5eb84e7e775fb646f1fd37fc175c321faab0c2a5b39eb4553729", + "dist/2023-10-04/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "47178d02b0d92eb0a1ce511a08ced08c5bf21571d2e560d64d7d00f9d7dc8d76", + "dist/2023-10-04/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "4580c08291405a349c384e34f5ccc728956ff169b7c86c528dbb1e4258a08a77", + "dist/2023-10-04/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "31ca3f2a4d11cdae30925f22154d833e1975b622dbc9bfeb73888fa8666d07f0", + "dist/2023-10-04/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "525dc3440d5bc10c29476e5dcf26c82887459b37fa4adb6f0c45d6f955a9b8e0", + "dist/2023-10-04/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "fac19194eb9261b0df166bccc757d77b78f12c015faf4fd02440978a835ac5b4", + "dist/2023-10-04/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "97e9e2970306e3148307f0a90720764bc74a9e161fe9efe09fb3919a6624e22f", + "dist/2023-10-04/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "805d20b6d572cf1fcfa9f036c9af7133284edf5b67c9ac2e635aaf4eae2d07a5", + "dist/2023-10-04/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "b482d11edee594d984c4da214a0d6dd3dd5538eabe6c6a04b8b36ad4d6918b9d", + "dist/2023-10-04/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "f052ee2d6b5f09d63cc43acbc3e13f044d39bc8cd411286b1fd0318802689e3f", + "dist/2023-10-04/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "3a428c893b46f7ef5e893438b48225d633190e2c99e475429a08556e16ed993e", + "dist/2023-10-04/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "cfdf1f990b6bdd43ad0e0b898065637ab422c4ca4489b78f0ed481684bd4c9a4", + "dist/2023-10-04/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "93239e235a34898e959d891f8d70a75e012f35af62f5576d1b2173fce8979d30", + "dist/2023-10-04/cargo-beta-i686-pc-windows-gnu.tar.gz": "a27be9e3c589d8d92a9b4d95fc6684d4f05951f985485cc516359ea600cb9b4d", + "dist/2023-10-04/cargo-beta-i686-pc-windows-gnu.tar.xz": "9339b0ee5395f75ee8ebfeaeb95582e5922e0f3fc268f59d47c2cc110844f269", + "dist/2023-10-04/cargo-beta-i686-pc-windows-msvc.tar.gz": "6bf3edf4612263ed698bb920e946065e964cd4f7fa6e864b029b8593997b1a0e", + "dist/2023-10-04/cargo-beta-i686-pc-windows-msvc.tar.xz": "46cd39b56d8a6d4724a99574907ddb81a6d170ceccca35a9201b8a61bd3e8190", + "dist/2023-10-04/cargo-beta-i686-unknown-linux-gnu.tar.gz": "f99efe464f62d1c11c035c8ee0fe649380522c8fce7273218ff8a818bbc1628d", + "dist/2023-10-04/cargo-beta-i686-unknown-linux-gnu.tar.xz": "32f68b074e6b9ca7bd216d8d924d0b796c3a6ba81b90d8a0ecbd1904a61867c2", + "dist/2023-10-04/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz": "d1b0179d8c8ab0541bfaf7830bafc0d384616785081c0149ebb80d009860261c", + "dist/2023-10-04/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz": "1265182fc1962018c2754359acbc7b7d07860bdd26eb388c8e332786fbbd678a", + "dist/2023-10-04/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "500f736aeea0a5648bd4703b772d9d9077272daf08c334c281d71f9c19150e1d", + "dist/2023-10-04/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "97e40806dfd8921b7c4347d2d6ebadb66dd315c3d30c0ba3e0b30fcc3de9f1d4", + "dist/2023-10-04/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "1bf735bbae45eb55f4156504299d41c169d3d923ca8615e333e181a0e4b744c4", + "dist/2023-10-04/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "2ab0afd75f20e290fac1063ac0ac8cec98f847918360d95326350671d3b0e05d", + "dist/2023-10-04/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "9092667b450f758c39420530a131e87bcf6c911cb3f2b0177ec6fa4dfb7e58fe", + "dist/2023-10-04/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "50417b4be7631069b8059df56f0834fc65951c5057124b681b7a97a00ff774b6", + "dist/2023-10-04/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "cfb8e229f98f43a612bbf0d6d29f42cbfe2ccae4e3ef03fbb0bd7ea4ced10154", + "dist/2023-10-04/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "32059ff422870f3d45f419f7a59de696fff9474aac1bc4ae20a527079b95cf86", + "dist/2023-10-04/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "d14942f7492df24a577464a2929c2251c1493a70d822b7c38b500e559fce18e8", + "dist/2023-10-04/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "f7688d17e33d49f6fe26a0e7d0d24dfa6fa99e3b1703f6b99dddca46f1080c89", + "dist/2023-10-04/cargo-beta-x86_64-apple-darwin.tar.gz": "9da00b7617cf14e3f5f32c6cfc8e0f4b4197747a6864a962dbaa8725279b52a4", + "dist/2023-10-04/cargo-beta-x86_64-apple-darwin.tar.xz": "a3735ff5fd823461eb411d11b1e675fa890907c859e353ec9c239fc85bc5df1e", + "dist/2023-10-04/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "9f98eb4b034acf6ee9315a7067a62668883d25fd95b306c3083feeb56b907ac5", + "dist/2023-10-04/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "93d0653eae1839dda931ba4e26afb32527a59ca3b4502778135cc5d9608bfeb6", + "dist/2023-10-04/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "23f8e3f8abb551e7c71b391b63d5a9514f49e03d89c0bf4877c94bfd9f1f3754", + "dist/2023-10-04/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "1e8c3996be4a94b54df4f1d5d5f514f254963ed479e40885cc943970d9c31ebb", + "dist/2023-10-04/cargo-beta-x86_64-unknown-freebsd.tar.gz": "3761bb7b4fb64fa4791d09b88fac9da690a422d611935f1627ea96dd43b1d229", + "dist/2023-10-04/cargo-beta-x86_64-unknown-freebsd.tar.xz": "d0a2bac9df9073f766ca0ac2a16b17b6ebf870913ca962c063e6cc9967a32ab8", + "dist/2023-10-04/cargo-beta-x86_64-unknown-illumos.tar.gz": "71d42631ac9867750c5ef86061b2ce6ac1fa56dc24eb07fe5fb13a97e2acffa1", + "dist/2023-10-04/cargo-beta-x86_64-unknown-illumos.tar.xz": "72002ff2f148fdd864fbd4a82ec4fe7fb33c6acf7a7186e30ee4a74759f593f9", + "dist/2023-10-04/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "774be8387ae3849a82447cc20b2bd1daf4d42c7a80faaf5090e153f78d96de9f", + "dist/2023-10-04/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "6f6794bf506362614b97d96f10d6d5171676205beedb655636d82e8344a47011", + "dist/2023-10-04/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "c5ef0aa9f422014bf4d1873f09c77818d2de51fd7d6c030b617cd106402a0f21", + "dist/2023-10-04/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "82ece6a6f7eff45d842ba1cd28e3e86ddac0c49fedca3039dac00d01d99a26e7", + "dist/2023-10-04/cargo-beta-x86_64-unknown-netbsd.tar.gz": "42627d918e4dbb692ef45ff162d7eb39e9126dc30f29cb96b787f0029d11e1d2", + "dist/2023-10-04/cargo-beta-x86_64-unknown-netbsd.tar.xz": "de92a4f9f58e728c63d47a39973c2ef396a073a6fa26bdadf0e833cee9722980", + "dist/2023-10-04/rust-std-beta-aarch64-apple-darwin.tar.gz": "150828b9c7e49d7555eaf989dd6fe84b2b30d06145f48b635ad04e893b537311", + "dist/2023-10-04/rust-std-beta-aarch64-apple-darwin.tar.xz": "c1006b9c0c7d0bf104146b52c92f004811988cc8b73474ef690208e78645a348", + "dist/2023-10-04/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "df8cd652323cdf204683789b902f440e8aa614b9950e096837bc3b6a32a58e80", + "dist/2023-10-04/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "f9bdde6063001b69002ad21777eb52b37ce78ea3ce04131cf81b8f40b0e16c84", + "dist/2023-10-04/rust-std-beta-aarch64-apple-ios.tar.gz": "db0362e805a012249fae465b205970035181a43a19a58d87dd475ebdbb986dc2", + "dist/2023-10-04/rust-std-beta-aarch64-apple-ios.tar.xz": "72fd22f528bb211b0d5ac807f590fac72b1698f7d118e1b3507e6994b3896cb0", + "dist/2023-10-04/rust-std-beta-aarch64-linux-android.tar.gz": "f691fd6cf51e9aad3a11c2b613646b06308ef9558fe04f274458b68a742d6efe", + "dist/2023-10-04/rust-std-beta-aarch64-linux-android.tar.xz": "65fc6a17622bcf0039b34699537f233d193b03514c039258395dff2de8ca5197", + "dist/2023-10-04/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "a99e89663dc6ade963dc13b468fc310ad7b8a17e4d417bc210a39feb6413422c", + "dist/2023-10-04/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "120579d0abbd68b692271290ae926f6677f97930ade6861ae71be0033db5437b", + "dist/2023-10-04/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "7663940abb0a080daac14573199e81b3000d80a27dcfd8f3d8c6d295efa1216a", + "dist/2023-10-04/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "59d7eef17b6cc40cf6af729abf173ecc43c03bf38516bf59fe27321db384972d", + "dist/2023-10-04/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "69647628d78604fdbdb830d23f661d31f997d77635ea0c123d1ca0017b18460d", + "dist/2023-10-04/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "93e15186a1ddd33f3cd7737ff5da28bccfd5644c9a579691611ee2e1308cdd4d", + "dist/2023-10-04/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "b8ac97fef649854f78a9290054728f40b90e5ce55dcde7cdd128e2a5a09224f0", + "dist/2023-10-04/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "4b0d7b2bf742425ddf024d7103b8651f662993038f66b9db915713ba8f039540", + "dist/2023-10-04/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "37847cacdcf142fc557bafcfd8b3ed3c9c5532757bf6c06e6493d21356e18f04", + "dist/2023-10-04/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "c64925fcbd6b7f97926fac45d789e70734d3895c46cc958c190815f8cd8f4989", + "dist/2023-10-04/rust-std-beta-aarch64-unknown-none.tar.gz": "a566b9c1784c919317f33678f889a15107fd31a403d50f6cf42036ff14ae507f", + "dist/2023-10-04/rust-std-beta-aarch64-unknown-none.tar.xz": "a1267921d98e56f36937e72a1dcd60624f94de6e9948fd86715f83fb152ff52b", + "dist/2023-10-04/rust-std-beta-aarch64-unknown-uefi.tar.gz": "0fd6a5925d5a69ae7c7f277ab503ddeeef9168ea815492b21a77a07d8e49142e", + "dist/2023-10-04/rust-std-beta-aarch64-unknown-uefi.tar.xz": "8477f0f15e1fd594b05e918f1940ee56a9458353eaac83f355d935ff2971df20", + "dist/2023-10-04/rust-std-beta-arm-linux-androideabi.tar.gz": "63ea0d1311b4c7a10a185dad0f13e53cac6f7de0047b96e6f23f872f84243339", + "dist/2023-10-04/rust-std-beta-arm-linux-androideabi.tar.xz": "9b35c8013417cdd08480640c609c3e0384814944b81e6f85f8741f53a768c944", + "dist/2023-10-04/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "290589b2438e6ef92366d86916d33f19504dbbe7adeb3e8b12786e524080fee2", + "dist/2023-10-04/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "ce39b799f490f0f7c8d166177d6a4174641872d2fbbd80d7d94dadfc1603b77e", + "dist/2023-10-04/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "5def5470a2c06adb70ab6373b35abdb2404987a41ea2b324d8852849540ed503", + "dist/2023-10-04/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "dfa329c8da739dab40cd111d9399ae2e38e7db8f8e07fda64117fa146b3d071c", + "dist/2023-10-04/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "94cbc1d6984b6018c373f5e7fd250f0bd2de4b4767f7f0c61a70c660576faf12", + "dist/2023-10-04/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "ec393c418b2ac3d2c97814b712648a0fd318dcdec381b4a49409dbb59079cb33", + "dist/2023-10-04/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "4765d35d61d4bb0a8d7dd9f2e6e1b17a9c27ac27fe24f111a42aca6b2dfe2fcf", + "dist/2023-10-04/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "07ee14b28ceec5e76f411b607d68cccb3bac17ed708e180081837f2e05c7057e", + "dist/2023-10-04/rust-std-beta-armebv7r-none-eabi.tar.gz": "f5f35b007304d6d25a189f000a89a64cebad035e3ab7d2f1d2225c7063575db8", + "dist/2023-10-04/rust-std-beta-armebv7r-none-eabi.tar.xz": "68ede435cb805a0e7d9c3bf172fda8c20486dcb2ab655cabc5ecfa25f8564955", + "dist/2023-10-04/rust-std-beta-armebv7r-none-eabihf.tar.gz": "53f1586ef3640a35e36d2b3b4caf62e444d43da64d744d99323f9b238fd0981d", + "dist/2023-10-04/rust-std-beta-armebv7r-none-eabihf.tar.xz": "404517420148caad58da5c5903d6b64b00aaef728dc9146f1c85d3675b2f7944", + "dist/2023-10-04/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "333a58268238a43864b65f51d5731c76e43f56f6f7c556057307d36d1c47bfd2", + "dist/2023-10-04/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "fe4ac5283e9025f7ec919d324592a3b88cf8ed02bfb6bd077d46a452af1fd723", + "dist/2023-10-04/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "ce2edf3faf28d92d2ecace77207e0a5b68aacbaf0f202e79503fabf913472f17", + "dist/2023-10-04/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "12df2bab8ce8301e3dc6eca8693b19eafe31894c285c013bc4445596cc93e49a", + "dist/2023-10-04/rust-std-beta-armv7-linux-androideabi.tar.gz": "f15088dd162f584123f07d58303e5aef3ed12a479ad6e351ad9c676c9d7953e1", + "dist/2023-10-04/rust-std-beta-armv7-linux-androideabi.tar.xz": "8ac08cc08e29b8aa4425889b5ed7f309ab98a3af51c66f2a40c5a5c62efbef97", + "dist/2023-10-04/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "d4b8fbf3b3d96e893145aa2868f6a470ad70bd946793fc49c435eb6fc921a00e", + "dist/2023-10-04/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "153c726bc061d8cd01f5c6c1786d12d04e699505a927ad5ee0e385ee1ea9ded7", + "dist/2023-10-04/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "4dfe33527e1c54cd0a9ff653e6c81376a01119bd894f5db47fb7c716464fc876", + "dist/2023-10-04/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "42081a3129ffd33ff6d9bbc10a10f214f909b4700255fa57decf82161e095d85", + "dist/2023-10-04/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "c1693a1887633f4c0baef1bb9910c502df5a70f2deaf00ead2a40d7ad210216a", + "dist/2023-10-04/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "a1f0068e719d231a6c1ec12055b883773584d9fba609f01fdc32a0dc856bd516", + "dist/2023-10-04/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "7568f5a3e65a649f13481afe384cccf54789c99fe74e62365b4922e649a36f2a", + "dist/2023-10-04/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "ad2989860396bc23ca4337887cd9865fa8a4e930d648df50f193330011f2e65e", + "dist/2023-10-04/rust-std-beta-armv7a-none-eabi.tar.gz": "0ed22040479e23cbf3e82087636c6ea30d75139af30db9e95b8ea7847be1184a", + "dist/2023-10-04/rust-std-beta-armv7a-none-eabi.tar.xz": "d182765ec6d63e0fbf2c6af1ecf57c475dda93c03676e8f3958da74aa47fa168", + "dist/2023-10-04/rust-std-beta-armv7r-none-eabi.tar.gz": "cdc524d00fbafccc363b456c32cc6410cefe98d9c1d37c1e5a22db986b600e7d", + "dist/2023-10-04/rust-std-beta-armv7r-none-eabi.tar.xz": "8815ae220f5bf7bced09274a1e17dd0f95e81ef5cbe1938b738298835c47001b", + "dist/2023-10-04/rust-std-beta-armv7r-none-eabihf.tar.gz": "c641416a3d67ca2a9b797d4800e5ac12a688a7af9daaeae10465c13d0f8cdeba", + "dist/2023-10-04/rust-std-beta-armv7r-none-eabihf.tar.xz": "3ce3dde8809d41f51534d9e8fd86f1c5f34b5450a2bdfffdc2d72e9e54af6ef0", + "dist/2023-10-04/rust-std-beta-asmjs-unknown-emscripten.tar.gz": "a3700f29bbf1f7508a438ef7ecf4cfa25acef21bc9205285736f34840932388d", + "dist/2023-10-04/rust-std-beta-asmjs-unknown-emscripten.tar.xz": "7a6927e77caad52d111366712697b3a7e6b3fa904e0a50eb4628b70d5a92717b", + "dist/2023-10-04/rust-std-beta-i586-pc-windows-msvc.tar.gz": "97c5d4837a4e4f019293c4dce265f6d09ddf3abdc7d7ab7f08ce0b62e0278b2c", + "dist/2023-10-04/rust-std-beta-i586-pc-windows-msvc.tar.xz": "f566a6b8083d3a1e0f5cff28a5131af4bce33a1519d7a7e6fb14d7ae349e3150", + "dist/2023-10-04/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "7a344a573529887631387d8e2f3e007653216f959a8f7c543e2c2cfb52673615", + "dist/2023-10-04/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "d6543b8eb696596fd35616fdc839af08f9a386412e7a8344ed92e08d840613cf", + "dist/2023-10-04/rust-std-beta-i586-unknown-linux-musl.tar.gz": "e8790ee297ef2661d8cead7875d3fa511d7ec4be5aac858562ddc107257648d7", + "dist/2023-10-04/rust-std-beta-i586-unknown-linux-musl.tar.xz": "8998fc7c0d7ecb5a06fae1799f2aa044cf3680546461ec9033115476f3acd2db", + "dist/2023-10-04/rust-std-beta-i686-linux-android.tar.gz": "f918380c6e01128fb16a047d6adc7a8fd3cb3c14bd18d25690ebc69c9a8f0f22", + "dist/2023-10-04/rust-std-beta-i686-linux-android.tar.xz": "cafedd439975af0f45894e111b89b03adee21136dd43558cb049608914b0a8fb", + "dist/2023-10-04/rust-std-beta-i686-pc-windows-gnu.tar.gz": "442d40afabdd05fbbe8b8570133dc119da6c6f8396a1cd6879a21b58c570dbbd", + "dist/2023-10-04/rust-std-beta-i686-pc-windows-gnu.tar.xz": "31c86d09c30d670a4915412d3fed90e0bc640f6b359ddb88ecc4c75f50b68b41", + "dist/2023-10-04/rust-std-beta-i686-pc-windows-msvc.tar.gz": "e0b23dd8a1a4805a1d13275e29edef5b5cfd34b271029262b943eda877c074c5", + "dist/2023-10-04/rust-std-beta-i686-pc-windows-msvc.tar.xz": "a954096bc423910cda8816093bcff11a3996d55239c19c3f9285f584057fdcde", + "dist/2023-10-04/rust-std-beta-i686-unknown-freebsd.tar.gz": "84c060e799148378223c56742d9bfef40b15252204f91bd49677083f48fff722", + "dist/2023-10-04/rust-std-beta-i686-unknown-freebsd.tar.xz": "faa471809786a5cef68807de3da9c0c9e0943b7f92014e232ab6693e1b081a9f", + "dist/2023-10-04/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "43ce123cd3f014b33444c853dc91a9921ba9af0b8d52e65c56386b7e300fa595", + "dist/2023-10-04/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "4792bc927d4dc0af996a47c4e82ab37244d0d28052b56abef6dfda60d8e58ac4", + "dist/2023-10-04/rust-std-beta-i686-unknown-linux-musl.tar.gz": "e609884e147deaa8265cd3f9150384d45d43689ba68cfe6e2ca003773d4f31f3", + "dist/2023-10-04/rust-std-beta-i686-unknown-linux-musl.tar.xz": "c27b005cc23453bc2ec9401515fc792d589619119f8f1006d8c9444f1592c1a7", + "dist/2023-10-04/rust-std-beta-i686-unknown-uefi.tar.gz": "e4fb77aefbc3ae63b81019eacfd35b6cee6f801ac2ff397a598d2ddaf84989dc", + "dist/2023-10-04/rust-std-beta-i686-unknown-uefi.tar.xz": "890d607b35053df912d0f3925f8c7af17ef3a66c267f31eadb8aada9b4491b3d", + "dist/2023-10-04/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz": "c07d08b9a17aebf127d01715259f5be3fc8e67d1e4a114a5f7eb9489c36ec529", + "dist/2023-10-04/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz": "27bffe29093dc3ad55cce741607a354035c8a2d40f8480b131c9608fbd9a86d9", + "dist/2023-10-04/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz": "ce7ebda42e41ad68924f2194c1dbb17f2487d2d6426669835e8dca3dc3f0f623", + "dist/2023-10-04/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz": "3564c11a5540b25f6c3ef24f47e64bf88d76aefacab01e0b28b0a48e4c0e9d73", + "dist/2023-10-04/rust-std-beta-loongarch64-unknown-none.tar.gz": "2aa6dfa17a120b2ef4e7899ed32a04e472725404b205739c12bff1829c05c7a9", + "dist/2023-10-04/rust-std-beta-loongarch64-unknown-none.tar.xz": "37cd947a8cc912e9c3fe07fd4b3ed310255cb45321ac48753cb8cbeee8b56fd4", + "dist/2023-10-04/rust-std-beta-mips-unknown-linux-musl.tar.gz": "5dc9a8b4a421a1be0fd4aff1256d98d76aa13ec38b10b0ba7fbb7ae7d0633354", + "dist/2023-10-04/rust-std-beta-mips-unknown-linux-musl.tar.xz": "c4762f98a836bd93c68fbac17c99e443bd05cae9897f3d1d3f6f39388659bfff", + "dist/2023-10-04/rust-std-beta-mips64-unknown-linux-muslabi64.tar.gz": "b1cb089447954c3a9d5244e2f08367db5fbd569eb986dc437cfa70f0dc5a9a6b", + "dist/2023-10-04/rust-std-beta-mips64-unknown-linux-muslabi64.tar.xz": "9d245bcfd07a430725c274504f5c8f80ea71027ca63f4442cdf4e950bb49683a", + "dist/2023-10-04/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.gz": "4bc42a59bb123188ea2cf143b169b5c5c25b1c10e6b9aaaa00fd5292e2cb4e1c", + "dist/2023-10-04/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.xz": "d58b61471e5bf9279b31b6dd15970efac0a7efef95478d46504bb79643641edf", + "dist/2023-10-04/rust-std-beta-mipsel-unknown-linux-musl.tar.gz": "d7982143a43ae7d2de013747558b808cdf5acf146eaadd32ee1f5baf3354b7dd", + "dist/2023-10-04/rust-std-beta-mipsel-unknown-linux-musl.tar.xz": "e48fd58c266991b24012eccf24212bcaa9f2ca76b93cae50b3b48efdb1c3b715", + "dist/2023-10-04/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "918d45e2212b240c975986d6db96b92bba1f51b2d66ec265c3b87dfd338bc548", + "dist/2023-10-04/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "311aed63bdb7316627a362a9606cd5ca680c4f77bbb9abc74998fea09e2b057b", + "dist/2023-10-04/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "6787ea0c089880a7fdbddb8565847597c4a25a19cc54fa7186e0468a377ee75e", + "dist/2023-10-04/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "20b812085cbf0b92cb0b0ac16cf6f3ef21a2b8d43e4185f4170850138361c944", + "dist/2023-10-04/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "41067f3710f1727c5e2410731f15cc72e15633921bc13295bb28096aae9feaae", + "dist/2023-10-04/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "8e771dcb137daf00ed15bf4d33418bc238da1f7352fc2ba3dee941e3af3635a2", + "dist/2023-10-04/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "bd69748bc81f972fb41d1ac5816cab38d810619692e9b2b762bdc346f2c84771", + "dist/2023-10-04/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "90d79aa923e15aee4e9aaed6721db1288712f473263cff3780dc66d7d7cf7b57", + "dist/2023-10-04/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "a1396acdfd52c857969db1ed6dbb3c29cf76f9744e39ee86eda25f7c3b6fb140", + "dist/2023-10-04/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "93fd04c8c70b30dae02c690c1326edf00090b5f22332dcecbfb0130b4288e795", + "dist/2023-10-04/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "a0592ab2d956ed79049548010c21d1043306502df200873ee0ab82185699da8d", + "dist/2023-10-04/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "a304cff2944d1c317940851980a55033f1918c8d4dd52636bc20fb93c0131927", + "dist/2023-10-04/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "46adfdd25bdcd3c8a9fd60cba9cb1c699b49a5c77b4e4d5aa1020c0985f7c6b2", + "dist/2023-10-04/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "c78bf8bc612d14ae2d619aeeba6ce10031113793bdce9ee2554d17fea74cf5ca", + "dist/2023-10-04/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "018d34e11a065100d45b7c529a3de5ddc5912affb74e4978bede24b6995bd394", + "dist/2023-10-04/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "d3d9062f44c575705ebe2a6d1f176a79fb6f0baf7095cd620184cfe69ff57ab7", + "dist/2023-10-04/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "a3edcf33b7241e9e06466c24c6325a1c7b7f2c0ef2107042827154480532ea05", + "dist/2023-10-04/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "d34eabbd010d9c30fb5c07d3bc854d13d629270a679d033a10d5359a3cf14423", + "dist/2023-10-04/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "1efd3a8cc38d94fec1b2f69fc286a5eb25b50eddf8bf2ded9d236456dc8af4f0", + "dist/2023-10-04/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "df58f0a2d80a6580c1f39d8dc59e785d624730a265c107dc35b264f20a6cbb75", + "dist/2023-10-04/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "d139f332dd3a40dae7689a673fc66997f318d690eb0a2b0704344fc2f5c3ed2a", + "dist/2023-10-04/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "fd46fd9ffd848d00ebf11002c40698b443c9ee9e056d342c8ebb28ce9f397d08", + "dist/2023-10-04/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "fd681ec7011de04cf347465594a65fef58882f298e527f22461fb9afc05d353e", + "dist/2023-10-04/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "5400c302976234fb4b952b7fa159ab2ec5fd19c8c7657b41dd7bcf925b59e769", + "dist/2023-10-04/rust-std-beta-sparcv9-sun-solaris.tar.gz": "93208b2ba15339c0d95434bb04e37ec98fc8a13ef9f92cf92fe0ea55b69e15fa", + "dist/2023-10-04/rust-std-beta-sparcv9-sun-solaris.tar.xz": "3a96871a781637bd885b374a30460196eb9cd064d31b269909c155537085e4e2", + "dist/2023-10-04/rust-std-beta-thumbv6m-none-eabi.tar.gz": "2367449493235e192851f8f7f891be6a4c6fa7663fceb04fa6d160380190159f", + "dist/2023-10-04/rust-std-beta-thumbv6m-none-eabi.tar.xz": "71592f9e4cb8f25ba7034fb797b1fb1cdd3cb9d44d12a8dcc0d450e125e89cd0", + "dist/2023-10-04/rust-std-beta-thumbv7em-none-eabi.tar.gz": "53bc65c17358c3645003068b0d9f231e543f7229e6c389b78aa95d32ded4eecc", + "dist/2023-10-04/rust-std-beta-thumbv7em-none-eabi.tar.xz": "0325e27cdfa9d1adcdf6be09515c3b71f8700a06c87579d314a56dd92ecdd82b", + "dist/2023-10-04/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "0810093364e500892abfc716e9ea44c51bb4f3e0d554fb6a5ccc5aa51bbe003a", + "dist/2023-10-04/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "21d2b3ec401dece48893c011e791c04f1233c9f579762ce6ed8ec665aa1747d2", + "dist/2023-10-04/rust-std-beta-thumbv7m-none-eabi.tar.gz": "76912f5ccc8582048be7a8e4800e2068fc395c85a28ba99f7ffd103f4a8cf98e", + "dist/2023-10-04/rust-std-beta-thumbv7m-none-eabi.tar.xz": "85282a5e52b22501b1aa805da1bb41805591d2a9c4aaabf62a2fc2096469dac2", + "dist/2023-10-04/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "0e0ec736578012bb05f6f4c3a2156af0255097d74a31586390d4ba9a64d73021", + "dist/2023-10-04/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "fbf578e9ed1903a14f10231d1d149b9efe701f9fb7ffe96231dfebab6e2de123", + "dist/2023-10-04/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "8f25cce159bc95b8e4678840fc9c0c4d0f6be50c70c54afc8324756e92da0e03", + "dist/2023-10-04/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "72226d027daef70c7b6dc7cacf2cb118e99cf4fa5c9cb7affe2214ae79eff6ac", + "dist/2023-10-04/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "5101557cafc2ae9c7acd05f62259618835bb852802863a268784bcc091fca31d", + "dist/2023-10-04/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "f68fd847bea42413ed67d9160926e25174e9e45037d7bca016d86bcceb40c779", + "dist/2023-10-04/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "abcd1dd5293ff16d4ccebfccbd2ef9954389554eacfa7d80c64a67e1bb550c83", + "dist/2023-10-04/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "24ef9d6f0a7f43c22ece67c6ea52a7df1a704e386d867d8f563f9ab0b1f4fbe6", + "dist/2023-10-04/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "ad415b127acce0ab1ece6b21d12b3bde7b98b0185c8bff9cdad967430081eacb", + "dist/2023-10-04/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "69be4cf95dcf1ca7d2de6f9ce6580a9a30d033839d3629d371b640325fb7a852", + "dist/2023-10-04/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "9d04e4d8314594175458d1cd8ee1fa93e0289fa0b94ab3280224d4b5bcb4ebae", + "dist/2023-10-04/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "cd4292ce22cdc5553e28ad53ed130408de0c7f1f5af0ad2d1e8c06fd74aa3de8", + "dist/2023-10-04/rust-std-beta-wasm32-unknown-unknown.tar.gz": "a7d5382ac87dca13292b816164aae7ecd5b1221d672f2c03b7d236937ab66e3b", + "dist/2023-10-04/rust-std-beta-wasm32-unknown-unknown.tar.xz": "4f165c1f17ebc81875d6d310619c880581a5bfbaeecfa89743f9771894046214", + "dist/2023-10-04/rust-std-beta-wasm32-wasi-preview1-threads.tar.gz": "4ce6dcb79a483cc1c298d19386fe3782429371c7d3a6bfa4f614cceed8f5dc5e", + "dist/2023-10-04/rust-std-beta-wasm32-wasi-preview1-threads.tar.xz": "2b98636f16a3b988ee27cae0915906593e34d4a6475b37370ca541d53aff1ff3", + "dist/2023-10-04/rust-std-beta-wasm32-wasi.tar.gz": "02b684cc228945097c7ba2340fe7c6ca37ad01ad2c4385b70f0c49aa8d6fcc07", + "dist/2023-10-04/rust-std-beta-wasm32-wasi.tar.xz": "68addf98d1fa241ebe10fc9c3d4fdc00f694c5c603dacd6f306cac07802043bb", + "dist/2023-10-04/rust-std-beta-x86_64-apple-darwin.tar.gz": "f49920ef48466960edf9f21bb7c5374bd9edbbc8c5f6c47eb068e5081e3adaf7", + "dist/2023-10-04/rust-std-beta-x86_64-apple-darwin.tar.xz": "b20cffe93d14408618e149c922114061aedadcdb59e65c72bbbb06e378381ac7", + "dist/2023-10-04/rust-std-beta-x86_64-apple-ios.tar.gz": "22cb46613453e6c5a6cffcda03d7a0337b978b64209afec29d4132b121a7b13d", + "dist/2023-10-04/rust-std-beta-x86_64-apple-ios.tar.xz": "bc65c441d62c0d3fe2432a265cacc8f5e871ee9e894b5572f2e1511c4398c173", + "dist/2023-10-04/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "18c6e2495d8be9598e515229e4ea683c1ea2866f9a299dde52ebfbb3d0e1df4d", + "dist/2023-10-04/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "b9f57cd15a15701e0dc77c4b7de1f02444318a338bc176abd7737219746c840e", + "dist/2023-10-04/rust-std-beta-x86_64-linux-android.tar.gz": "b7299cf0a98d7eb7a28ecd57fbdc4fdc8bc6cde32cdaab27e9c5b4e323647908", + "dist/2023-10-04/rust-std-beta-x86_64-linux-android.tar.xz": "ff3190da0a9f11e43bd53b795bea384481026c5d426ac91768e0818a4c35c0ca", + "dist/2023-10-04/rust-std-beta-x86_64-pc-solaris.tar.gz": "2e602b85e49de5efbcc425c33c64bb85dd40cd7fe7b740a8e2953aa193bc4884", + "dist/2023-10-04/rust-std-beta-x86_64-pc-solaris.tar.xz": "e3120a09217977bd0fca8c10909319f1d5b2cf1c3a14d1a0bfa894a25c1dd30d", + "dist/2023-10-04/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "84508811863e1da5bb903fdbc1fe8335e15455469f58f243052b1d8e3885f3d1", + "dist/2023-10-04/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "105de75121b217dafb5b3432bbfcaee0432fc84d17bbfe0d8f6d27a7c9e3ad6c", + "dist/2023-10-04/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "559f9d676c36a236131a73776879103f68b7782ecfbacb7207bc443de44457e7", + "dist/2023-10-04/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "7baa8e4a543211d2235965d681f6d92127f2adc0a51c25d2fbb123715fb512c1", + "dist/2023-10-04/rust-std-beta-x86_64-sun-solaris.tar.gz": "ac20916902c464c9a9ee037b53f90e3b0cd3ec4c7b642deae88dc5f60bf98a8e", + "dist/2023-10-04/rust-std-beta-x86_64-sun-solaris.tar.xz": "c25d29435a43a607ff21204fb109675496229b975fbe879ce88bbb0c290f6cdf", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "8aae13ca12a349bcc0a2eae61543122095266e1fff1e6abd2d53e6f4609574ab", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "c94ec8fc50a4e003b4e4cd3ac3106b9cea0709dcd9d7729f72499744d875fa10", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "e8cf05fa4f01186b6e1810c0e5f8c3f6e5c7efe88cbf2efb6e9d6e4fed2692d9", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "70688ef9098dda4c2c0acb06a4edcf7457ccf5f6ae509edcad89ce1eb9b33fe6", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-illumos.tar.gz": "4ee1f9699c22200beb40523976617b32e097c443bae1201fc64ad3235c8f58ea", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-illumos.tar.xz": "988079564d076c2c49f8eae77069a0636945a980389ae06ed09a90326ddf9f76", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "0897b02e38e01b0c47075c9f2ebe1e8d127193890be499acec84c56e7a04c036", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "746317cab5b1c8676191287077e4a93877c545fbde577c3cc96149aaaec80afb", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "8130a54368f699c26108314690745dc69bcdc572ccedfcb5799728fb902b2ec7", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "c7493f1d747cbd893195a548f23ec9e713694057a15caa86d121fd981cf50ab6", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "6eec43a326e3c26a5f64c0aea25bcef1f890bbd4ec7bdfe9e32ea47641fb5820", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "1bca9c3dafa477ce34e2f58f6625bd3b461ae188468759921db591ec065cd3f6", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "bbb87aabd230f4209df5f63fdb88fb9f7a2f6d0b4e9cd9f9770e2a60881d4442", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "b235872c8041c38321d3e9d9ff3b4fce3ace96493c61af46e47b531bfab0eade", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-none.tar.gz": "d20e50343834f77e39043ab23fe5591bff07bf913bbffcfbc9e618a920fb2043", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-none.tar.xz": "495a4e236f92d2c9ec0ffaee4792e356ee15de447093538f9a34e85c94fd3ddf", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-redox.tar.gz": "de46554c25acc2b3571063da2d63d32337a5c60f71afff96ead0339dedcb7f3d", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-redox.tar.xz": "dea31f24ddd5c5bac73c6bc731f5356232be331fc8cdff80f4fa460266f1f5b5", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-uefi.tar.gz": "7a1f61d37a132fe288652e7679f78c8f36d51a0724102ae39ccf81f0bc9e88bd", + "dist/2023-10-04/rust-std-beta-x86_64-unknown-uefi.tar.xz": "c452f747af508bfa76f27a3ecfdd333c50e9168ced7738fda38ea4e7f1ea904e", + "dist/2023-10-04/rustc-beta-aarch64-apple-darwin.tar.gz": "68aa57ce1a40d955bbc110bbcf1a9a433ef8492d91961658f163eea0f1917de6", + "dist/2023-10-04/rustc-beta-aarch64-apple-darwin.tar.xz": "30063d4818173bd302eecbe204942fc7c7a908a4294cfd3b5670de6a91c5937c", + "dist/2023-10-04/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "e91ae34b35404fd9466b3c4210c4859489b726df6bd1c6b5deda2f54f8243662", + "dist/2023-10-04/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "f5f62ccb98f5340a02ce4ad73cf370692eafb722d89a7dc18d411216dc62d082", + "dist/2023-10-04/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "b9dd02920bcd80f7bf58e5545ec8cfed0763eea657c2903cd21526b6f9ad3891", + "dist/2023-10-04/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "9ac274cd2078ddba5c856e3258862d45b61375f98d326a32505267c4856fa21f", + "dist/2023-10-04/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "ca1accabfd224bcefc1e9726cbb19066e42b3f5eff349c1be837e6adc4b4c63f", + "dist/2023-10-04/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "cd53dd9d96dff348f45ba28ffe68dcdb0fa90b372acc18e3edff9748e0ef6bed", + "dist/2023-10-04/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "3ca0229603110cb4492c2c399da2b57e5084791d8ec84b4cf9557498134362ce", + "dist/2023-10-04/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "f7950c38c09c37a8fb3d521b62185316e85cefcee13ecf6cf86238c03854aec9", + "dist/2023-10-04/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "332e1f2d816e878bcef183485ededaca830f72265c676af2df92e359df608fcc", + "dist/2023-10-04/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "0b88d3083b62f3e212bb2c823c7c2f5491eaed0baed99a031220f6ca115d4b17", + "dist/2023-10-04/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "0b4854c6290e97b4539f55973ccc9f9a4941a07c5b559f94b79490635913cf0f", + "dist/2023-10-04/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "fac86fc193852246947b648e2c725a4e9973d67a8129e66e9df88a91e7403ffa", + "dist/2023-10-04/rustc-beta-i686-pc-windows-gnu.tar.gz": "1ab3eecffe819ee2b4057a06998fce122931f1989dfab260272fc238f5672592", + "dist/2023-10-04/rustc-beta-i686-pc-windows-gnu.tar.xz": "8af88f78bbe66d35013a9b51606c570ade03c10c3e01115340ac62a99ad28ef8", + "dist/2023-10-04/rustc-beta-i686-pc-windows-msvc.tar.gz": "1d9c70146764cce221cc3e8144395541fc0f3b4af1cc4178342cc6c54e9adb6f", + "dist/2023-10-04/rustc-beta-i686-pc-windows-msvc.tar.xz": "5599aec7ac269dd2a03f5c549a50eca656a309cfe4178e097b64f6357f1d38e5", + "dist/2023-10-04/rustc-beta-i686-unknown-linux-gnu.tar.gz": "7b2b59a9e5acaa56d614c68fbe3b9f0e792f75a32e5f7c27b1ffb6d74508a433", + "dist/2023-10-04/rustc-beta-i686-unknown-linux-gnu.tar.xz": "2ed53af655d58300f88bae54967f964959c01f7d39e7198b14ad835392826dae", + "dist/2023-10-04/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz": "720e53352f5388ce0880b3f51b9941c4d7db86a549ae4c624238808438b02ecf", + "dist/2023-10-04/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz": "9fe3dc9d520284e4004c712fd328d86b6e4601283efe0bf519c3386906dd460f", + "dist/2023-10-04/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "d479a5254d2707ddf725b7400ae04c8c68c138a54aa65861ee5f8e6ef107c4a9", + "dist/2023-10-04/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "bf1756fc7b439b338defd1cbdcc1127c364a5ce4248c73f9a5881c39dd6a7bff", + "dist/2023-10-04/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "691e59ad96392bd1b61538fe2bcd8665470d9243a09c372bad93c115092aa5b7", + "dist/2023-10-04/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "3597d20828b23e94934ea8bbd4aafc51e06bd006ff993e95d1106822131403b7", + "dist/2023-10-04/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "24d283898ca2ce98b2ba38a9ac2fd2fb039da21badbe7c2e0c15660cd622a7e4", + "dist/2023-10-04/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "5c927ce64da0e898c03b56677047f087f88eab5c0777b6f07fb5356fb7dfd913", + "dist/2023-10-04/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "e10ef3fafa1dd6bf2c935853bb9289e1fbf85cfb092683b99107f986a2ba0b9c", + "dist/2023-10-04/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "d0fa4adb60babd26da08c8e141f1ce472c0c3111b1c361bb1a28cc65cd83afa7", + "dist/2023-10-04/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "65020cdd2b30795f3a8771fe41176e747bd13f3b948860aefed5675b89c55257", + "dist/2023-10-04/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "233890aaf235832448dbf05f7ac547cc74c53490fd6c9818d7ea673bb6391d35", + "dist/2023-10-04/rustc-beta-x86_64-apple-darwin.tar.gz": "745e29cf4127d5f67c1a663e47755a8cb200a14cbb44a33e5da6d25e11c145a3", + "dist/2023-10-04/rustc-beta-x86_64-apple-darwin.tar.xz": "609f55c6c784caf6978c176ddfe1b2675bd7f23a4ce4ebff98147f0ce58c0cac", + "dist/2023-10-04/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "78e37a161d41f1012896efb345b1e53febc11943e003c3e848106828e2b9337c", + "dist/2023-10-04/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "58baad93c3fd4a9c25472bfb10cea890efc94cc7c7b131d8dbca727bae79491e", + "dist/2023-10-04/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "3e5497aa975297ad9abae5913ab7ffe8a77a40a37cf26d7fbf18410993731ddf", + "dist/2023-10-04/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "157877278bb6b5af2676a61377e4a2b637470c89971e649b3476ec33d2f84987", + "dist/2023-10-04/rustc-beta-x86_64-unknown-freebsd.tar.gz": "923235f207f5477e455e82c1f516fcb1f9281f67c2f4fefdcb8b4a64b651d7eb", + "dist/2023-10-04/rustc-beta-x86_64-unknown-freebsd.tar.xz": "8e298f4524ee23f9f9b7ca00ce8c45c9e1a16d85c19acb4897fcf24ae1e40d8a", + "dist/2023-10-04/rustc-beta-x86_64-unknown-illumos.tar.gz": "e443cd9be3b531b645ad8ef32bb7f91f25fd17bdbd9439f1f77cd8345c13cc03", + "dist/2023-10-04/rustc-beta-x86_64-unknown-illumos.tar.xz": "682f11962582237689f9b8bc75c5a42b7492a26957909d15e919e0871b33b030", + "dist/2023-10-04/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "60faf9e993a2e2ebec1922a485fa63a47a1c4ad9e282928be8c21dd6397efe9e", + "dist/2023-10-04/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "e0a5cee0346f2ec96d14c5aa6b9d26d8d6d8ac80ea852b2df89d2df999c965e9", + "dist/2023-10-04/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "62ad39e3d0ee9eee3d88f3e2e0b151fc9eed8475e2e4b601dea37b8c6990a9c6", + "dist/2023-10-04/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "8946e23ee7e0eec9b519c0a7c0428592c30a605efb6b58109936300b59ac3074", + "dist/2023-10-04/rustc-beta-x86_64-unknown-netbsd.tar.gz": "651b08daca5f9de5c24ff465ee8f93beaa77477b6b54af8f7929d54876ca08e2", + "dist/2023-10-04/rustc-beta-x86_64-unknown-netbsd.tar.xz": "443bc94ae5274c8f42961bd2a297a32ee1d543ee1014d0f6cfce45febfc19c18", + "dist/2023-10-04/rustc-nightly-aarch64-apple-darwin.tar.gz": "2932fbd7dbe55d1bdfe33788d9aae9e40e42e5fc81841b605873cd118a769947", + "dist/2023-10-04/rustc-nightly-aarch64-apple-darwin.tar.xz": "c9bb124d9b5433d0a5fbfe8728fe4db5314b07f6f38617e6c8fa0b263f02b813", + "dist/2023-10-04/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "8b9a4eea2d57230d6dcc867b0564ac7c5b557e4eadfe8198ac253c523e72c00a", + "dist/2023-10-04/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "993f2afb93e5736973eba557ff5e14cebf4836ec02cfbdf2b652f06fce39cce5", + "dist/2023-10-04/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "0e10e13a02462859451cddcb429af9453ac3ba11dbe896d49b008905ec3b0fec", + "dist/2023-10-04/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "be81aa143335be4d36c01ca557128cbff380cdcea72d9df20260ac6d91ac79fe", + "dist/2023-10-04/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "f4300af316cc86ea85fb9775ad488e22e1f36fc10a2c40a55bea26fd1d180359", + "dist/2023-10-04/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "8579fdaf0c89dc6dfb69ef6f9c1c650476c4aa3d6f2664776a453028516366d3", + "dist/2023-10-04/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "bf6cb4c51f515a63e0ab92904c364238dcb889f21148ceffce0c2110238a7fca", + "dist/2023-10-04/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "359a9a8ca14829ef6f530631d8b88eda2fbfd9a7d01a3b9c8e98b121c8470056", + "dist/2023-10-04/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "9508938031c9333accd01cffad43b5ff1c552843cb4d5f5a0f767a3ccf908c01", + "dist/2023-10-04/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "e5d7638eab37ee18b58d50848398cef79d241939e1330796a7678399d395d1c8", + "dist/2023-10-04/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "196c7e12591a22f5c354045bb1f8ad18e8f069191b5d234fac3490d4c0782839", + "dist/2023-10-04/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "d01560008ec3c254b5ec1c4f9b4b707b7e60d4c7eb1560a2e95efd9fd681a63f", + "dist/2023-10-04/rustc-nightly-i686-pc-windows-gnu.tar.gz": "13987991229171f65295f901451bc735d5b38737c012150c7d912a9dbb627136", + "dist/2023-10-04/rustc-nightly-i686-pc-windows-gnu.tar.xz": "de3b82265e5157b0fe36ba0686b4dfaf9b697594ba50c0697d1d261812bddd30", + "dist/2023-10-04/rustc-nightly-i686-pc-windows-msvc.tar.gz": "aa2292fbcd0ea65407e5cf47924616a90762ca4750535c3e980b9057623bd896", + "dist/2023-10-04/rustc-nightly-i686-pc-windows-msvc.tar.xz": "063fcf503b76f1ae1ed7278a01c61e12bef4aa6d5e69ddec751986dfc7038b27", + "dist/2023-10-04/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "cb0a6e9cfbf7a2869818fe16c853127e4d7cafb69cda01d7737d30476f7d9b49", + "dist/2023-10-04/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "0057ecebc5d9e12f6ef8d0c0ea737b7694507b9c7a8ce0e6e0d323acd0a39b3e", + "dist/2023-10-04/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz": "b38717c03d77eb019262ea3a82e7d91f620170bcb1f05717f8e5dadfac1df483", + "dist/2023-10-04/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz": "4e6a0e9d35101983388772f77ac0fc0714f3025d670c649e6050fb50ca031738", + "dist/2023-10-04/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "1ea0bd0e5070fa590dc2301b6f41a54b9895b0fd688d9c6f37d77d0b6bbef8ee", + "dist/2023-10-04/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "6666cc6e04743127cd63ec7c8fe1e9fb7882222778471ea1368bbab4adce903a", + "dist/2023-10-04/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "60c4c413d85f86de2709e4b9ab4c0e25bb6e99da3e10cc68eb2b3864a5d60e18", + "dist/2023-10-04/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "8569bba6344da9ceb87d53c3d5664d442a1251621625f7b332c4a6f4cb93643a", + "dist/2023-10-04/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "016f8daba0a904e185075840c55f477bab7c91a8b6ca1aee936074f01adb2b44", + "dist/2023-10-04/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "573286e527de43850a25b2c03b61d89fc97437ceacc9f5b3be3a313c9175027e", + "dist/2023-10-04/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "d03339ef02057584100232a6def4a9b80f13b9d242fe57fa47c0b18e84f3c56f", + "dist/2023-10-04/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "2e5ceb85b2612164e1727471a775d5ca1924f92327deddce0d1509c5a87e4bb9", + "dist/2023-10-04/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "b991507575a08b993508ee4c7ac065f3f1983278a457c141ffbfb15b46ae25c2", + "dist/2023-10-04/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "155a4e360eeae301379200415820a6f9c53d3923943d791a3e802ef8083494c4", + "dist/2023-10-04/rustc-nightly-x86_64-apple-darwin.tar.gz": "0ae7a68d86c72f42e3a98737abe466ad88a6be92cb17994b26fc2a495abacd2e", + "dist/2023-10-04/rustc-nightly-x86_64-apple-darwin.tar.xz": "5e2b0a191b34e133ca9e0d883714bea46dc0f6381c9e5ee145851bba799bf7db", + "dist/2023-10-04/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "62e5b0dae1aa25488dab73869da8ed2425114b778adc55db6c6c6b9f77c67d7e", + "dist/2023-10-04/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "5494b11d55bb36ae0536b534796870a0ad8e2a427f64a21418d5bcc2d0f27ab9", + "dist/2023-10-04/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "38b8add3755f62016c40ac84ad3b7085b6058e40768b40e2df672ea4c5d3e91d", + "dist/2023-10-04/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "e511c5e3adfffd33e6dd3cd9525409366f3b54ebb1b3a7f2c09cb7444e678006", + "dist/2023-10-04/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "54190bb432f9dbc4fb414ff40a5e8a5668b8aa343599b4e4b28f7a2e9fc0fa3b", + "dist/2023-10-04/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "7c260043c68b31484f3d415d43ad8bd702f642cfc5050e09ea6b9bb7fa108020", + "dist/2023-10-04/rustc-nightly-x86_64-unknown-illumos.tar.gz": "7cc87c2a5f801a1023688cc6bbecfa0c4c072108b4edcf4afea5df059ef1c2cc", + "dist/2023-10-04/rustc-nightly-x86_64-unknown-illumos.tar.xz": "b21f227d6b8c4c8847db2e3299613a86b13c95bff4f17c7055e1c0d46721fbc6", + "dist/2023-10-04/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "52b372926f5f72a711c36da67a09dfd8d4c9e819b76917053865cce5bc603732", + "dist/2023-10-04/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "499a3aa2baff90e710e2aa9d6be421569119ac90b484093ec38717da1fea3142", + "dist/2023-10-04/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "dc43a1ff5639479cef66778baf3a61ccee67b1aba57dc24a81a0d2f35b24b3ad", + "dist/2023-10-04/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "0f953831e44c7084c86f393cfa3a3b3a0ea8aa2de3a0f7701094683f491c4a6b", + "dist/2023-10-04/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "e636cdb58be6fc3d97387121c404d02772c5a7519f0f001f1c9ff282acdaead4", + "dist/2023-10-04/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "79db9632154590294cd0a9f1229b95ec82163a278b3011e25f2fb86c8af6d894", + "dist/2023-10-04/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "0cde181bc0e9af1eb2813aea3ada3333974eaa85227eab12eaeffe026fe7f31b", + "dist/2023-10-04/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "0aa47b92b78591f522c5d5b4109b1a0fcb4489ceeb3a9014d3f71dc76bc00a6e", + "dist/2023-10-04/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "30ac919cb1eec11a22d96ab32debddf9ee91e776d0edac25fd2c71421145d77c", + "dist/2023-10-04/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "55d800eab787c0bb1d41def853b1a48ab54c2e6cfd6b118e905ec283cc1814eb", + "dist/2023-10-04/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "9e3ae2cbc37307c47c78c953cb2703daddd46b6df44cc61c2b3cf43921c5b03c", + "dist/2023-10-04/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "6812bf2f1ff86bce8bc82cf2ea2f29171fced04b9ca89cfc43121824c4d15eda", + "dist/2023-10-04/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "99ee18898dde1821751cc06eead4d53208d66d98c7f95e8122c7a1161924aaea", + "dist/2023-10-04/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "f65c4577aad313101a6b22f55d777a76db31f21c6467f25eb1d8775a484256ba", + "dist/2023-10-04/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "94b76e626d2460f6701d5c16dc91d633a8c88b0f2583f4996b1173709c29c8cb", + "dist/2023-10-04/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "d63186fe9980b884f375f8ea44ea2e4e8493529047a7035c49c9007261310d8d", + "dist/2023-10-04/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "04e20827f34cab6f259686decdec4df335a8bfa2846a46fc83bee1d65b39ee15", + "dist/2023-10-04/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "f46798ddac7d5b3cafaba54b0fa561ff618f7b931cba4b59eaf2f38e5a60b720", + "dist/2023-10-04/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "3d2b5974f820e976c890300755efbcebb4b14558bd9824bc66d9ebf1dc33de7d", + "dist/2023-10-04/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "ce148b424ce7122fb2330c9911fdb134a67b7365dbd10fff182bd70517ea39e1", + "dist/2023-10-04/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "369278645833248dad11a65a886791134880e26bf0a35ff9462913a355fffb90", + "dist/2023-10-04/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "995727a9213386e7e02d27a3d2f99f5beda5fc0469fccc5736b92ecb4e317ba6", + "dist/2023-10-04/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "92da2162ef18033e68593617613ac11d9ba16bda81a0a685a89fcbd80a815994", + "dist/2023-10-04/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "abca8c7e31afc80ea515c92a7e12a8d6d0af6d41d5f18caeba74a1cd5372876c", + "dist/2023-10-04/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "e755ab5413fa52013cc00df1d8cda68c5b3ef1e99d1d964259d5b002f293e8b2", + "dist/2023-10-04/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "1100241ea39bc177140c458a12174b54af5d569000f59c9791ee8c6497fd4fe6", + "dist/2023-10-04/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz": "5ac4fe7bb0f596cd8565d1edef6f1696043c698c90f5562f5d4a94fca26021a6", + "dist/2023-10-04/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz": "9ecf3bac557d64bd467f9213959e8b1a361041e5a98552a448936fd2903b334d", + "dist/2023-10-04/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "71bbdb6c608d2cdc60619dc2acd7bc7e35e9a20e5e02a633b224b124438a7cb6", + "dist/2023-10-04/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "2d3af87b5c6e0ea524cde039a6deb0b014ca103e4183602b47aedb5bfb97ff9d", + "dist/2023-10-04/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "e3678dc35f3dede5d6fc5e75eec6f19990e4a8b034163c4ef79eb522e654f6f3", + "dist/2023-10-04/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "da9ed66ae0021c2cc16d70a29151963149a433fd4a2a299a45d7cd23556fc58f", + "dist/2023-10-04/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "8a08e5a3d5eea3f414e7b8ed939793ce02f843a60dadf0e4d6eb62e8265fa20c", + "dist/2023-10-04/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "68441252ba1e058023cd480e431e04d755309c1acd7330d49a20c0aeefb1ceac", + "dist/2023-10-04/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "305f24d9813129ce07117dff8cf0de42aff539c7a89df58c2a11f7056594a702", + "dist/2023-10-04/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "beca739e374e20d15a3a16240a801662c42ef135eea5311d8bae7335bf27634c", + "dist/2023-10-04/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "c33dc1b858ad79f2ef89159f40b893d071bd54b1891868064bd210fa2ab1c917", + "dist/2023-10-04/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "0929169a91b4d66058e251ebf7c8bbeb73e3859600158afeb9fcdedd4de84168", + "dist/2023-10-04/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "13684516018f9c56c504793b4d110610f6f8c4a2a1624c63630a12927a9b5b29", + "dist/2023-10-04/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "50686ab2eeeb73d51830b8f19c76a615eec1b17df8f34ddbcbee6458fc51832d", + "dist/2023-10-04/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "315a87aa3fbbc7594d64b4771d105961144f9937c9c1b33991de4ff33c186bd6", + "dist/2023-10-04/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "289c99380cfb2933d5c85b20f7f38e4a61de2c3ce3640ca45a81eb68a7005b72", + "dist/2023-10-04/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "81f689344b8d0d2312790109c18e206849906bcee5bb167c9a07632c1ba71eaa", + "dist/2023-10-04/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "6f17e1e8327cb470c00e58acb8f4b076aa8989c98bcbb0c55867dd6ba1f436ae", + "dist/2023-10-04/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "93e0ccbe7484ee679c4cefa80e46d76c0adfe93f0b52b34ba80cefbde69845b9", + "dist/2023-10-04/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "4c9fde270df24fbca4286d42577d454fab9aa3cc7abec2f8eb4fce359162d8ad", + "dist/2023-10-04/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "e6d4e9b727c7c61a28dbfead22492c7503c4b5d05b41e2991eb9e3551365d440", + "dist/2023-10-04/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "30db9362b5f7eb09ba8ac2050cb98599fb352b332bf3e5c94ad6bc182fe9f294", + "dist/2023-10-04/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "348b94f9020c65fec79a36c6044857a7e897164f1b2a4250e807f258efe99e1b", + "dist/2023-10-04/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "2914983968c484e4e74cee620764aeb476445b1e324253c5087354dbb95a0132", + "dist/2023-10-04/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "0ab0a77a8fadc6cc4e21238cb9487bf5e3b6085663351b2b3c429038621ad83d", + "dist/2023-10-04/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "a992de62c67d56889e11dc7c5401729d8658c3e50365037b4bd975624122dec5", + "dist/2023-10-04/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "e9ab091b5bf9d307164b8c774f98912a0a8282f98e6d9528569acb2dcf29a10d", + "dist/2023-10-04/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "d9421dbbb9b995b6df1144cebf0d6b10fc4a91414b97d66b28335e78b8859d5b" } } diff --git a/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed b/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed index a50fa0ccf6e..fa117aaddcd 100644 --- a/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed +++ b/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed @@ -1,6 +1,5 @@ #![warn(clippy::implied_bounds_in_impls)] #![allow(dead_code)] -#![feature(return_position_impl_trait_in_trait)] use std::ops::{Deref, DerefMut}; diff --git a/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs b/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs index e74ed4425b8..c96aac151a7 100644 --- a/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs +++ b/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs @@ -1,6 +1,5 @@ #![warn(clippy::implied_bounds_in_impls)] #![allow(dead_code)] -#![feature(return_position_impl_trait_in_trait)] use std::ops::{Deref, DerefMut}; diff --git a/src/tools/clippy/tests/ui/implied_bounds_in_impls.stderr b/src/tools/clippy/tests/ui/implied_bounds_in_impls.stderr index 72dc2a183a3..fb44f2aba17 100644 --- a/src/tools/clippy/tests/ui/implied_bounds_in_impls.stderr +++ b/src/tools/clippy/tests/ui/implied_bounds_in_impls.stderr @@ -1,5 +1,5 @@ error: this bound is already specified as the supertrait of `DerefMut<Target = T>` - --> $DIR/implied_bounds_in_impls.rs:13:36 + --> $DIR/implied_bounds_in_impls.rs:12:36 | LL | fn deref_derefmut<T>(x: T) -> impl Deref<Target = T> + DerefMut<Target = T> { | ^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL + fn deref_derefmut<T>(x: T) -> impl DerefMut<Target = T> { | error: this bound is already specified as the supertrait of `GenericSubtrait<U, W, U>` - --> $DIR/implied_bounds_in_impls.rs:30:37 + --> $DIR/implied_bounds_in_impls.rs:29:37 | LL | fn generics_implied<U, W>() -> impl GenericTrait<W> + GenericSubtrait<U, W, U> | ^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + fn generics_implied<U, W>() -> impl GenericSubtrait<U, W, U> | error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, V>` - --> $DIR/implied_bounds_in_impls.rs:36:40 + --> $DIR/implied_bounds_in_impls.rs:35:40 | LL | fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {} | ^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + fn generics_implied_multi<V>() -> impl GenericTrait2<V> + GenericSubtrait<( | error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, V>` - --> $DIR/implied_bounds_in_impls.rs:36:60 + --> $DIR/implied_bounds_in_impls.rs:35:60 | LL | fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {} | ^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericSubtrait< | error: this bound is already specified as the supertrait of `GenericSubtrait<(), T, V>` - --> $DIR/implied_bounds_in_impls.rs:38:44 + --> $DIR/implied_bounds_in_impls.rs:37:44 | LL | fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V> | ^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + fn generics_implied_multi2<T, V>() -> impl GenericTrait2<V> + GenericSubtra | error: this bound is already specified as the supertrait of `GenericSubtrait<(), T, V>` - --> $DIR/implied_bounds_in_impls.rs:38:62 + --> $DIR/implied_bounds_in_impls.rs:37:62 | LL | fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V> | ^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericSubtrai | error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, ()>` - --> $DIR/implied_bounds_in_impls.rs:48:28 + --> $DIR/implied_bounds_in_impls.rs:47:28 | LL | fn generics_same() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, ()> {} | ^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + fn generics_same() -> impl GenericSubtrait<(), i32, ()> {} | error: this bound is already specified as the supertrait of `DerefMut<Target = u8>` - --> $DIR/implied_bounds_in_impls.rs:52:20 + --> $DIR/implied_bounds_in_impls.rs:51:20 | LL | fn f() -> impl Deref + DerefMut<Target = u8>; | ^^^^^ @@ -97,7 +97,7 @@ LL + fn f() -> impl DerefMut<Target = u8>; | error: this bound is already specified as the supertrait of `DerefMut<Target = u8>` - --> $DIR/implied_bounds_in_impls.rs:57:20 + --> $DIR/implied_bounds_in_impls.rs:56:20 | LL | fn f() -> impl Deref + DerefMut<Target = u8> { | ^^^^^ @@ -109,7 +109,7 @@ LL + fn f() -> impl DerefMut<Target = u8> { | error: this bound is already specified as the supertrait of `DerefMut<Target = u8>` - --> $DIR/implied_bounds_in_impls.rs:63:20 + --> $DIR/implied_bounds_in_impls.rs:62:20 | LL | fn f() -> impl Deref + DerefMut<Target = u8> { | ^^^^^ @@ -121,7 +121,7 @@ LL + fn f() -> impl DerefMut<Target = u8> { | error: this bound is already specified as the supertrait of `PartialOrd` - --> $DIR/implied_bounds_in_impls.rs:74:41 + --> $DIR/implied_bounds_in_impls.rs:73:41 | LL | fn default_generic_param1() -> impl PartialEq + PartialOrd + Debug {} | ^^^^^^^^^ @@ -133,7 +133,7 @@ LL + fn default_generic_param1() -> impl PartialOrd + Debug {} | error: this bound is already specified as the supertrait of `PartialOrd` - --> $DIR/implied_bounds_in_impls.rs:75:54 + --> $DIR/implied_bounds_in_impls.rs:74:54 | LL | fn default_generic_param2() -> impl PartialOrd + PartialEq + Debug {} | ^^^^^^^^^ @@ -145,7 +145,7 @@ LL + fn default_generic_param2() -> impl PartialOrd + Debug {} | error: this bound is already specified as the supertrait of `DoubleEndedIterator` - --> $DIR/implied_bounds_in_impls.rs:88:26 + --> $DIR/implied_bounds_in_impls.rs:87:26 | LL | fn my_iter() -> impl Iterator<Item = u32> + DoubleEndedIterator { | ^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL + fn my_iter() -> impl DoubleEndedIterator<Item = u32> { | error: this bound is already specified as the supertrait of `Copy` - --> $DIR/implied_bounds_in_impls.rs:93:27 + --> $DIR/implied_bounds_in_impls.rs:92:27 | LL | fn f() -> impl Copy + Clone { | ^^^^^ @@ -169,7 +169,7 @@ LL + fn f() -> impl Copy { | error: this bound is already specified as the supertrait of `Trait2<i32>` - --> $DIR/implied_bounds_in_impls.rs:107:21 + --> $DIR/implied_bounds_in_impls.rs:106:21 | LL | fn f2() -> impl Trait1<i32, U = i64> + Trait2<i32> {} | ^^^^^^^^^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL + fn f2() -> impl Trait2<i32, U = i64> {} | error: this bound is already specified as the supertrait of `Trait4<i8, X = i32>` - --> $DIR/implied_bounds_in_impls.rs:122:21 + --> $DIR/implied_bounds_in_impls.rs:121:21 | LL | fn f3() -> impl Trait3<i8, i16, i64, X = i32, Y = i128> + Trait4<i8, X = i32> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/unused_async.rs b/src/tools/clippy/tests/ui/unused_async.rs index 71722e9afd0..7ec8a3adb4c 100644 --- a/src/tools/clippy/tests/ui/unused_async.rs +++ b/src/tools/clippy/tests/ui/unused_async.rs @@ -1,5 +1,4 @@ #![warn(clippy::unused_async)] -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] use std::future::Future; diff --git a/src/tools/clippy/tests/ui/unused_async.stderr b/src/tools/clippy/tests/ui/unused_async.stderr index 077e8cacce1..c97a76a55cb 100644 --- a/src/tools/clippy/tests/ui/unused_async.stderr +++ b/src/tools/clippy/tests/ui/unused_async.stderr @@ -1,5 +1,5 @@ error: unused `async` for function with no await statements - --> $DIR/unused_async.rs:13:5 + --> $DIR/unused_async.rs:12:5 | LL | / async fn async_block_await() { LL | | @@ -11,7 +11,7 @@ LL | | } | = help: consider removing the `async` from this function note: `await` used in an async block, which does not require the enclosing function to be `async` - --> $DIR/unused_async.rs:16:23 + --> $DIR/unused_async.rs:15:23 | LL | ready(()).await; | ^^^^^ @@ -19,7 +19,7 @@ LL | ready(()).await; = help: to override `-D warnings` add `#[allow(clippy::unused_async)]` error: unused `async` for function with no await statements - --> $DIR/unused_async.rs:46:5 + --> $DIR/unused_async.rs:45:5 | LL | async fn f3() {} | ^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | async fn f3() {} = help: consider removing the `async` from this function error: unused `async` for function with no await statements - --> $DIR/unused_async.rs:59:1 + --> $DIR/unused_async.rs:58:1 | LL | / async fn foo() -> i32 { LL | | @@ -38,7 +38,7 @@ LL | | } = help: consider removing the `async` from this function error: unused `async` for function with no await statements - --> $DIR/unused_async.rs:71:5 + --> $DIR/unused_async.rs:70:5 | LL | / async fn unused(&self) -> i32 { LL | | diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 657d074b380..7b42d8e9b58 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2335,17 +2335,14 @@ impl<'test> TestCx<'test> { rustc.arg("-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX"); rustc.arg("-Ztranslate-remapped-path-to-local-path=no"); - // #[cfg(not(bootstrap))]: After beta bump, this should **always** run. - if !(self.config.stage_id.starts_with("stage1-") && self.config.suite == "ui-fulldeps") { - // Hide Cargo dependency sources from ui tests to make sure the error message doesn't - // change depending on whether $CARGO_HOME is remapped or not. If this is not present, - // when $CARGO_HOME is remapped the source won't be shown, and when it's not remapped the - // source will be shown, causing a blessing hell. - rustc.arg("-Z").arg(format!( - "ignore-directory-in-diagnostics-source-blocks={}", - home::cargo_home().expect("failed to find cargo home").to_str().unwrap() - )); - } + // Hide Cargo dependency sources from ui tests to make sure the error message doesn't + // change depending on whether $CARGO_HOME is remapped or not. If this is not present, + // when $CARGO_HOME is remapped the source won't be shown, and when it's not remapped the + // source will be shown, causing a blessing hell. + rustc.arg("-Z").arg(format!( + "ignore-directory-in-diagnostics-source-blocks={}", + home::cargo_home().expect("failed to find cargo home").to_str().unwrap() + )); // Optionally prevent default --sysroot if specified in test compile-flags. if !self.props.compile_flags.iter().any(|flag| flag.starts_with("--sysroot")) diff --git a/src/tools/miri/ci.sh b/src/tools/miri/ci.sh index 1b3ed796c66..eda1ceb4084 100755 --- a/src/tools/miri/ci.sh +++ b/src/tools/miri/ci.sh @@ -110,8 +110,8 @@ case $HOST_TARGET in MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple atomic data_race env/var MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic - MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings - MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings + MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm + MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm MIRI_TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std # no_std embedded architecture MIRI_TEST_TARGET=tests/avr.json MIRI_NO_STD=1 run_tests_minimal no_std # JSON target file ;; diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 474e7da0000..a7c9d720c0c 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -2a7c2df506fcd5611967a203cc994da5f21abd1e +c07693c1608258f3577eb15057fc0744fa924ae9 diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index 66b729fb166..a74c69d52f2 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -14,7 +14,7 @@ use log::trace; use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir::{Mutability, RetagKind}; use rustc_middle::ty::{self, layout::HasParamEnv, Ty}; -use rustc_target::abi::{Abi, Align, Size}; +use rustc_target::abi::{Abi, Size}; use crate::borrow_tracker::{ stacked_borrows::diagnostics::{AllocHistory, DiagnosticCx, DiagnosticCxBuilder}, @@ -616,7 +616,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' ) -> InterpResult<'tcx, Option<Provenance>> { let this = self.eval_context_mut(); // Ensure we bail out if the pointer goes out-of-bounds (see miri#1050). - this.check_ptr_access_align(place.ptr(), size, Align::ONE, CheckInAllocMsg::InboundsTest)?; + this.check_ptr_access(place.ptr(), size, CheckInAllocMsg::InboundsTest)?; // It is crucial that this gets called on all code paths, to ensure we track tag creation. let log_creation = |this: &MiriInterpCx<'mir, 'tcx>, diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index 6d4c573a35c..e902939290a 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -1,6 +1,6 @@ use log::trace; -use rustc_target::abi::{Abi, Align, Size}; +use rustc_target::abi::{Abi, Size}; use crate::borrow_tracker::{ AccessKind, GlobalState, GlobalStateInner, ProtectorKind, RetagFields, @@ -206,12 +206,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' // Make sure the new permission makes sense as the initial permission of a fresh tag. assert!(new_perm.initial_state.is_initial()); // Ensure we bail out if the pointer goes out-of-bounds (see miri#1050). - this.check_ptr_access_align( - place.ptr(), - ptr_size, - Align::ONE, - CheckInAllocMsg::InboundsTest, - )?; + this.check_ptr_access(place.ptr(), ptr_size, CheckInAllocMsg::InboundsTest)?; // It is crucial that this gets called on all code paths, to ensure we track tag creation. let log_creation = |this: &MiriInterpCx<'mir, 'tcx>, diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index 24b9fa0776f..bec2972c50d 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -1017,12 +1017,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { // even if the type they wrap would be less aligned (e.g. AtomicU64 on 32bit must // be 8-aligned). let align = Align::from_bytes(place.layout.size.bytes()).unwrap(); - this.check_ptr_access_align( - place.ptr(), - place.layout.size, - align, - CheckInAllocMsg::MemoryAccessTest, - )?; + this.check_ptr_align(place.ptr(), align)?; // Ensure the allocation is mutable. Even failing (read-only) compare_exchange need mutable // memory on many targets (i.e., they segfault if taht memory is mapped read-only), and // atomic loads can be implemented via compare_exchange on some targets. There could diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 4146a9b41ae..fd75e8b0ca6 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -697,27 +697,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> { let this = self.eval_context_ref(); let ptr = this.read_pointer(op)?; - - let mplace = MPlaceTy::from_aligned_ptr(ptr, layout); - - this.check_mplace(&mplace)?; - - Ok(mplace) - } - - /// Deref' a pointer *without* checking that the place is dereferenceable. - fn deref_pointer_unchecked( - &self, - val: &ImmTy<'tcx, Provenance>, - layout: TyAndLayout<'tcx>, - ) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> { - let this = self.eval_context_ref(); - let mut mplace = this.ref_to_mplace(val)?; - - mplace.layout = layout; - mplace.align = layout.align.abi; - - Ok(mplace) + Ok(this.ptr_to_mplace(ptr, layout)) } /// Calculates the MPlaceTy given the offset and layout of an access on an operand @@ -805,7 +785,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { loop { // FIXME: We are re-getting the allocation each time around the loop. // Would be nice if we could somehow "extend" an existing AllocRange. - let alloc = this.get_ptr_alloc(ptr.offset(len, this)?, size1, Align::ONE)?.unwrap(); // not a ZST, so we will get a result + let alloc = this.get_ptr_alloc(ptr.offset(len, this)?, size1)?.unwrap(); // not a ZST, so we will get a result let byte = alloc.read_integer(alloc_range(Size::ZERO, size1))?.to_u8()?; if byte == 0 { break; @@ -845,13 +825,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn read_wide_str(&self, mut ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, Vec<u16>> { let this = self.eval_context_ref(); let size2 = Size::from_bytes(2); - let align2 = Align::from_bytes(2).unwrap(); + this.check_ptr_align(ptr, Align::from_bytes(2).unwrap())?; let mut wchars = Vec::new(); loop { // FIXME: We are re-getting the allocation each time around the loop. // Would be nice if we could somehow "extend" an existing AllocRange. - let alloc = this.get_ptr_alloc(ptr, size2, align2)?.unwrap(); // not a ZST, so we will get a result + let alloc = this.get_ptr_alloc(ptr, size2)?.unwrap(); // not a ZST, so we will get a result let wchar = alloc.read_integer(alloc_range(Size::ZERO, size2))?.to_u16()?; if wchar == 0 { break; @@ -887,9 +867,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Store the UTF-16 string. let size2 = Size::from_bytes(2); let this = self.eval_context_mut(); - let mut alloc = this - .get_ptr_alloc_mut(ptr, size2 * string_length, Align::from_bytes(2).unwrap())? - .unwrap(); // not a ZST, so we will get a result + this.check_ptr_align(ptr, Align::from_bytes(2).unwrap())?; + let mut alloc = this.get_ptr_alloc_mut(ptr, size2 * string_length)?.unwrap(); // not a ZST, so we will get a result for (offset, wchar) in wide_str.iter().copied().chain(iter::once(0x0000)).enumerate() { let offset = u64::try_from(offset).unwrap(); alloc.write_scalar(alloc_range(size2 * offset, size2), Scalar::from_u16(wchar))?; diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 439cff84bd4..864374bfdf2 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1288,6 +1288,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { // We do need to write `uninit` so that even after the call ends, the former contents of // this place cannot be observed any more. We do the write after retagging so that for // Tree Borrows, this is considered to activate the new tag. + // Conveniently this also ensures that the place actually points to suitable memory. ecx.write_uninit(&protected_place)?; // Now we throw away the protected place, ensuring its tag is never used again. Ok(()) diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 3462f03c30f..2d5df303745 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -805,14 +805,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.ptr_get_alloc_id(ptr_dest)?; this.ptr_get_alloc_id(ptr_src)?; - this.mem_copy( - ptr_src, - Align::ONE, - ptr_dest, - Align::ONE, - Size::from_bytes(n), - true, - )?; + this.mem_copy(ptr_src, ptr_dest, Size::from_bytes(n), true)?; this.write_pointer(ptr_dest, dest)?; } "strcpy" => { @@ -828,14 +821,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // reason to have `strcpy` destroy pointer provenance. // This reads at least 1 byte, so we are already enforcing that this is a valid pointer. let n = this.read_c_str(ptr_src)?.len().checked_add(1).unwrap(); - this.mem_copy( - ptr_src, - Align::ONE, - ptr_dest, - Align::ONE, - Size::from_bytes(n), - true, - )?; + this.mem_copy(ptr_src, ptr_dest, Size::from_bytes(n), true)?; this.write_pointer(ptr_dest, dest)?; } diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 1014a61b75e..062623a7f6a 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -13,7 +13,7 @@ use log::trace; use rustc_data_structures::fx::FxHashMap; use rustc_middle::ty::TyCtxt; -use rustc_target::abi::{Align, Size}; +use rustc_target::abi::Size; use crate::shims::os_str::bytes_to_os_str; use crate::*; @@ -756,12 +756,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { trace!("Reading from FD {}, size {}", fd, count); // Check that the *entire* buffer is actually valid memory. - this.check_ptr_access_align( - buf, - Size::from_bytes(count), - Align::ONE, - CheckInAllocMsg::MemoryAccessTest, - )?; + this.check_ptr_access(buf, Size::from_bytes(count), CheckInAllocMsg::MemoryAccessTest)?; // We cap the number of read bytes to the largest value that we are able to fit in both the // host's and target's `isize`. This saves us from having to handle overflows later. @@ -810,12 +805,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Isolation check is done via `FileDescriptor` trait. // Check that the *entire* buffer is actually valid memory. - this.check_ptr_access_align( - buf, - Size::from_bytes(count), - Align::ONE, - CheckInAllocMsg::MemoryAccessTest, - )?; + this.check_ptr_access(buf, Size::from_bytes(count), CheckInAllocMsg::MemoryAccessTest)?; // We cap the number of written bytes to the largest value that we are able to fit in both the // host's and target's `isize`. This saves us from having to handle overflows later. @@ -1370,7 +1360,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ("d_reclen", size.into()), ("d_type", file_type.into()), ], - &MPlaceTy::from_aligned_ptr(entry, dirent64_layout), + &this.ptr_to_mplace(entry, dirent64_layout), )?; let name_ptr = entry.offset(Size::from_bytes(d_name_offset), this)?; diff --git a/src/tools/miri/src/shims/unix/linux/sync.rs b/src/tools/miri/src/shims/unix/linux/sync.rs index 7d15abfbfb2..ff25b8120b1 100644 --- a/src/tools/miri/src/shims/unix/linux/sync.rs +++ b/src/tools/miri/src/shims/unix/linux/sync.rs @@ -34,7 +34,7 @@ pub fn futex<'tcx>( let thread = this.get_active_thread(); // This is a vararg function so we have to bring our own type for this pointer. - let addr = MPlaceTy::from_aligned_ptr(addr, this.machine.layouts.i32); + let addr = this.ptr_to_mplace(addr, this.machine.layouts.i32); let addr_usize = addr.ptr().addr().bytes(); let futex_private = this.eval_libc_i32("FUTEX_PRIVATE_FLAG"); @@ -85,11 +85,7 @@ pub fn futex<'tcx>( return Ok(()); } - // `read_timespec` will check the place when it is not null. - let timeout = this.deref_pointer_unchecked( - &this.read_immediate(&args[3])?, - this.libc_ty_layout("timespec"), - )?; + let timeout = this.deref_pointer_as(&args[3], this.libc_ty_layout("timespec"))?; let timeout_time = if this.ptr_is_null(timeout.ptr())? { None } else { diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index c8c8173aa51..2c9603097c8 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -321,9 +321,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.atomic_fence(AtomicFenceOrd::SeqCst)?; let layout = this.machine.layouts.uint(size).unwrap(); - let futex_val = this - .read_scalar_atomic(&MPlaceTy::from_aligned_ptr(ptr, layout), AtomicReadOrd::Relaxed)?; - let compare_val = this.read_scalar(&MPlaceTy::from_aligned_ptr(compare, layout))?; + let futex_val = + this.read_scalar_atomic(&this.ptr_to_mplace(ptr, layout), AtomicReadOrd::Relaxed)?; + let compare_val = this.read_scalar(&this.ptr_to_mplace(compare, layout))?; if futex_val == compare_val { // If the values are the same, we have to block. diff --git a/src/tools/miri/src/shims/x86/sse3.rs b/src/tools/miri/src/shims/x86/sse3.rs index a41de5dbf7e..246e9e9c6cb 100644 --- a/src/tools/miri/src/shims/x86/sse3.rs +++ b/src/tools/miri/src/shims/x86/sse3.rs @@ -1,6 +1,5 @@ use rustc_middle::mir; use rustc_span::Symbol; -use rustc_target::abi::Align; use rustc_target::spec::abi::Abi; use super::horizontal_bin_op; @@ -74,14 +73,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: let src_ptr = this.read_pointer(src_ptr)?; let dest = dest.force_mplace(this)?; - this.mem_copy( - src_ptr, - Align::ONE, - dest.ptr(), - Align::ONE, - dest.layout.size, - /*nonoverlapping*/ true, - )?; + this.mem_copy(src_ptr, dest.ptr(), dest.layout.size, /*nonoverlapping*/ true)?; } _ => return Ok(EmulateForeignItemResult::NotSupported), } diff --git a/src/tools/miri/tests/compiletest.rs b/src/tools/miri/tests/compiletest.rs index c2dccf81377..dbf559631ea 100644 --- a/src/tools/miri/tests/compiletest.rs +++ b/src/tools/miri/tests/compiletest.rs @@ -181,6 +181,7 @@ regexes! { r"0x[0-9a-fA-F]+[0-9a-fA-F]{2,2}" => "$$HEX", // erase specific alignments "alignment [0-9]+" => "alignment ALIGN", + "[0-9]+ byte alignment but found [0-9]+" => "ALIGN byte alignment but found ALIGN", // erase thread caller ids r"call [0-9]+" => "call ID", // erase platform module paths diff --git a/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.stderr b/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.stderr index 44e122330bc..35d26972839 100644 --- a/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.stderr +++ b/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.stderr @@ -13,11 +13,11 @@ LL | libc::munmap(ptr, 4096); = note: BACKTRACE: = note: inside `main` at $DIR/mmap_use_after_munmap.rs:LL:CC -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/mmap_use_after_munmap.rs:LL:CC | LL | let _x = *(ptr as *mut u8); - | ^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.stderr b/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.stderr index ff4cb399157..d4e907bd067 100644 --- a/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.stderr +++ b/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/reallocate-change-alloc.rs:LL:CC | LL | let _z = *x; - | ^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/concurrency/thread_local_static_dealloc.stderr b/src/tools/miri/tests/fail/concurrency/thread_local_static_dealloc.stderr index 0cb8aa29001..7069e8cccfe 100644 --- a/src/tools/miri/tests/fail/concurrency/thread_local_static_dealloc.stderr +++ b/src/tools/miri/tests/fail/concurrency/thread_local_static_dealloc.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/thread_local_static_dealloc.rs:LL:CC | LL | let _val = *dangling_ptr.0; - | ^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/const-ub-checks.stderr b/src/tools/miri/tests/fail/const-ub-checks.stderr index d2b9018cd4b..29acc642c14 100644 --- a/src/tools/miri/tests/fail/const-ub-checks.stderr +++ b/src/tools/miri/tests/fail/const-ub-checks.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const-ub-checks.rs:LL:CC | LL | ptr.read(); - | ^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^^^^^^^^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required note: erroneous constant encountered --> $DIR/const-ub-checks.rs:LL:CC diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.rs deleted file mode 100644 index 49f3ae306a0..00000000000 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Make sure we find these even with many checks disabled. -//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation -use std::ptr; - -fn main() { - let p = { - let b = Box::new(42); - &*b as *const i32 - }; - let x = unsafe { ptr::addr_of!(*p) }; //~ ERROR: has been freed - panic!("this should never print: {:?}", x); -} diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.stderr deleted file mode 100644 index 6a3efbdd3dd..00000000000 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling - --> $DIR/dangling_pointer_addr_of.rs:LL:CC - | -LL | let x = unsafe { ptr::addr_of!(*p) }; - | ^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information -help: ALLOC was allocated here: - --> $DIR/dangling_pointer_addr_of.rs:LL:CC - | -LL | let b = Box::new(42); - | ^^^^^^^^^^^^ -help: ALLOC was deallocated here: - --> $DIR/dangling_pointer_addr_of.rs:LL:CC - | -LL | }; - | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: this error originates in the macro `ptr::addr_of` (in Nightly builds, run with -Z macro-backtrace for more info) - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to previous error - diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.stderr index fad4b4be28c..33d640759fd 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/dangling_pointer_deref.rs:LL:CC | LL | let x = unsafe { *p }; - | ^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.rs index 4c641243950..22a5ce8ea74 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.rs @@ -4,10 +4,9 @@ fn main() { let p = { let b = Box::new(42); - &*b as *const i32 + &*b as *const i32 as *const (u8, u8, u8, u8) }; unsafe { - let _ = *p; //~ ERROR: has been freed + let _ = (*p).1; //~ ERROR: out-of-bounds pointer arithmetic } - panic!("this should never print"); } diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.stderr index 1de6465802b..20f3a25a0b1 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: out-of-bounds pointer arithmetic: ALLOC has been freed, so this pointer is dangling --> $DIR/dangling_pointer_project_underscore.rs:LL:CC | -LL | let _ = *p; - | ^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +LL | let _ = (*p).1; + | ^^^^^^ out-of-bounds pointer arithmetic: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr index bdc9c31db40..c2a73bfbcb2 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/dangling_primitive.rs:LL:CC | LL | dbg!(*ptr); - | ^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.stderr index bf6ee775e94..d8cb691e553 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/dangling_zst_deref.rs:LL:CC | LL | let _x = unsafe { *p }; - | ^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/dangling_pointers/deref-invalid-ptr.stderr b/src/tools/miri/tests/fail/dangling_pointers/deref-invalid-ptr.stderr index 3e2c3903b7e..f11863b5067 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/deref-invalid-ptr.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/deref-invalid-ptr.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: 0x10[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: out-of-bounds pointer use: 0x10[noalloc] is a dangling pointer (it has no provenance) --> $DIR/deref-invalid-ptr.rs:LL:CC | LL | let _y = unsafe { &*x as *const u32 }; - | ^^^ dereferencing pointer failed: 0x10[noalloc] is a dangling pointer (it has no provenance) + | ^^^ out-of-bounds pointer use: 0x10[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/dangling_pointers/deref-partially-dangling.rs b/src/tools/miri/tests/fail/dangling_pointers/deref-partially-dangling.rs deleted file mode 100644 index 27040c26dc2..00000000000 --- a/src/tools/miri/tests/fail/dangling_pointers/deref-partially-dangling.rs +++ /dev/null @@ -1,8 +0,0 @@ -// Deref a raw ptr to access a field of a large struct, where the field -// is allocated but not the entire struct is. -fn main() { - let x = (1, 13); - let xptr = &x as *const _ as *const (i32, i32, i32); - let val = unsafe { (*xptr).1 }; //~ ERROR: pointer to 12 bytes starting at offset 0 is out-of-bounds - assert_eq!(val, 13); -} diff --git a/src/tools/miri/tests/fail/dangling_pointers/deref-partially-dangling.stderr b/src/tools/miri/tests/fail/dangling_pointers/deref-partially-dangling.stderr deleted file mode 100644 index 92b1fcb1145..00000000000 --- a/src/tools/miri/tests/fail/dangling_pointers/deref-partially-dangling.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 8, so pointer to 12 bytes starting at offset 0 is out-of-bounds - --> $DIR/deref-partially-dangling.rs:LL:CC - | -LL | let val = unsafe { (*xptr).1 }; - | ^^^^^^^^^ dereferencing pointer failed: ALLOC has size 8, so pointer to 12 bytes starting at offset 0 is out-of-bounds - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information -help: ALLOC was allocated here: - --> $DIR/deref-partially-dangling.rs:LL:CC - | -LL | let x = (1, 13); - | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at $DIR/deref-partially-dangling.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to previous error - diff --git a/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.rs b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.rs new file mode 100644 index 00000000000..d2823672ade --- /dev/null +++ b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.rs @@ -0,0 +1,16 @@ +// Should be caught even without retagging +//@compile-flags: -Zmiri-disable-stacked-borrows +#![feature(strict_provenance)] +use std::ptr::{self, addr_of_mut}; + +// Deref'ing a dangling raw pointer is fine, but for a dangling box it is not. +// We do this behind a pointer indirection to potentially fool validity checking. +// (This test relies on the `deref_copy` pass that lowers `**ptr` to materialize the intermediate pointer.) + +fn main() { + let mut inner = ptr::invalid::<i32>(24); + let outer = addr_of_mut!(inner).cast::<Box<i32>>(); + // Now `outer` is a pointer to a dangling reference. + // Deref'ing that should be UB. + let _val = unsafe { addr_of_mut!(**outer) }; //~ERROR: dangling box +} diff --git a/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.stderr b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.stderr new file mode 100644 index 00000000000..64d6d36c2c0 --- /dev/null +++ b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_box.stderr @@ -0,0 +1,16 @@ +error: Undefined Behavior: constructing invalid value: encountered a dangling box (0x18[noalloc] has no provenance) + --> $DIR/deref_dangling_box.rs:LL:CC + | +LL | let _val = unsafe { addr_of_mut!(**outer) }; + | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (0x18[noalloc] has no provenance) + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at RUSTLIB/core/src/ptr/mod.rs:LL:CC + = note: this error originates in the macro `addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.rs b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.rs new file mode 100644 index 00000000000..b62e041d70c --- /dev/null +++ b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.rs @@ -0,0 +1,16 @@ +// Should be caught even without retagging +//@compile-flags: -Zmiri-disable-stacked-borrows +#![feature(strict_provenance)] +use std::ptr::{self, addr_of_mut}; + +// Deref'ing a dangling raw pointer is fine, but for a dangling reference it is not. +// We do this behind a pointer indirection to potentially fool validity checking. +// (This test relies on the `deref_copy` pass that lowers `**ptr` to materialize the intermediate pointer.) + +fn main() { + let mut inner = ptr::invalid::<i32>(24); + let outer = addr_of_mut!(inner).cast::<&'static mut i32>(); + // Now `outer` is a pointer to a dangling reference. + // Deref'ing that should be UB. + let _val = unsafe { addr_of_mut!(**outer) }; //~ERROR: dangling reference +} diff --git a/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.stderr b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.stderr new file mode 100644 index 00000000000..244e3f4b659 --- /dev/null +++ b/src/tools/miri/tests/fail/dangling_pointers/deref_dangling_ref.stderr @@ -0,0 +1,16 @@ +error: Undefined Behavior: constructing invalid value: encountered a dangling reference (0x18[noalloc] has no provenance) + --> $DIR/deref_dangling_ref.rs:LL:CC + | +LL | let _val = unsafe { addr_of_mut!(**outer) }; + | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (0x18[noalloc] has no provenance) + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at RUSTLIB/core/src/ptr/mod.rs:LL:CC + = note: this error originates in the macro `addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/dangling_pointers/dyn_size.rs b/src/tools/miri/tests/fail/dangling_pointers/dyn_size.rs index 87ca8a6077c..fa01bbc19c9 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dyn_size.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/dyn_size.rs @@ -1,13 +1,13 @@ -// should find the bug even without these -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows +// should find the bug even without retagging +//@compile-flags: -Zmiri-disable-stacked-borrows struct SliceWithHead(u8, [u8]); fn main() { let buf = [0u32; 1]; // We craft a wide pointer `*const SliceWithHead` such that the unsized tail is only partially allocated. - // That should be UB, as the reference is not fully dereferencable. + // That should lead to UB, as the reference is not fully dereferenceable. let ptr: *const SliceWithHead = unsafe { std::mem::transmute((&buf, 4usize)) }; // Re-borrow that. This should be UB. - let _ptr = unsafe { &*ptr }; //~ ERROR: pointer to 5 bytes starting at offset 0 is out-of-bounds + let _ptr = unsafe { &*ptr }; //~ ERROR: encountered a dangling reference (going beyond the bounds of its allocation) } diff --git a/src/tools/miri/tests/fail/dangling_pointers/dyn_size.stderr b/src/tools/miri/tests/fail/dangling_pointers/dyn_size.stderr index 95a50bc8750..4d45630e1ba 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dyn_size.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dyn_size.stderr @@ -1,17 +1,12 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 4, so pointer to 5 bytes starting at offset 0 is out-of-bounds +error: Undefined Behavior: constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) --> $DIR/dyn_size.rs:LL:CC | LL | let _ptr = unsafe { &*ptr }; - | ^^^^^ dereferencing pointer failed: ALLOC has size 4, so pointer to 5 bytes starting at offset 0 is out-of-bounds + | ^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information -help: ALLOC was allocated here: - --> $DIR/dyn_size.rs:LL:CC - | -LL | let buf = [0u32; 1]; - | ^^^ - = note: BACKTRACE (of the first span): + = note: BACKTRACE: = note: inside `main` at $DIR/dyn_size.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.stderr b/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.stderr index 3e492a170c8..895d4c7fce2 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds +error: Undefined Behavior: memory access failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds --> $DIR/maybe_null_pointer_deref_zst.rs:LL:CC | LL | let _x: () = unsafe { *ptr }; - | ^^^^ dereferencing pointer failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds + | ^^^^ memory access failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.stderr b/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.stderr index c41c20aaf4a..6cc05758b7e 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds +error: Undefined Behavior: memory access failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds --> $DIR/maybe_null_pointer_write_zst.rs:LL:CC | LL | unsafe { *ptr = zst_val }; - | ^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds + | ^^^^^^^^^^^^^^ memory access failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref.stderr b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref.stderr index 64dcaa45484..727c724552d 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance) --> $DIR/null_pointer_deref.rs:LL:CC | LL | let x: i32 = unsafe { *std::ptr::null() }; - | ^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.rs b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.rs index 4cb805db095..f8af43ff352 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.rs @@ -1,5 +1,5 @@ #[allow(deref_nullptr)] fn main() { - let x: () = unsafe { *std::ptr::null() }; //~ ERROR: dereferencing pointer failed: null pointer is a dangling pointer + let x: () = unsafe { *std::ptr::null() }; //~ ERROR: memory access failed: null pointer is a dangling pointer panic!("this should never print: {:?}", x); } diff --git a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.stderr b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.stderr index 301578a4f5f..9f93a0e18a2 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance) --> $DIR/null_pointer_deref_zst.rs:LL:CC | LL | let x: () = unsafe { *std::ptr::null() }; - | ^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write.stderr b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write.stderr index 0e5858a96f9..6974b997725 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance) --> $DIR/null_pointer_write.rs:LL:CC | LL | unsafe { *std::ptr::null_mut() = 0i32 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs index ec34c631a46..edd6c8fadce 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs @@ -4,5 +4,5 @@ fn main() { // Also not assigning directly as that's array initialization, not assignment. let zst_val = [1u8; 0]; unsafe { std::ptr::null_mut::<[u8; 0]>().write(zst_val) }; - //~^ERROR: dereferencing pointer failed: null pointer is a dangling pointer + //~^ERROR: memory access failed: null pointer is a dangling pointer } diff --git a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.stderr b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.stderr index a4e0ebe38f6..2953d85c25f 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance) --> $DIR/null_pointer_write_zst.rs:LL:CC | LL | unsafe { std::ptr::null_mut::<[u8; 0]>().write(zst_val) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_project.rs b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_project.rs new file mode 100644 index 00000000000..b596ba428ae --- /dev/null +++ b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_project.rs @@ -0,0 +1,12 @@ +// Make sure we find these even with many checks disabled. +//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation +use std::ptr::addr_of; + +fn main() { + let v = 0u32; + let ptr = addr_of!(v).cast::<(u32, u32, u32)>(); + unsafe { + let _field = addr_of!((*ptr).1); // still just in-bounds + let _field = addr_of!((*ptr).2); //~ ERROR: out-of-bounds pointer arithmetic + } +} diff --git a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_project.stderr b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_project.stderr new file mode 100644 index 00000000000..1c105991015 --- /dev/null +++ b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_project.stderr @@ -0,0 +1,21 @@ +error: Undefined Behavior: out-of-bounds pointer arithmetic: ALLOC has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds + --> $DIR/out_of_bounds_project.rs:LL:CC + | +LL | let _field = addr_of!((*ptr).2); + | ^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: ALLOC has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information +help: ALLOC was allocated here: + --> $DIR/out_of_bounds_project.rs:LL:CC + | +LL | let v = 0u32; + | ^ + = note: BACKTRACE (of the first span): + = note: inside `main` at RUSTLIB/core/src/ptr/mod.rs:LL:CC + = note: this error originates in the macro `addr_of` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read.rs b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read.rs new file mode 100644 index 00000000000..f6b8a1ad55b --- /dev/null +++ b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read.rs @@ -0,0 +1,8 @@ +#![feature(pointer_byte_offsets)] + +fn main() { + let v: Vec<u16> = vec![1, 2]; + // This read is also misaligned. We make sure that the OOB message has priority. + let x = unsafe { *v.as_ptr().wrapping_byte_add(5) }; //~ ERROR: out-of-bounds + panic!("this should never print: {}", x); +} diff --git a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read1.stderr b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read.stderr index 7d2aed371bd..38d691f4c01 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read1.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read.stderr @@ -1,18 +1,18 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 2, so pointer to 1 byte starting at offset 5 is out-of-bounds - --> $DIR/out_of_bounds_read1.rs:LL:CC +error: Undefined Behavior: memory access failed: ALLOC has size 4, so pointer to 2 bytes starting at offset 5 is out-of-bounds + --> $DIR/out_of_bounds_read.rs:LL:CC | -LL | let x = unsafe { *v.as_ptr().wrapping_offset(5) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 2, so pointer to 1 byte starting at offset 5 is out-of-bounds +LL | let x = unsafe { *v.as_ptr().wrapping_byte_add(5) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has size 4, so pointer to 2 bytes starting at offset 5 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information help: ALLOC was allocated here: - --> $DIR/out_of_bounds_read1.rs:LL:CC + --> $DIR/out_of_bounds_read.rs:LL:CC | -LL | let v: Vec<u8> = vec![1, 2]; - | ^^^^^^^^^^ +LL | let v: Vec<u16> = vec![1, 2]; + | ^^^^^^^^^^ = note: BACKTRACE (of the first span): - = note: inside `main` at $DIR/out_of_bounds_read1.rs:LL:CC + = note: inside `main` at $DIR/out_of_bounds_read.rs:LL:CC = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read1.rs b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read1.rs deleted file mode 100644 index 58a64eecace..00000000000 --- a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read1.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - let v: Vec<u8> = vec![1, 2]; - let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR: out-of-bounds - panic!("this should never print: {}", x); -} diff --git a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read2.rs b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read2.rs deleted file mode 100644 index 58a64eecace..00000000000 --- a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read2.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - let v: Vec<u8> = vec![1, 2]; - let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR: out-of-bounds - panic!("this should never print: {}", x); -} diff --git a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_write.rs b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_write.rs new file mode 100644 index 00000000000..4ead91744c8 --- /dev/null +++ b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_write.rs @@ -0,0 +1,7 @@ +#![feature(pointer_byte_offsets)] + +fn main() { + let mut v: Vec<u16> = vec![1, 2]; + // This read is also misaligned. We make sure that the OOB message has priority. + unsafe { *v.as_mut_ptr().wrapping_byte_add(5) = 0 }; //~ ERROR: out-of-bounds +} diff --git a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read2.stderr b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_write.stderr index 69a8498f097..9669614d47f 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_read2.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/out_of_bounds_write.stderr @@ -1,18 +1,18 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 2, so pointer to 1 byte starting at offset 5 is out-of-bounds - --> $DIR/out_of_bounds_read2.rs:LL:CC +error: Undefined Behavior: memory access failed: ALLOC has size 4, so pointer to 2 bytes starting at offset 5 is out-of-bounds + --> $DIR/out_of_bounds_write.rs:LL:CC | -LL | let x = unsafe { *v.as_ptr().wrapping_offset(5) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 2, so pointer to 1 byte starting at offset 5 is out-of-bounds +LL | unsafe { *v.as_mut_ptr().wrapping_byte_add(5) = 0 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has size 4, so pointer to 2 bytes starting at offset 5 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information help: ALLOC was allocated here: - --> $DIR/out_of_bounds_read2.rs:LL:CC + --> $DIR/out_of_bounds_write.rs:LL:CC | -LL | let v: Vec<u8> = vec![1, 2]; - | ^^^^^^^^^^ +LL | let mut v: Vec<u16> = vec![1, 2]; + | ^^^^^^^^^^ = note: BACKTRACE (of the first span): - = note: inside `main` at $DIR/out_of_bounds_read2.rs:LL:CC + = note: inside `main` at $DIR/out_of_bounds_write.rs:LL:CC = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr b/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr index 4d2dfe28aed..28a9207cff3 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/stack_temporary.rs:LL:CC | LL | let val = *x; - | ^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr b/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr index 6c41add60ef..9b47655a047 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: out-of-bounds pointer use: $HEX[noalloc] is a dangling pointer (it has no provenance) --> $DIR/storage_dead_dangling.rs:LL:CC | LL | let _ = unsafe { &mut *(LEAK as *mut i32) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: $HEX[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/dangling_pointers/wild_pointer_deref.stderr b/src/tools/miri/tests/fail/dangling_pointers/wild_pointer_deref.stderr index 658fb228174..802995aea50 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/wild_pointer_deref.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/wild_pointer_deref.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: 0x2c[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: 0x2c[noalloc] is a dangling pointer (it has no provenance) --> $DIR/wild_pointer_deref.rs:LL:CC | LL | let x = unsafe { *p }; - | ^^ dereferencing pointer failed: 0x2c[noalloc] is a dangling pointer (it has no provenance) + | ^^ memory access failed: 0x2c[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr index 810e48d59c6..792faf8f5d1 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/dealloc_read_race2.rs:LL:CC | LL | *ptr.0 - | ^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr index 7d672cd4d62..64f654402d7 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/dealloc_write_race2.rs:LL:CC | LL | *ptr.0 = 2; - | ^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/environ-gets-deallocated.stderr b/src/tools/miri/tests/fail/environ-gets-deallocated.stderr index 6332846d5d8..dd7420906d3 100644 --- a/src/tools/miri/tests/fail/environ-gets-deallocated.stderr +++ b/src/tools/miri/tests/fail/environ-gets-deallocated.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/environ-gets-deallocated.rs:LL:CC | LL | let _y = unsafe { *pointer }; - | ^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/function_pointers/deref_fn_ptr.rs b/src/tools/miri/tests/fail/function_pointers/deref_fn_ptr.rs index f071b63902f..3510f41361a 100644 --- a/src/tools/miri/tests/fail/function_pointers/deref_fn_ptr.rs +++ b/src/tools/miri/tests/fail/function_pointers/deref_fn_ptr.rs @@ -2,7 +2,7 @@ fn f() {} fn main() { let x: u8 = unsafe { - *std::mem::transmute::<fn(), *const u8>(f) //~ ERROR: out-of-bounds + *std::mem::transmute::<fn(), *const u8>(f) //~ ERROR: contains a function }; panic!("this should never print: {}", x); } diff --git a/src/tools/miri/tests/fail/function_pointers/deref_fn_ptr.stderr b/src/tools/miri/tests/fail/function_pointers/deref_fn_ptr.stderr index 7ce0b08695e..954bb8721e7 100644 --- a/src/tools/miri/tests/fail/function_pointers/deref_fn_ptr.stderr +++ b/src/tools/miri/tests/fail/function_pointers/deref_fn_ptr.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds +error: Undefined Behavior: accessing ALLOC which contains a function --> $DIR/deref_fn_ptr.rs:LL:CC | LL | *std::mem::transmute::<fn(), *const u8>(f) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing ALLOC which contains a function | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/generator-pinned-moved.stderr b/src/tools/miri/tests/fail/generator-pinned-moved.stderr index 4cb8450c6d5..8ad0ce8cc32 100644 --- a/src/tools/miri/tests/fail/generator-pinned-moved.stderr +++ b/src/tools/miri/tests/fail/generator-pinned-moved.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/generator-pinned-moved.rs:LL:CC | LL | *num += 1; - | ^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr b/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr index f82b30a9633..f3bd275b027 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds +error: Undefined Behavior: memory access failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds --> $DIR/simd-gather.rs:LL:CC | LL | let _result = Simd::gather_select_unchecked(&vec, Mask::splat(true), idxs, Simd::splat(0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr b/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr index 5beee034db2..1720a24aa13 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds +error: Undefined Behavior: memory access failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds --> $DIR/simd-scatter.rs:LL:CC | LL | / Simd::from_array([-27, 82, -41, 124]).scatter_select_unchecked( @@ -7,7 +7,7 @@ LL | | &mut vec, LL | | Mask::splat(true), LL | | idxs, LL | | ); - | |_________^ dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds + | |_________^ memory access failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/provenance/pointer_partial_overwrite.stderr b/src/tools/miri/tests/fail/provenance/pointer_partial_overwrite.stderr index 06e5ede8c77..8fafc7e82c9 100644 --- a/src/tools/miri/tests/fail/provenance/pointer_partial_overwrite.stderr +++ b/src/tools/miri/tests/fail/provenance/pointer_partial_overwrite.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) --> $DIR/pointer_partial_overwrite.rs:LL:CC | LL | let x = *p; - | ^^ dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) + | ^^ memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/provenance/provenance_transmute.rs b/src/tools/miri/tests/fail/provenance/provenance_transmute.rs index abcfc060e52..bc5dd53dcf5 100644 --- a/src/tools/miri/tests/fail/provenance/provenance_transmute.rs +++ b/src/tools/miri/tests/fail/provenance/provenance_transmute.rs @@ -13,7 +13,7 @@ unsafe fn deref(left: *const u8, right: *const u8) { // The compiler is allowed to replace `left_int` by `right_int` here... let left_ptr: *const u8 = mem::transmute(left_int); // ...which however means here it could be dereferencing the wrong pointer. - let _val = *left_ptr; //~ERROR: dereferencing pointer failed + let _val = *left_ptr; //~ERROR: dangling pointer } } diff --git a/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr b/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr index 042d8cd4afe..319517d062b 100644 --- a/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr +++ b/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) --> $DIR/provenance_transmute.rs:LL:CC | LL | let _val = *left_ptr; - | ^^^^^^^^^ dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) + | ^^^^^^^^^ memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/provenance/ptr_int_unexposed.stderr b/src/tools/miri/tests/fail/provenance/ptr_int_unexposed.stderr index 4ad885ddabd..9ebabfb129c 100644 --- a/src/tools/miri/tests/fail/provenance/ptr_int_unexposed.stderr +++ b/src/tools/miri/tests/fail/provenance/ptr_int_unexposed.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) --> $DIR/ptr_int_unexposed.rs:LL:CC | LL | assert_eq!(unsafe { *ptr }, 3); - | ^^^^ dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) + | ^^^^ memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/provenance/ptr_invalid.stderr b/src/tools/miri/tests/fail/provenance/ptr_invalid.stderr index ef9dcad97cb..50ceae7cfda 100644 --- a/src/tools/miri/tests/fail/provenance/ptr_invalid.stderr +++ b/src/tools/miri/tests/fail/provenance/ptr_invalid.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) --> $DIR/ptr_invalid.rs:LL:CC | LL | let _val = unsafe { *xptr_invalid }; - | ^^^^^^^^^^^^^ dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^ memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/rc_as_ptr.stderr b/src/tools/miri/tests/fail/rc_as_ptr.stderr index 460ed977137..eb522b2bc0c 100644 --- a/src/tools/miri/tests/fail/rc_as_ptr.stderr +++ b/src/tools/miri/tests/fail/rc_as_ptr.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: out-of-bounds pointer use: ALLOC has been freed, so this pointer is dangling --> $DIR/rc_as_ptr.rs:LL:CC | LL | assert_eq!(42, **unsafe { &*Weak::as_ptr(&weak) }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/reading_half_a_pointer.stderr b/src/tools/miri/tests/fail/reading_half_a_pointer.stderr index 61a7161a98b..df4adb5ead7 100644 --- a/src/tools/miri/tests/fail/reading_half_a_pointer.stderr +++ b/src/tools/miri/tests/fail/reading_half_a_pointer.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) --> $DIR/reading_half_a_pointer.rs:LL:CC | LL | let _val = *x; - | ^^ dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) + | ^^ memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/unaligned_pointers/alignment.stderr b/src/tools/miri/tests/fail/unaligned_pointers/alignment.stderr index bbebe3b89fd..5fdec1dc74c 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/alignment.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/alignment.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/alignment.rs:LL:CC | LL | *(x_ptr as *mut u32) = 42; *(x_ptr.add(1) as *mut u32) = 42; - | ^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs index d8cab68ac5d..d71d5954a40 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs @@ -13,7 +13,7 @@ struct PartialDrop { b: u8, } -//@error-in-other-file: /alignment 2 is required/ +//@error-in-other-file: /required 2 byte alignment/ fn main() { unsafe { // Create an unaligned pointer diff --git a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr index ef20b43c118..db35a20ee22 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) --> RUSTLIB/core/src/ptr/mod.rs:LL:CC | LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.stderr b/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.stderr index 503721b9551..cfb43ae891f 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required 256 byte alignment but found $ALIGN) +error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) --> $DIR/dyn_alignment.rs:LL:CC | LL | let _ptr = &*ptr; - | ^^^^^ constructing invalid value: encountered an unaligned reference (required 256 byte alignment but found $ALIGN) + | ^^^^^ constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs index fa1812adc29..114ab5479b4 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs @@ -8,7 +8,7 @@ pub struct S { } unsafe fn foo(x: *const S) -> u8 { - unsafe { (*x).x } //~ERROR: accessing memory with alignment 1, but alignment 4 is required + unsafe { (*x).x } //~ERROR: based on pointer with alignment 1, but alignment 4 is required } fn main() { diff --git a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr index 0f030a6e27c..2ffbc2a434e 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/field_requires_parent_struct_alignment.rs:LL:CC | LL | unsafe { (*x).x } - | ^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^^^^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.rs b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.rs new file mode 100644 index 00000000000..8459c64ed2d --- /dev/null +++ b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.rs @@ -0,0 +1,30 @@ +/// This tests that when a field sits at a well-aligned offset, accessing the field +/// requires high alignment even if the field type has lower alignment requirements. + +#[repr(C, align(16))] +#[derive(Default, Copy, Clone)] +pub struct Aligned { + _pad: [u8; 11], + packed: Packed, +} +#[repr(packed)] +#[derive(Default, Copy, Clone)] +pub struct Packed { + _pad: [u8; 5], + x: u8, +} + +unsafe fn foo(x: *const Aligned) -> u8 { + unsafe { (*x).packed.x } //~ERROR: based on pointer with alignment 1, but alignment 16 is required +} + +fn main() { + unsafe { + let mem = [Aligned::default(); 16]; + let odd_ptr = std::ptr::addr_of!(mem).cast::<u8>().add(1); + // `odd_ptr` is now not aligned enough for `Aligned`. + // If accessing the nested field `packed.x` can exploit that it is at offset 16 + // in a 16-aligned struct, this has to be UB. + foo(odd_ptr.cast()); + } +} diff --git a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.stderr b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.stderr new file mode 100644 index 00000000000..6d96c62545a --- /dev/null +++ b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required + --> $DIR/field_requires_parent_struct_alignment2.rs:LL:CC + | +LL | unsafe { (*x).packed.x } + | ^^^^^^^^^^^^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `foo` at $DIR/field_requires_parent_struct_alignment2.rs:LL:CC +note: inside `main` + --> $DIR/field_requires_parent_struct_alignment2.rs:LL:CC + | +LL | foo(odd_ptr.cast()); + | ^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs b/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs index ed43e552506..11f63839122 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs @@ -12,6 +12,6 @@ fn main() { // Manually make sure the pointer is properly aligned. let base_addr_aligned = if base_addr % 2 == 0 { base_addr } else { base_addr + 1 }; let u16_ptr = base_addr_aligned as *mut u16; - unsafe { *u16_ptr = 2 }; //~ERROR: memory with alignment 1, but alignment 2 is required + unsafe { *u16_ptr = 2 }; //~ERROR: with alignment 1, but alignment 2 is required println!("{:?}", x); } diff --git a/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr b/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr index 392495a386d..9342b269993 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/intptrcast_alignment_check.rs:LL:CC | LL | unsafe { *u16_ptr = 2 }; - | ^^^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^^^^^^^^^^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this usually indicates that your program performed an invalid operation and caused Undefined Behavior = help: but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives diff --git a/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs b/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs index 4a8cf405ae2..b9d29d775ab 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs @@ -1,5 +1,5 @@ -// This should fail even without validation/SB -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no +// This should fail even without SB +//@compile-flags: -Zmiri-disable-stacked-borrows -Cdebug-assertions=no #![allow(dead_code, unused_variables)] @@ -12,15 +12,14 @@ struct Foo { } unsafe fn raw_to_ref<'a, T>(x: *const T) -> &'a T { - mem::transmute(x) + mem::transmute(x) //~ERROR: required 4 byte alignment } fn main() { // Try many times as this might work by chance. for _ in 0..20 { let foo = Foo { x: 42, y: 99 }; - // There seem to be implicit reborrows, which make the error already appear here - let p: &i32 = unsafe { raw_to_ref(ptr::addr_of!(foo.x)) }; //~ERROR: alignment 4 is required + let p: &i32 = unsafe { raw_to_ref(ptr::addr_of!(foo.x)) }; let i = *p; } } diff --git a/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.stderr b/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.stderr index 7c246706dba..fb588854b2a 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.stderr @@ -1,13 +1,18 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) --> $DIR/reference_to_packed.rs:LL:CC | -LL | let p: &i32 = unsafe { raw_to_ref(ptr::addr_of!(foo.x)) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required +LL | mem::transmute(x) + | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: - = note: inside `main` at $DIR/reference_to_packed.rs:LL:CC + = note: inside `raw_to_ref::<'_, i32>` at $DIR/reference_to_packed.rs:LL:CC +note: inside `main` + --> $DIR/reference_to_packed.rs:LL:CC + | +LL | let p: &i32 = unsafe { raw_to_ref(ptr::addr_of!(foo.x)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.rs index 921bcd6ce24..9c72781ee05 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.rs @@ -7,6 +7,6 @@ fn main() { let x = [2u16, 3, 4]; // Make it big enough so we don't get an out-of-bounds error. let x = &x[0] as *const _ as *const u32; // This must fail because alignment is violated: the allocation's base is not sufficiently aligned. - let _x = unsafe { *x }; //~ERROR: memory with alignment 2, but alignment 4 is required + let _x = unsafe { *x }; //~ERROR: with alignment 2, but alignment 4 is required } } diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.stderr b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.stderr index 49292be9cd1..daebabf4557 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/unaligned_ptr1.rs:LL:CC | LL | let _x = unsafe { *x }; - | ^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.rs index 8f597659f73..ac3062773de 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.rs @@ -8,5 +8,5 @@ fn main() { let x = (x.as_ptr() as *const u8).wrapping_offset(3) as *const u32; // This must fail because alignment is violated: the offset is not sufficiently aligned. // Also make the offset not a power of 2, that used to ICE. - let _x = unsafe { *x }; //~ERROR: memory with alignment 1, but alignment 4 is required + let _x = unsafe { *x }; //~ERROR: with alignment 1, but alignment 4 is required } diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.stderr b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.stderr index e75482f723b..38902e693dc 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/unaligned_ptr2.rs:LL:CC | LL | let _x = unsafe { *x }; - | ^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.stderr b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.stderr index 50dd4fdfc89..36a13b63319 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/unaligned_ptr3.rs:LL:CC | LL | let _x = unsafe { *x }; - | ^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.stderr b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.stderr index 182f3e0f876..8d7a62c3850 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/unaligned_ptr4.rs:LL:CC | LL | let _val = unsafe { *ptr }; - | ^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.rs deleted file mode 100644 index b414b905472..00000000000 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.rs +++ /dev/null @@ -1,14 +0,0 @@ -// This should fail even without validation or Stacked Borrows. -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no -use std::ptr; - -fn main() { - // Try many times as this might work by chance. - for _ in 0..20 { - let x = [2u16, 3, 4]; // Make it big enough so we don't get an out-of-bounds error. - let x = &x[0] as *const _ as *const u32; - // This must fail because alignment is violated: the allocation's base is not sufficiently aligned. - // The deref is UB even if we just put the result into a raw pointer. - let _x = unsafe { ptr::addr_of!(*x) }; //~ ERROR: memory with alignment 2, but alignment 4 is required - } -} diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.stderr b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.stderr deleted file mode 100644 index 2d8b1bf7450..00000000000 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required - --> $DIR/unaligned_ptr_addr_of.rs:LL:CC - | -LL | let _x = unsafe { ptr::addr_of!(*x) }; - | ^^^^^^^^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: this error originates in the macro `ptr::addr_of` (in Nightly builds, run with -Z macro-backtrace for more info) - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to previous error - diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.stderr b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.stderr index aa0cbe1623b..7481179f26a 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/unaligned_ptr_zst.rs:LL:CC | LL | let _x = unsafe { *x }; - | ^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs new file mode 100644 index 00000000000..470420acd50 --- /dev/null +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs @@ -0,0 +1,12 @@ +// This should fail even without Stacked Borrows. +//@compile-flags: -Zmiri-disable-stacked-borrows -Cdebug-assertions=no + +fn main() { + // Try many times as this might work by chance. + for _ in 0..20 { + let x = [2u16, 3, 4]; // Make it big enough so we don't get an out-of-bounds error. + let x = &x[0] as *const _ as *const u32; + // This must fail because alignment is violated: the allocation's base is not sufficiently aligned. + let _x = unsafe { &*x }; //~ ERROR: required 4 byte alignment + } +} diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.stderr b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.stderr new file mode 100644 index 00000000000..e47226ecdc7 --- /dev/null +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) + --> $DIR/unaligned_ref_addr_of.rs:LL:CC + | +LL | let _x = unsafe { &*x }; + | ^^^ constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/unaligned_ref_addr_of.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/zst1.stderr b/src/tools/miri/tests/fail/zst1.stderr index b89f06af958..07bf048ab6e 100644 --- a/src/tools/miri/tests/fail/zst1.stderr +++ b/src/tools/miri/tests/fail/zst1.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds +error: Undefined Behavior: memory access failed: ALLOC has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds --> $DIR/zst1.rs:LL:CC | LL | let _val = unsafe { *x }; - | ^^ dereferencing pointer failed: ALLOC has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds + | ^^ memory access failed: ALLOC has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/zst2.stderr b/src/tools/miri/tests/fail/zst2.stderr index 49954b1fd14..f42fb07edcd 100644 --- a/src/tools/miri/tests/fail/zst2.stderr +++ b/src/tools/miri/tests/fail/zst2.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/zst2.rs:LL:CC | LL | unsafe { *x = zst_val }; - | ^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/zst3.stderr b/src/tools/miri/tests/fail/zst3.stderr index b62aef675d2..f8b416ec348 100644 --- a/src/tools/miri/tests/fail/zst3.stderr +++ b/src/tools/miri/tests/fail/zst3.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 1, so pointer at offset 2 is out-of-bounds +error: Undefined Behavior: memory access failed: ALLOC has size 1, so pointer at offset 2 is out-of-bounds --> $DIR/zst3.rs:LL:CC | LL | unsafe { *(x as *mut [u8; 0]) = zst_val }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 1, so pointer at offset 2 is out-of-bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has size 1, so pointer at offset 2 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/pass/function_calls/target_feature_wasm.rs b/src/tools/miri/tests/pass/function_calls/target_feature_wasm.rs new file mode 100644 index 00000000000..5056f32de44 --- /dev/null +++ b/src/tools/miri/tests/pass/function_calls/target_feature_wasm.rs @@ -0,0 +1,11 @@ +//@only-target-wasm32: tests WASM-specific behavior +//@compile-flags: -C target-feature=-simd128 + +fn main() { + // Calling functions with `#[target_feature]` is not unsound on WASM, see #84988 + assert!(!cfg!(target_feature = "simd128")); + simd128_fn(); +} + +#[target_feature(enable = "simd128")] +fn simd128_fn() {} diff --git a/src/tools/miri/tests/pass/ptr_raw.rs b/src/tools/miri/tests/pass/ptr_raw.rs index 2f184358907..11c3455a9ca 100644 --- a/src/tools/miri/tests/pass/ptr_raw.rs +++ b/src/tools/miri/tests/pass/ptr_raw.rs @@ -1,3 +1,7 @@ +#![feature(strict_provenance)] +use std::mem; +use std::ptr::{self, addr_of}; + fn basic_raw() { let mut x = 12; let x = &mut x; @@ -28,7 +32,37 @@ fn assign_overlapping() { unsafe { *ptr = *ptr }; } +fn deref_invalid() { + unsafe { + // `addr_of!(*ptr)` is never UB. + let _val = addr_of!(*ptr::invalid::<i32>(0)); + let _val = addr_of!(*ptr::invalid::<i32>(1)); // not aligned + + // Similarly, just mentioning the place is fine. + let _ = *ptr::invalid::<i32>(0); + let _ = *ptr::invalid::<i32>(1); + } +} + +fn deref_partially_dangling() { + let x = (1, 13); + let xptr = &x as *const _ as *const (i32, i32, i32); + let val = unsafe { (*xptr).1 }; + assert_eq!(val, 13); +} + +fn deref_too_big_slice() { + unsafe { + let slice: *const [u8] = mem::transmute((1usize, usize::MAX)); + // `&*slice` would complain that the slice is too big, but in a raw pointer this is fine. + let _val = addr_of!(*slice); + } +} + fn main() { basic_raw(); assign_overlapping(); + deref_invalid(); + deref_partially_dangling(); + deref_too_big_slice(); } diff --git a/src/tools/opt-dist/Cargo.toml b/src/tools/opt-dist/Cargo.toml index c212e8aafe1..9e852b0645a 100644 --- a/src/tools/opt-dist/Cargo.toml +++ b/src/tools/opt-dist/Cargo.toml @@ -23,4 +23,4 @@ glob = "0.3" tempfile = "3.5" derive_builder = "0.12" clap = { version = "4", features = ["derive"] } -tabled = "0.13" +tabled = { version = "0.13", default-features = false, features = ["std"] } diff --git a/src/tools/opt-dist/src/bolt.rs b/src/tools/opt-dist/src/bolt.rs index cf9f4fabcec..f694c08f9b9 100644 --- a/src/tools/opt-dist/src/bolt.rs +++ b/src/tools/opt-dist/src/bolt.rs @@ -1,14 +1,14 @@ use anyhow::Context; use crate::exec::cmd; -use crate::training::LlvmBoltProfile; +use crate::training::BoltProfile; use camino::{Utf8Path, Utf8PathBuf}; use crate::utils::io::copy_file; /// Instruments an artifact at the given `path` (in-place) with BOLT and then calls `func`. /// After this function finishes, the original file will be restored. -pub fn with_bolt_instrumented<F: FnOnce() -> anyhow::Result<R>, R>( +pub fn with_bolt_instrumented<F: FnOnce(&Utf8Path) -> anyhow::Result<R>, R>( path: &Utf8Path, func: F, ) -> anyhow::Result<R> { @@ -20,10 +20,16 @@ pub fn with_bolt_instrumented<F: FnOnce() -> anyhow::Result<R>, R>( let instrumented_path = tempfile::NamedTempFile::new()?.into_temp_path(); + let profile_dir = + tempfile::TempDir::new().context("Could not create directory for BOLT profiles")?; + let profile_prefix = profile_dir.path().join("prof.fdata"); + let profile_prefix = Utf8Path::from_path(&profile_prefix).unwrap(); + // Instrument the original file with BOLT, saving the result into `instrumented_path` cmd(&["llvm-bolt"]) .arg("-instrument") .arg(path) + .arg(&format!("--instrumentation-file={profile_prefix}")) // Make sure that each process will write its profiles into a separate file .arg("--instrumentation-file-append-pid") .arg("-o") @@ -36,11 +42,11 @@ pub fn with_bolt_instrumented<F: FnOnce() -> anyhow::Result<R>, R>( // Run the function that will make use of the instrumented artifact. // The original file will be restored when `_backup_file` is dropped. - func() + func(profile_prefix) } /// Optimizes the file at `path` with BOLT in-place using the given `profile`. -pub fn bolt_optimize(path: &Utf8Path, profile: &LlvmBoltProfile) -> anyhow::Result<()> { +pub fn bolt_optimize(path: &Utf8Path, profile: &BoltProfile) -> anyhow::Result<()> { // Copy the artifact to a new location, so that we do not use the same input and output file. // BOLT cannot handle optimizing when the input and output is the same file, because it performs // in-place patching. diff --git a/src/tools/opt-dist/src/exec.rs b/src/tools/opt-dist/src/exec.rs index 04e0184528a..90a045e83d7 100644 --- a/src/tools/opt-dist/src/exec.rs +++ b/src/tools/opt-dist/src/exec.rs @@ -1,7 +1,7 @@ use crate::environment::Environment; use crate::metrics::{load_metrics, record_metrics}; use crate::timer::TimerSection; -use crate::training::{LlvmBoltProfile, LlvmPGOProfile, RustcPGOProfile}; +use crate::training::{BoltProfile, LlvmPGOProfile, RustcPGOProfile}; use camino::{Utf8Path, Utf8PathBuf}; use std::collections::BTreeMap; use std::fs::File; @@ -159,7 +159,12 @@ impl Bootstrap { self } - pub fn with_bolt_profile(mut self, profile: LlvmBoltProfile) -> Self { + pub fn with_rustc_bolt_ldflags(mut self) -> Self { + self.cmd = self.cmd.arg("--enable-bolt-settings"); + self + } + + pub fn with_bolt_profile(mut self, profile: BoltProfile) -> Self { self.cmd = self.cmd.arg("--reproducible-artifact").arg(profile.0.as_str()); self } diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index 03a1912f5ce..9cdff84676e 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -12,7 +12,10 @@ use crate::environment::{Environment, EnvironmentBuilder}; use crate::exec::{cmd, Bootstrap}; use crate::tests::run_tests; use crate::timer::Timer; -use crate::training::{gather_llvm_bolt_profiles, gather_llvm_profiles, gather_rustc_profiles}; +use crate::training::{ + gather_bolt_profiles, gather_llvm_profiles, gather_rustc_profiles, llvm_benchmarks, + rustc_benchmarks, +}; use crate::utils::artifact_size::print_binary_sizes; use crate::utils::io::{copy_directory, move_directory, reset_directory}; use crate::utils::{ @@ -212,7 +215,12 @@ fn execute_pipeline( print_free_disk_space()?; stage.section("Build PGO optimized rustc", |section| { - Bootstrap::build(env).rustc_pgo_optimize(&profile).run(section) + let mut cmd = Bootstrap::build(env).rustc_pgo_optimize(&profile); + if env.use_bolt() { + cmd = cmd.with_rustc_bolt_ldflags(); + } + + cmd.run(section) })?; Ok(profile) @@ -246,13 +254,13 @@ fn execute_pipeline( Ok(profile) })?; - let llvm_bolt_profile = if env.use_bolt() { + let bolt_profiles = if env.use_bolt() { // Stage 3: Build BOLT instrumented LLVM // We build a PGO optimized LLVM in this step, then instrument it with BOLT and gather BOLT profiles. // Note that we don't remove LLVM artifacts after this step, so that they are reused in the final dist build. // BOLT instrumentation is performed "on-the-fly" when the LLVM library is copied to the sysroot of rustc, // therefore the LLVM artifacts on disk are not "tainted" with BOLT instrumentation and they can be reused. - timer.section("Stage 3 (LLVM BOLT)", |stage| { + timer.section("Stage 3 (BOLT)", |stage| { stage.section("Build PGO optimized LLVM", |stage| { Bootstrap::build(env) .with_llvm_bolt_ldflags() @@ -261,16 +269,17 @@ fn execute_pipeline( .run(stage) })?; - // Find the path to the `libLLVM.so` file - let llvm_lib = io::find_file_in_dir( - &env.build_artifacts().join("stage2").join("lib"), - "libLLVM", - ".so", - )?; + let libdir = env.build_artifacts().join("stage2").join("lib"); + let llvm_lib = io::find_file_in_dir(&libdir, "libLLVM", ".so")?; - // Instrument it and gather profiles - let profile = with_bolt_instrumented(&llvm_lib, || { - stage.section("Gather profiles", |_| gather_llvm_bolt_profiles(env)) + log::info!("Optimizing {llvm_lib} with BOLT"); + + // FIXME(kobzol): try gather profiles together, at once for LLVM and rustc + // Instrument the libraries and gather profiles + let llvm_profile = with_bolt_instrumented(&llvm_lib, |llvm_profile_dir| { + stage.section("Gather profiles", |_| { + gather_bolt_profiles(env, "LLVM", llvm_benchmarks(env), llvm_profile_dir) + }) })?; print_free_disk_space()?; @@ -279,13 +288,29 @@ fn execute_pipeline( // the final dist build. However, when BOLT optimizes an artifact, it does so *in-place*, // therefore it will actually optimize all the hard links, which means that the final // packaged `libLLVM.so` file *will* be BOLT optimized. - bolt_optimize(&llvm_lib, &profile).context("Could not optimize LLVM with BOLT")?; + bolt_optimize(&llvm_lib, &llvm_profile).context("Could not optimize LLVM with BOLT")?; + + let rustc_lib = io::find_file_in_dir(&libdir, "librustc_driver", ".so")?; + + log::info!("Optimizing {rustc_lib} with BOLT"); + + // Instrument it and gather profiles + let rustc_profile = with_bolt_instrumented(&rustc_lib, |rustc_profile_dir| { + stage.section("Gather profiles", |_| { + gather_bolt_profiles(env, "rustc", rustc_benchmarks(env), rustc_profile_dir) + }) + })?; + print_free_disk_space()?; + + // Now optimize the library with BOLT. + bolt_optimize(&rustc_lib, &rustc_profile) + .context("Could not optimize rustc with BOLT")?; // LLVM is not being cleared here, we want to use the BOLT-optimized LLVM - Ok(Some(profile)) + Ok(vec![llvm_profile, rustc_profile]) })? } else { - None + vec![] }; let mut dist = Bootstrap::dist(env, &dist_args) @@ -293,13 +318,13 @@ fn execute_pipeline( .rustc_pgo_optimize(&rustc_pgo_profile) .avoid_rustc_rebuild(); - if let Some(llvm_bolt_profile) = llvm_bolt_profile { - dist = dist.with_bolt_profile(llvm_bolt_profile); + for bolt_profile in bolt_profiles { + dist = dist.with_bolt_profile(bolt_profile); } // Final stage: Assemble the dist artifacts // The previous PGO optimized rustc build and PGO optimized LLVM builds should be reused. - timer.section("Stage 4 (final build)", |stage| dist.run(stage))?; + timer.section("Stage 5 (final build)", |stage| dist.run(stage))?; // After dist has finished, run a subset of the test suite on the optimized artifacts to discover // possible regressions. diff --git a/src/tools/opt-dist/src/training.rs b/src/tools/opt-dist/src/training.rs index 274f4cea0ab..46040e32a03 100644 --- a/src/tools/opt-dist/src/training.rs +++ b/src/tools/opt-dist/src/training.rs @@ -27,8 +27,6 @@ const RUSTC_PGO_CRATES: &[&str] = &[ "bitmaps-3.1.0", ]; -const LLVM_BOLT_CRATES: &[&str] = LLVM_PGO_CRATES; - fn init_compiler_benchmarks( env: &Environment, profiles: &[&str], @@ -113,6 +111,14 @@ fn log_profile_stats( Ok(()) } +pub fn llvm_benchmarks(env: &Environment) -> CmdBuilder { + init_compiler_benchmarks(env, &["Debug", "Opt"], &["Full"], LLVM_PGO_CRATES) +} + +pub fn rustc_benchmarks(env: &Environment) -> CmdBuilder { + init_compiler_benchmarks(env, &["Check", "Debug", "Opt"], &["All"], RUSTC_PGO_CRATES) +} + pub struct LlvmPGOProfile(pub Utf8PathBuf); pub fn gather_llvm_profiles( @@ -122,9 +128,7 @@ pub fn gather_llvm_profiles( log::info!("Running benchmarks with PGO instrumented LLVM"); with_log_group("Running benchmarks", || { - init_compiler_benchmarks(env, &["Debug", "Opt"], &["Full"], LLVM_PGO_CRATES) - .run() - .context("Cannot gather LLVM PGO profiles") + llvm_benchmarks(env).run().context("Cannot gather LLVM PGO profiles") })?; let merged_profile = env.artifact_dir().join("llvm-pgo.profdata"); @@ -157,7 +161,7 @@ pub fn gather_rustc_profiles( // Here we're profiling the `rustc` frontend, so we also include `Check`. // The benchmark set includes various stress tests that put the frontend under pressure. with_log_group("Running benchmarks", || { - init_compiler_benchmarks(env, &["Check", "Debug", "Opt"], &["All"], RUSTC_PGO_CRATES) + rustc_benchmarks(env) .env("LLVM_PROFILE_FILE", profile_template.as_str()) .run() .context("Cannot gather rustc PGO profiles") @@ -176,23 +180,25 @@ pub fn gather_rustc_profiles( Ok(RustcPGOProfile(merged_profile)) } -pub struct LlvmBoltProfile(pub Utf8PathBuf); +pub struct BoltProfile(pub Utf8PathBuf); -pub fn gather_llvm_bolt_profiles(env: &Environment) -> anyhow::Result<LlvmBoltProfile> { - log::info!("Running benchmarks with BOLT instrumented LLVM"); +pub fn gather_bolt_profiles( + env: &Environment, + name: &str, + benchmarks: CmdBuilder, + profile_prefix: &Utf8Path, +) -> anyhow::Result<BoltProfile> { + log::info!("Running benchmarks with BOLT instrumented {name}"); with_log_group("Running benchmarks", || { - init_compiler_benchmarks(env, &["Check", "Debug", "Opt"], &["Full"], LLVM_BOLT_CRATES) - .run() - .context("Cannot gather LLVM BOLT profiles") + benchmarks.run().with_context(|| "Cannot gather {name} BOLT profiles") })?; - let merged_profile = env.artifact_dir().join("llvm-bolt.profdata"); - let profile_root = Utf8PathBuf::from("/tmp/prof.fdata"); - log::info!("Merging LLVM BOLT profiles to {merged_profile}"); + let merged_profile = env.artifact_dir().join(format!("{name}-bolt.profdata")); + log::info!("Merging {name} BOLT profiles from {profile_prefix} to {merged_profile}"); let profiles: Vec<_> = - glob::glob(&format!("{profile_root}*"))?.collect::<Result<Vec<_>, _>>()?; + glob::glob(&format!("{profile_prefix}*"))?.collect::<Result<Vec<_>, _>>()?; let mut merge_args = vec!["merge-fdata"]; merge_args.extend(profiles.iter().map(|p| p.to_str().unwrap())); @@ -204,7 +210,7 @@ pub fn gather_llvm_bolt_profiles(env: &Environment) -> anyhow::Result<LlvmBoltPr .context("Cannot merge BOLT profiles") })?; - log::info!("LLVM BOLT statistics"); + log::info!("{name} BOLT statistics"); log::info!( "{merged_profile}: {}", humansize::format_size(std::fs::metadata(merged_profile.as_std_path())?.len(), BINARY) @@ -216,8 +222,17 @@ pub fn gather_llvm_bolt_profiles(env: &Environment) -> anyhow::Result<LlvmBoltPr .collect::<Result<Vec<_>, _>>()? .into_iter() .sum::<u64>(); - log::info!("{profile_root}: {}", humansize::format_size(size, BINARY)); + log::info!("{profile_prefix}: {}", humansize::format_size(size, BINARY)); log::info!("Profile file count: {}", profiles.len()); - Ok(LlvmBoltProfile(merged_profile)) + // Delete the gathered profiles + for profile in glob::glob(&format!("{profile_prefix}*"))?.into_iter() { + if let Ok(profile) = profile { + if let Err(error) = std::fs::remove_file(&profile) { + log::error!("Cannot delete BOLT profile {}: {error:?}", profile.display()); + } + } + } + + Ok(BoltProfile(merged_profile)) } diff --git a/src/tools/rustdoc-gui/tester.js b/src/tools/rustdoc-gui/tester.js index af1bc05ddb2..8f6626f6296 100644 --- a/src/tools/rustdoc-gui/tester.js +++ b/src/tools/rustdoc-gui/tester.js @@ -249,12 +249,17 @@ async function main(argv) { console.log("`--no-headless` option is active, disabling concurrency for running tests."); } - console.log(`Running ${files.length} rustdoc-gui (${opts["jobs"]} concurrently) ...`); - if (opts["jobs"] < 1) { + const len = files.length; + console.log( + `Running ${len} rustdoc-gui (UNBOUNDED concurrency; use "-j#" for a limit) ...`, + ); process.setMaxListeners(files.length + 1); } else if (headless) { + console.log(`Running ${files.length} rustdoc-gui (${opts["jobs"]} concurrently) ...`); process.setMaxListeners(opts["jobs"] + 1); + } else { + console.log(`Running ${files.length} rustdoc-gui ...`); } // We catch this "event" to display a nicer message in case of unexpected exit (because of a diff --git a/src/tools/tidy/src/alphabetical.rs b/src/tools/tidy/src/alphabetical.rs index fdc411c8925..3e60915c224 100644 --- a/src/tools/tidy/src/alphabetical.rs +++ b/src/tools/tidy/src/alphabetical.rs @@ -30,8 +30,8 @@ fn is_close_bracket(c: char) -> bool { } // Don't let tidy check this here :D -const START_COMMENT: &str = concat!("// tidy-alphabetical", "-start"); -const END_COMMENT: &str = "// tidy-alphabetical-end"; +const START_COMMENT: &str = concat!("tidy-alphabetical", "-start"); +const END_COMMENT: &str = "tidy-alphabetical-end"; fn check_section<'a>( file: impl Display, diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index d900c04c124..8e791a7dc69 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -30,7 +30,7 @@ const FEATURE_GROUP_END_PREFIX: &str = "// feature-group-end"; #[derive(Debug, PartialEq, Clone)] pub enum Status { - Stable, + Accepted, Removed, Unstable, } @@ -38,7 +38,7 @@ pub enum Status { impl fmt::Display for Status { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let as_str = match *self { - Status::Stable => "stable", + Status::Accepted => "accepted", Status::Unstable => "unstable", Status::Removed => "removed", }; @@ -279,9 +279,9 @@ fn test_filen_gate(filen_underscore: &str, features: &mut Features) -> bool { pub fn collect_lang_features(base_compiler_path: &Path, bad: &mut bool) -> Features { let mut features = Features::new(); - collect_lang_features_in(&mut features, base_compiler_path, "active.rs", bad); collect_lang_features_in(&mut features, base_compiler_path, "accepted.rs", bad); collect_lang_features_in(&mut features, base_compiler_path, "removed.rs", bad); + collect_lang_features_in(&mut features, base_compiler_path, "unstable.rs", bad); features } @@ -336,11 +336,11 @@ fn collect_lang_features_in(features: &mut Features, base: &Path, file: &str, ba let mut parts = line.split(','); let level = match parts.next().map(|l| l.trim().trim_start_matches('(')) { - Some("active") => Status::Unstable, + Some("unstable") => Status::Unstable, Some("incomplete") => Status::Unstable, Some("internal") => Status::Unstable, Some("removed") => Status::Removed, - Some("accepted") => Status::Stable, + Some("accepted") => Status::Accepted, _ => continue, }; let name = parts.next().unwrap().trim(); @@ -449,7 +449,7 @@ fn get_and_check_lib_features( Ok((name, f)) => { let mut check_features = |f: &Feature, list: &Features, display: &str| { if let Some(ref s) = list.get(name) { - if f.tracking_issue != s.tracking_issue && f.level != Status::Stable { + if f.tracking_issue != s.tracking_issue && f.level != Status::Accepted { tidy_error!( bad, "{}:{}: `issue` \"{}\" mismatches the {} `issue` of \"{}\"", @@ -566,7 +566,7 @@ fn map_lib_features( let level = if line.contains("[unstable(") { Status::Unstable } else if line.contains("[stable(") { - Status::Stable + Status::Accepted } else { continue; }; @@ -581,7 +581,7 @@ fn map_lib_features( Some(Err(_err)) => { err!("malformed stability attribute: can't parse `since` key"); } - None if level == Status::Stable => { + None if level == Status::Accepted => { err!("malformed stability attribute: missing the `since` key"); } None => None, diff --git a/tests/assembly/libs/issue-115339-zip-arrays.rs b/tests/assembly/libs/issue-115339-zip-arrays.rs new file mode 100644 index 00000000000..26b7b9770bc --- /dev/null +++ b/tests/assembly/libs/issue-115339-zip-arrays.rs @@ -0,0 +1,25 @@ +// assembly-output: emit-asm +// # zen3 previously exhibited odd vectorization +// compile-flags: --crate-type=lib -Ctarget-cpu=znver3 -O +// only-x86_64 +// ignore-sgx + +use std::iter; + +// previously this produced a long chain of +// 56: vpextrb $6, %xmm0, %ecx +// 57: orb %cl, 22(%rsi) +// 58: vpextrb $7, %xmm0, %ecx +// 59: orb %cl, 23(%rsi) +// [...] + +// CHECK-LABEL: zip_arrays: +#[no_mangle] +pub fn zip_arrays(mut a: [u8; 32], b: [u8; 32]) -> [u8; 32] { + // CHECK-NOT: vpextrb + // CHECK-NOT: orb %cl + // CHECK: vorps + iter::zip(&mut a, b).for_each(|(a, b)| *a |= b); + // CHECK: retq + a +} diff --git a/tests/codegen/target-feature-inline-closure.rs b/tests/codegen/target-feature-inline-closure.rs index d075706173f..54cb27242d5 100644 --- a/tests/codegen/target-feature-inline-closure.rs +++ b/tests/codegen/target-feature-inline-closure.rs @@ -31,3 +31,7 @@ unsafe fn without_avx(x: __m256) -> __m256 { }; add(x, x) } + +// Don't allow the above CHECK-NOT to accidentally match a commit hash in the +// compiler version. +// CHECK-LABEL: rustc version diff --git a/tests/codegen/vec_pop_push_noop.rs b/tests/codegen/vec_pop_push_noop.rs new file mode 100644 index 00000000000..8bc7b68a816 --- /dev/null +++ b/tests/codegen/vec_pop_push_noop.rs @@ -0,0 +1,24 @@ +// compile-flags: -O + +#![crate_type = "lib"] + +#[no_mangle] +// CHECK-LABEL: @noop( +pub fn noop(v: &mut Vec<u8>) { + // CHECK-NOT: reserve_for_push + // CHECK-NOT: call + // CHECK: tail call void @llvm.assume + // CHECK-NOT: reserve_for_push + // CHECK-NOT: call + // CHECK: ret + if let Some(x) = v.pop() { + v.push(x) + } +} + +#[no_mangle] +// CHECK-LABEL: @push_byte( +pub fn push_byte(v: &mut Vec<u8>) { + // CHECK: call {{.*}}reserve_for_push + v.push(3); +} diff --git a/tests/pretty/format-args-str-escape.pp b/tests/pretty/format-args-str-escape.pp new file mode 100644 index 00000000000..b84bc2303b7 --- /dev/null +++ b/tests/pretty/format-args-str-escape.pp @@ -0,0 +1,21 @@ +#![feature(prelude_import)] +#![no_std] +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; +// pretty-compare-only +// pretty-mode:expanded +// pp-exact:format-args-str-escape.pp + +fn main() { + { ::std::io::_print(format_args!("\u{1b}[1mHello, world!\u{1b}[0m\n")); }; + { ::std::io::_print(format_args!("\u{1b}[1mHello, world!\u{1b}[0m\n")); }; + { + ::std::io::_print(format_args!("Not an escape sequence: \\u{{1B}}[1mbold\\x1B[0m\n")); + }; + { + ::std::io::_print(format_args!("{0}\n", + "\x1B[1mHello, world!\x1B[0m")); + }; +} diff --git a/tests/pretty/format-args-str-escape.rs b/tests/pretty/format-args-str-escape.rs new file mode 100644 index 00000000000..e596fcfd8bc --- /dev/null +++ b/tests/pretty/format-args-str-escape.rs @@ -0,0 +1,10 @@ +// pretty-compare-only +// pretty-mode:expanded +// pp-exact:format-args-str-escape.pp + +fn main() { + println!("\x1B[1mHello, world!\x1B[0m"); + println!("\u{1B}[1mHello, world!\u{1B}[0m"); + println!("Not an escape sequence: \\u{{1B}}[1mbold\\x1B[0m"); + println!("{}", "\x1B[1mHello, world!\x1B[0m"); +} diff --git a/tests/run-make-fulldeps/issue-19371/foo.rs b/tests/run-make-fulldeps/issue-19371/foo.rs index 1c9d33dcc8e..7ee46e1520a 100644 --- a/tests/run-make-fulldeps/issue-19371/foo.rs +++ b/tests/run-make-fulldeps/issue-19371/foo.rs @@ -57,6 +57,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) { locale_resources: &[], lint_caps: Default::default(), parse_sess_created: None, + hash_untracked_state: None, register_lints: None, override_queries: None, make_codegen_backend: None, diff --git a/tests/run-make/wasm-override-linker/Makefile b/tests/run-make/wasm-override-linker/Makefile new file mode 100644 index 00000000000..52339f9261c --- /dev/null +++ b/tests/run-make/wasm-override-linker/Makefile @@ -0,0 +1,13 @@ +# needs-matching-clang + +include ../tools.mk + +ifeq ($(TARGET),wasm32-unknown-unknown) +all: + $(RUSTC) foo.rs --crate-type cdylib --target $(TARGET) -C linker=$(CLANG) +else ifeq ($(TARGET),wasm64-unknown-unknown) +all: + $(RUSTC) foo.rs --crate-type cdylib --target $(TARGET) -C linker=$(CLANG) +else +all: +endif diff --git a/tests/run-make/wasm-override-linker/foo.rs b/tests/run-make/wasm-override-linker/foo.rs new file mode 100644 index 00000000000..f4167a4fc4a --- /dev/null +++ b/tests/run-make/wasm-override-linker/foo.rs @@ -0,0 +1,6 @@ +#![crate_type = "cdylib"] + +#[no_mangle] +pub extern "C" fn add(a: i32, b: i32) -> i32 { + a + b +} diff --git a/tests/rustdoc-ui/issues/issue-96287.stderr b/tests/rustdoc-ui/issues/issue-96287.stderr index 7722eb96028..c4809a311fc 100644 --- a/tests/rustdoc-ui/issues/issue-96287.stderr +++ b/tests/rustdoc-ui/issues/issue-96287.stderr @@ -2,7 +2,12 @@ error[E0220]: associated type `Assoc` not found for `V` --> $DIR/issue-96287.rs:7:33 | LL | pub type Foo<V> = impl Trait<V::Assoc>; - | ^^^^^ there is a similarly named associated type `Assoc` in the trait `TraitWithAssoc` + | ^^^^^ there is an associated type `Assoc` in the trait `TraitWithAssoc` + | +help: consider restricting type parameter `V` + | +LL | pub type Foo<V: TraitWithAssoc> = impl Trait<V::Assoc>; + | ++++++++++++++++ error: aborting due to previous error diff --git a/tests/rustdoc/async-trait-sig.rs b/tests/rustdoc/async-trait-sig.rs index 2578bc8f7a1..db1848f716d 100644 --- a/tests/rustdoc/async-trait-sig.rs +++ b/tests/rustdoc/async-trait-sig.rs @@ -1,6 +1,5 @@ // edition:2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] pub trait Foo { diff --git a/tests/rustdoc/async-trait.rs b/tests/rustdoc/async-trait.rs index a473e467473..8de95aac22c 100644 --- a/tests/rustdoc/async-trait.rs +++ b/tests/rustdoc/async-trait.rs @@ -1,7 +1,6 @@ // aux-build:async-trait-dep.rs // edition:2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] extern crate async_trait_dep; diff --git a/tests/rustdoc/auxiliary/async-trait-dep.rs b/tests/rustdoc/auxiliary/async-trait-dep.rs index 10a55dd0260..d455ee99e09 100644 --- a/tests/rustdoc/auxiliary/async-trait-dep.rs +++ b/tests/rustdoc/auxiliary/async-trait-dep.rs @@ -1,6 +1,5 @@ // edition:2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] pub trait Meow { diff --git a/tests/rustdoc/inline_cross/attributes.rs b/tests/rustdoc/inline_cross/attributes.rs new file mode 100644 index 00000000000..c0b75c48fee --- /dev/null +++ b/tests/rustdoc/inline_cross/attributes.rs @@ -0,0 +1,7 @@ +// aux-crate:attributes=attributes.rs +// edition:2021 +#![crate_name = "user"] + +// @has 'user/struct.NonExhaustive.html' +// @has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[non_exhaustive]' +pub use attributes::NonExhaustive; diff --git a/tests/rustdoc/inline_cross/auxiliary/async-fn.rs b/tests/rustdoc/inline_cross/auxiliary/async-fn.rs index 767564ed145..564ca7d671e 100644 --- a/tests/rustdoc/inline_cross/auxiliary/async-fn.rs +++ b/tests/rustdoc/inline_cross/auxiliary/async-fn.rs @@ -1,4 +1,3 @@ -#![feature(async_fn_in_trait)] // edition: 2021 pub async fn load() -> i32 { diff --git a/tests/rustdoc/inline_cross/auxiliary/attributes.rs b/tests/rustdoc/inline_cross/auxiliary/attributes.rs new file mode 100644 index 00000000000..c6f155d4ba5 --- /dev/null +++ b/tests/rustdoc/inline_cross/auxiliary/attributes.rs @@ -0,0 +1,2 @@ +#[non_exhaustive] +pub struct NonExhaustive; diff --git a/tests/rustdoc/inline_cross/auxiliary/repr.rs b/tests/rustdoc/inline_cross/auxiliary/repr.rs index 4a6648a6439..35f08c11b7b 100644 --- a/tests/rustdoc/inline_cross/auxiliary/repr.rs +++ b/tests/rustdoc/inline_cross/auxiliary/repr.rs @@ -10,7 +10,7 @@ pub struct ReprSimd { } #[repr(transparent)] pub struct ReprTransparent { - field: u8, + pub field: u8, } #[repr(isize)] pub enum ReprIsize { @@ -20,3 +20,23 @@ pub enum ReprIsize { pub enum ReprU8 { Bla, } + +#[repr(transparent)] // private +pub struct ReprTransparentPrivField { + field: u32, // non-1-ZST field +} + +#[repr(transparent)] // public +pub struct ReprTransparentPriv1ZstFields { + marker0: Marker, + pub main: u64, // non-1-ZST field + marker1: Marker, +} + +#[repr(transparent)] // private +pub struct ReprTransparentPrivFieldPub1ZstFields { + main: [u16; 0], // non-1-ZST field + pub marker: Marker, +} + +pub struct Marker; // 1-ZST diff --git a/tests/rustdoc/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs b/tests/rustdoc/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs index c72f011152d..08a3f517671 100644 --- a/tests/rustdoc/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs +++ b/tests/rustdoc/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs @@ -1,5 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] - pub trait Trait { fn create() -> impl Iterator<Item = u64> { std::iter::empty() diff --git a/tests/rustdoc/inline_cross/repr.rs b/tests/rustdoc/inline_cross/repr.rs index 9e107cee9e9..2f3d8f00388 100644 --- a/tests/rustdoc/inline_cross/repr.rs +++ b/tests/rustdoc/inline_cross/repr.rs @@ -9,21 +9,32 @@ extern crate repr; // @has 'foo/struct.ReprC.html' // @has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(C, align(8))]' -#[doc(inline)] pub use repr::ReprC; // @has 'foo/struct.ReprSimd.html' // @has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(simd, packed(2))]' -#[doc(inline)] pub use repr::ReprSimd; // @has 'foo/struct.ReprTransparent.html' // @has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' -#[doc(inline)] pub use repr::ReprTransparent; // @has 'foo/enum.ReprIsize.html' // @has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(isize)]' -#[doc(inline)] pub use repr::ReprIsize; // @has 'foo/enum.ReprU8.html' // @has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(u8)]' -#[doc(inline)] pub use repr::ReprU8; + +// Regression test for <https://github.com/rust-lang/rust/issues/90435>. +// Check that we show `#[repr(transparent)]` iff the non-1-ZST field is public or at least one +// field is public in case all fields are 1-ZST fields. + +// @has 'foo/struct.ReprTransparentPrivField.html' +// @!has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' +pub use repr::ReprTransparentPrivField; + +// @has 'foo/struct.ReprTransparentPriv1ZstFields.html' +// @has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' +pub use repr::ReprTransparentPriv1ZstFields; + +// @has 'foo/struct.ReprTransparentPrivFieldPub1ZstFields.html' +// @!has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' +pub use repr::ReprTransparentPrivFieldPub1ZstFields; diff --git a/tests/rustdoc/repr.rs b/tests/rustdoc/repr.rs new file mode 100644 index 00000000000..fbb46e126ba --- /dev/null +++ b/tests/rustdoc/repr.rs @@ -0,0 +1,29 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/90435>. +// Check that we show `#[repr(transparent)]` iff the non-1-ZST field is public or at least one +// field is public in case all fields are 1-ZST fields. + +// @has 'repr/struct.ReprTransparentPrivField.html' +// @!has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' +#[repr(transparent)] // private +pub struct ReprTransparentPrivField { + field: u32, // non-1-ZST field +} + +// @has 'repr/struct.ReprTransparentPriv1ZstFields.html' +// @has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' +#[repr(transparent)] // public +pub struct ReprTransparentPriv1ZstFields { + marker0: Marker, + pub main: u64, // non-1-ZST field + marker1: Marker, +} + +// @has 'repr/struct.ReprTransparentPub1ZstField.html' +// @has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' +#[repr(transparent)] // public +pub struct ReprTransparentPub1ZstField { + marker0: Marker, + pub marker1: Marker, +} + +struct Marker; // 1-ZST diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.current.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.current.stderr index b8be132e6b6..65f7a72fbff 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.current.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.current.stderr @@ -25,7 +25,7 @@ LL | fn bar<T: Trait<method() -> (): Send>>() {} warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/bad-inputs-and-output.rs:5:12 | -LL | #![feature(return_type_notation, async_fn_in_trait)] +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.next.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.next.stderr index b8be132e6b6..65f7a72fbff 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.next.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.next.stderr @@ -25,7 +25,7 @@ LL | fn bar<T: Trait<method() -> (): Send>>() {} warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/bad-inputs-and-output.rs:5:12 | -LL | #![feature(return_type_notation, async_fn_in_trait)] +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs index 58ce41d1a89..4f332fa13d0 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs @@ -1,6 +1,6 @@ // edition: 2021 -#![feature(return_type_notation, async_fn_in_trait)] +#![feature(return_type_notation)] //~^ WARN the feature `return_type_notation` is incomplete trait Trait { diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr index 95ef7d82fca..1714dac12db 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr @@ -25,7 +25,7 @@ LL | fn bar<T: Trait<method() -> (): Send>>() {} warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/bad-inputs-and-output.rs:3:12 | -LL | #![feature(return_type_notation, async_fn_in_trait)] +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.current_with.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.current_with.stderr index 98c1a282779..c4dc5d36296 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.current_with.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.current_with.stderr @@ -1,7 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/basic.rs:8:12 | -LL | #![feature(return_type_notation, async_fn_in_trait)] +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.current_without.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.current_without.stderr index 1066c420c31..6c2645ae5bd 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.current_without.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.current_without.stderr @@ -1,7 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/basic.rs:8:12 | -LL | #![feature(return_type_notation, async_fn_in_trait)] +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.next_with.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.next_with.stderr index 98c1a282779..c4dc5d36296 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.next_with.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.next_with.stderr @@ -1,7 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/basic.rs:8:12 | -LL | #![feature(return_type_notation, async_fn_in_trait)] +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.next_without.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.next_without.stderr index 1066c420c31..6c2645ae5bd 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.next_without.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.next_without.stderr @@ -1,7 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/basic.rs:8:12 | -LL | #![feature(return_type_notation, async_fn_in_trait)] +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.rs b/tests/ui/associated-type-bounds/return-type-notation/basic.rs index 3dd9249a791..7f0647534f2 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.rs @@ -2,7 +2,7 @@ // edition: 2021 // [with] check-pass -#![feature(return_type_notation, async_fn_in_trait)] +#![feature(return_type_notation)] //~^ WARN the feature `return_type_notation` is incomplete trait Foo { diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.with.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.with.stderr index 9962f4706b3..9d4bb356caa 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.with.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.with.stderr @@ -1,7 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/basic.rs:5:12 | -LL | #![feature(return_type_notation, async_fn_in_trait)] +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr index edce1045e24..5b96676d037 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr @@ -1,7 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/basic.rs:5:12 | -LL | #![feature(return_type_notation, async_fn_in_trait)] +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.current.stderr b/tests/ui/associated-type-bounds/return-type-notation/equality.current.stderr index b631dd0ebb5..d2a445f3387 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/equality.current.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/equality.current.stderr @@ -1,7 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/equality.rs:5:12 | -LL | #![feature(return_type_notation, async_fn_in_trait)] +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.next.stderr b/tests/ui/associated-type-bounds/return-type-notation/equality.next.stderr index b631dd0ebb5..d2a445f3387 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/equality.next.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/equality.next.stderr @@ -1,7 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/equality.rs:5:12 | -LL | #![feature(return_type_notation, async_fn_in_trait)] +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.rs b/tests/ui/associated-type-bounds/return-type-notation/equality.rs index 6884305d7b3..d5a29616ac5 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/equality.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/equality.rs @@ -1,6 +1,6 @@ // edition: 2021 -#![feature(return_type_notation, async_fn_in_trait)] +#![feature(return_type_notation)] //~^ WARN the feature `return_type_notation` is incomplete use std::future::Future; diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.stderr b/tests/ui/associated-type-bounds/return-type-notation/equality.stderr index 490bfdc4c3c..1a2f8471524 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/equality.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/equality.stderr @@ -1,7 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/equality.rs:3:12 | -LL | #![feature(return_type_notation, async_fn_in_trait)] +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information diff --git a/tests/ui/associated-type-bounds/return-type-notation/missing.rs b/tests/ui/associated-type-bounds/return-type-notation/missing.rs index a52562d78f8..0679b96f6c5 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/missing.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/missing.rs @@ -1,6 +1,6 @@ // edition: 2021 -#![feature(return_type_notation, async_fn_in_trait)] +#![feature(return_type_notation)] //~^ WARN the feature `return_type_notation` is incomplete trait Trait { diff --git a/tests/ui/associated-type-bounds/return-type-notation/missing.stderr b/tests/ui/associated-type-bounds/return-type-notation/missing.stderr index 5b1c4cb0b2c..fb6538fa05c 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/missing.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/missing.stderr @@ -1,7 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/missing.rs:3:12 | -LL | #![feature(return_type_notation, async_fn_in_trait)] +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information diff --git a/tests/ui/async-await/async-trait-fn.current.stderr b/tests/ui/async-await/async-trait-fn.current.stderr deleted file mode 100644 index 7ccf2f2301d..00000000000 --- a/tests/ui/async-await/async-trait-fn.current.stderr +++ /dev/null @@ -1,42 +0,0 @@ -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/async-trait-fn.rs:6:5 - | -LL | async fn foo() {} - | -----^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/async-trait-fn.rs:7:5 - | -LL | async fn bar(&self) {} - | -----^^^^^^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/async-trait-fn.rs:8:5 - | -LL | async fn baz() { - | -----^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0706`. diff --git a/tests/ui/async-await/async-trait-fn.next.stderr b/tests/ui/async-await/async-trait-fn.next.stderr deleted file mode 100644 index 7ccf2f2301d..00000000000 --- a/tests/ui/async-await/async-trait-fn.next.stderr +++ /dev/null @@ -1,42 +0,0 @@ -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/async-trait-fn.rs:6:5 - | -LL | async fn foo() {} - | -----^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/async-trait-fn.rs:7:5 - | -LL | async fn bar(&self) {} - | -----^^^^^^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/async-trait-fn.rs:8:5 - | -LL | async fn baz() { - | -----^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0706`. diff --git a/tests/ui/async-await/async-trait-fn.rs b/tests/ui/async-await/async-trait-fn.rs index 04123badb53..4e5e3ba83e4 100644 --- a/tests/ui/async-await/async-trait-fn.rs +++ b/tests/ui/async-await/async-trait-fn.rs @@ -1,9 +1,10 @@ // edition:2018 +// check-pass trait T { - async fn foo() {} //~ ERROR functions in traits cannot be declared `async` - async fn bar(&self) {} //~ ERROR functions in traits cannot be declared `async` - async fn baz() { //~ ERROR functions in traits cannot be declared `async` + async fn foo() {} + async fn bar(&self) {} + async fn baz() { // Nested item must not ICE. fn a() {} } diff --git a/tests/ui/async-await/async-trait-fn.stderr b/tests/ui/async-await/async-trait-fn.stderr deleted file mode 100644 index 68ebe3507ac..00000000000 --- a/tests/ui/async-await/async-trait-fn.stderr +++ /dev/null @@ -1,42 +0,0 @@ -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/async-trait-fn.rs:4:5 - | -LL | async fn foo() {} - | -----^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/async-trait-fn.rs:5:5 - | -LL | async fn bar(&self) {} - | -----^^^^^^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/async-trait-fn.rs:6:5 - | -LL | async fn baz() { - | -----^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0706`. diff --git a/tests/ui/async-await/edition-deny-async-fns-2015.current.stderr b/tests/ui/async-await/edition-deny-async-fns-2015.current.stderr deleted file mode 100644 index c47b99e657e..00000000000 --- a/tests/ui/async-await/edition-deny-async-fns-2015.current.stderr +++ /dev/null @@ -1,98 +0,0 @@ -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:5:1 - | -LL | async fn foo() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:7:12 - | -LL | fn baz() { async fn foo() {} } - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:9:1 - | -LL | async fn async_baz() { - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:10:5 - | -LL | async fn bar() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:16:5 - | -LL | async fn foo() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:20:5 - | -LL | async fn foo() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:38:9 - | -LL | async fn bar() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:28:9 - | -LL | async fn foo() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:33:13 - | -LL | async fn bar() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/edition-deny-async-fns-2015.rs:20:5 - | -LL | async fn foo() {} - | -----^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error: aborting due to 10 previous errors - -Some errors have detailed explanations: E0670, E0706. -For more information about an error, try `rustc --explain E0670`. diff --git a/tests/ui/async-await/edition-deny-async-fns-2015.next.stderr b/tests/ui/async-await/edition-deny-async-fns-2015.next.stderr deleted file mode 100644 index c47b99e657e..00000000000 --- a/tests/ui/async-await/edition-deny-async-fns-2015.next.stderr +++ /dev/null @@ -1,98 +0,0 @@ -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:5:1 - | -LL | async fn foo() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:7:12 - | -LL | fn baz() { async fn foo() {} } - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:9:1 - | -LL | async fn async_baz() { - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:10:5 - | -LL | async fn bar() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:16:5 - | -LL | async fn foo() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:20:5 - | -LL | async fn foo() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:38:9 - | -LL | async fn bar() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:28:9 - | -LL | async fn foo() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:33:13 - | -LL | async fn bar() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 or later - | - = help: pass `--edition 2021` to `rustc` - = note: for more on editions, read https://doc.rust-lang.org/edition-guide - -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/edition-deny-async-fns-2015.rs:20:5 - | -LL | async fn foo() {} - | -----^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error: aborting due to 10 previous errors - -Some errors have detailed explanations: E0670, E0706. -For more information about an error, try `rustc --explain E0670`. diff --git a/tests/ui/async-await/edition-deny-async-fns-2015.rs b/tests/ui/async-await/edition-deny-async-fns-2015.rs index 6bd6d879a4a..9059f99ba66 100644 --- a/tests/ui/async-await/edition-deny-async-fns-2015.rs +++ b/tests/ui/async-await/edition-deny-async-fns-2015.rs @@ -16,7 +16,6 @@ impl Foo { trait Bar { async fn foo() {} //~ ERROR `async fn` is not permitted in Rust 2015 - //~^ ERROR functions in traits cannot be declared `async` } fn main() { diff --git a/tests/ui/async-await/edition-deny-async-fns-2015.stderr b/tests/ui/async-await/edition-deny-async-fns-2015.stderr index ba918eb28de..c40cdc5acec 100644 --- a/tests/ui/async-await/edition-deny-async-fns-2015.stderr +++ b/tests/ui/async-await/edition-deny-async-fns-2015.stderr @@ -53,7 +53,7 @@ LL | async fn foo() {} = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:36:9 + --> $DIR/edition-deny-async-fns-2015.rs:35:9 | LL | async fn bar() {} | ^^^^^ to use `async fn`, switch to Rust 2018 or later @@ -62,7 +62,7 @@ LL | async fn bar() {} = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:26:9 + --> $DIR/edition-deny-async-fns-2015.rs:25:9 | LL | async fn foo() {} | ^^^^^ to use `async fn`, switch to Rust 2018 or later @@ -71,7 +71,7 @@ LL | async fn foo() {} = note: for more on editions, read https://doc.rust-lang.org/edition-guide error[E0670]: `async fn` is not permitted in Rust 2015 - --> $DIR/edition-deny-async-fns-2015.rs:31:13 + --> $DIR/edition-deny-async-fns-2015.rs:30:13 | LL | async fn bar() {} | ^^^^^ to use `async fn`, switch to Rust 2018 or later @@ -79,20 +79,6 @@ LL | async fn bar() {} = help: pass `--edition 2021` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/edition-deny-async-fns-2015.rs:18:5 - | -LL | async fn foo() {} - | -----^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error: aborting due to 10 previous errors +error: aborting due to 9 previous errors -Some errors have detailed explanations: E0670, E0706. -For more information about an error, try `rustc --explain E0670`. +For more information about this error, try `rustc --explain E0670`. diff --git a/tests/ui/async-await/feature-gate-async_fn_in_trait.rs b/tests/ui/async-await/feature-gate-async_fn_in_trait.rs deleted file mode 100644 index 792f378cb57..00000000000 --- a/tests/ui/async-await/feature-gate-async_fn_in_trait.rs +++ /dev/null @@ -1,25 +0,0 @@ -// edition:2021 - -// RPITIT is not enough to allow use of async functions -#![allow(incomplete_features)] -#![feature(return_position_impl_trait_in_trait)] - -trait T { - async fn foo(); //~ ERROR functions in traits cannot be declared `async` -} - -// Both return_position_impl_trait_in_trait and async_fn_in_trait are required for this (see also -// feature-gate-return_position_impl_trait_in_trait.rs) -trait T2 { - async fn foo() -> impl Sized; //~ ERROR functions in traits cannot be declared `async` -} - -trait T3 { - fn foo() -> impl std::future::Future<Output = ()>; -} - -impl T3 for () { - async fn foo() {} //~ ERROR functions in traits cannot be declared `async` -} - -fn main() {} diff --git a/tests/ui/async-await/feature-gate-async_fn_in_trait.stderr b/tests/ui/async-await/feature-gate-async_fn_in_trait.stderr deleted file mode 100644 index 2a5fbd1ecd0..00000000000 --- a/tests/ui/async-await/feature-gate-async_fn_in_trait.stderr +++ /dev/null @@ -1,42 +0,0 @@ -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/feature-gate-async_fn_in_trait.rs:8:5 - | -LL | async fn foo(); - | -----^^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/feature-gate-async_fn_in_trait.rs:14:5 - | -LL | async fn foo() -> impl Sized; - | -----^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/feature-gate-async_fn_in_trait.rs:22:5 - | -LL | async fn foo() {} - | -----^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0706`. diff --git a/tests/ui/async-await/in-trait/async-associated-types.rs b/tests/ui/async-await/in-trait/async-associated-types.rs index 14f18811c1e..8d89500477b 100644 --- a/tests/ui/async-await/in-trait/async-associated-types.rs +++ b/tests/ui/async-await/in-trait/async-associated-types.rs @@ -1,9 +1,6 @@ // check-pass // edition: 2021 -#![feature(async_fn_in_trait)] -#![allow(incomplete_features)] - use std::fmt::Debug; trait MyTrait<'a, 'b, T> where Self: 'a, T: Debug + Sized + 'b { diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs index 8143f0bca03..c8fd2d8f6c2 100644 --- a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs +++ b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs @@ -1,7 +1,6 @@ // run-pass // edition:2021 -#![feature(async_fn_in_trait)] use std::future::Future; diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs index 38ba297189c..3cc11d241f7 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs @@ -1,7 +1,5 @@ // edition: 2021 -#![feature(async_fn_in_trait)] -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] use std::future::Future; diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr index 3f1f1766eb5..e6dd83b6b0a 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr @@ -1,11 +1,11 @@ error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/async-example-desugared-boxed-in-trait.rs:15:5 + --> $DIR/async-example-desugared-boxed-in-trait.rs:13:5 | LL | async fn foo(&self) -> i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<Box<dyn Future<Output = i32>>>`, found future | note: type in trait - --> $DIR/async-example-desugared-boxed-in-trait.rs:11:22 + --> $DIR/async-example-desugared-boxed-in-trait.rs:9:22 | LL | fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs b/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs index 1b1b3cffd58..81d25ce27ae 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs @@ -1,7 +1,5 @@ // edition: 2021 -#![feature(async_fn_in_trait)] -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] use std::future::Future; diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr index 60fa534a64f..cd18790fdfb 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr @@ -1,5 +1,5 @@ error: method `foo` should be async because the method from the trait is async - --> $DIR/async-example-desugared-boxed.rs:15:5 + --> $DIR/async-example-desugared-boxed.rs:13:5 | LL | async fn foo(&self) -> i32; | --------------------------- required because the trait method is async diff --git a/tests/ui/async-await/in-trait/async-example-desugared-extra.rs b/tests/ui/async-await/in-trait/async-example-desugared-extra.rs index 5d5aa817b4c..f0c59180fb5 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-extra.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared-extra.rs @@ -1,8 +1,7 @@ // check-pass // edition: 2021 -#![feature(async_fn_in_trait)] -#![feature(return_position_impl_trait_in_trait, lint_reasons)] +#![feature(lint_reasons)] #![allow(incomplete_features)] use std::future::Future; diff --git a/tests/ui/async-await/in-trait/async-example-desugared-in-trait.rs b/tests/ui/async-await/in-trait/async-example-desugared-in-trait.rs index feeda719e03..deca28af853 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-in-trait.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared-in-trait.rs @@ -1,8 +1,6 @@ // check-pass // edition: 2021 -#![feature(async_fn_in_trait)] -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] use std::future::Future; diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.rs b/tests/ui/async-await/in-trait/async-example-desugared-manual.rs index 71473e7455f..fdba4d93c77 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-manual.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared-manual.rs @@ -1,7 +1,5 @@ // edition: 2021 -#![feature(async_fn_in_trait)] -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] use std::future::Future; diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr b/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr index 567a36a86d1..463892f21bf 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr @@ -1,5 +1,5 @@ error: method `foo` should be async because the method from the trait is async - --> $DIR/async-example-desugared-manual.rs:23:5 + --> $DIR/async-example-desugared-manual.rs:21:5 | LL | async fn foo(&self) -> i32; | --------------------------- required because the trait method is async diff --git a/tests/ui/async-await/in-trait/async-example-desugared.rs b/tests/ui/async-await/in-trait/async-example-desugared.rs index 7987645c97b..7fc78f7da6d 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared.rs @@ -1,8 +1,6 @@ // check-pass // edition: 2021 -#![feature(async_fn_in_trait)] -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] use std::future::Future; diff --git a/tests/ui/async-await/in-trait/async-example.rs b/tests/ui/async-await/in-trait/async-example.rs index 8c80c21eabe..62ed490bf05 100644 --- a/tests/ui/async-await/in-trait/async-example.rs +++ b/tests/ui/async-await/in-trait/async-example.rs @@ -1,7 +1,6 @@ // check-pass // edition: 2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] trait MyTrait { diff --git a/tests/ui/async-await/in-trait/async-generics-and-bounds.rs b/tests/ui/async-await/in-trait/async-generics-and-bounds.rs index a73d55adfec..4e859fb27a9 100644 --- a/tests/ui/async-await/in-trait/async-generics-and-bounds.rs +++ b/tests/ui/async-await/in-trait/async-generics-and-bounds.rs @@ -2,7 +2,6 @@ // known-bug: #102682 // edition: 2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] use std::fmt::Debug; diff --git a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr b/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr index 965c385e9bc..d7251a52863 100644 --- a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr +++ b/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr @@ -1,5 +1,5 @@ error[E0311]: the parameter type `U` may not live long enough - --> $DIR/async-generics-and-bounds.rs:12:5 + --> $DIR/async-generics-and-bounds.rs:11:5 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Has | ++++ ++ ++ +++++++ error[E0311]: the parameter type `T` may not live long enough - --> $DIR/async-generics-and-bounds.rs:12:5 + --> $DIR/async-generics-and-bounds.rs:11:5 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/async-await/in-trait/async-generics.rs b/tests/ui/async-await/in-trait/async-generics.rs index 67000e5770e..2d342592848 100644 --- a/tests/ui/async-await/in-trait/async-generics.rs +++ b/tests/ui/async-await/in-trait/async-generics.rs @@ -2,7 +2,6 @@ // known-bug: #102682 // edition: 2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] trait MyTrait<T, U> { diff --git a/tests/ui/async-await/in-trait/async-generics.stderr b/tests/ui/async-await/in-trait/async-generics.stderr index 20c2491e9d0..aec62d12201 100644 --- a/tests/ui/async-await/in-trait/async-generics.stderr +++ b/tests/ui/async-await/in-trait/async-generics.stderr @@ -1,5 +1,5 @@ error[E0311]: the parameter type `U` may not live long enough - --> $DIR/async-generics.rs:9:5 + --> $DIR/async-generics.rs:8:5 | LL | async fn foo(&self) -> &(T, U); | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | async fn foo<'a>(&'a self) -> &'a (T, U) where U: 'a; | ++++ ++ ++ +++++++++++ error[E0311]: the parameter type `T` may not live long enough - --> $DIR/async-generics.rs:9:5 + --> $DIR/async-generics.rs:8:5 | LL | async fn foo(&self) -> &(T, U); | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/async-await/in-trait/async-lifetimes-and-bounds.rs b/tests/ui/async-await/in-trait/async-lifetimes-and-bounds.rs index 96cda4e35da..ea8330a4b52 100644 --- a/tests/ui/async-await/in-trait/async-lifetimes-and-bounds.rs +++ b/tests/ui/async-await/in-trait/async-lifetimes-and-bounds.rs @@ -1,7 +1,6 @@ // check-pass // edition: 2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] use std::fmt::Debug; diff --git a/tests/ui/async-await/in-trait/async-lifetimes.rs b/tests/ui/async-await/in-trait/async-lifetimes.rs index 4b0264bc8d0..6e573b9cc8b 100644 --- a/tests/ui/async-await/in-trait/async-lifetimes.rs +++ b/tests/ui/async-await/in-trait/async-lifetimes.rs @@ -1,7 +1,6 @@ // check-pass // edition: 2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] trait MyTrait<'a, 'b, T> { diff --git a/tests/ui/async-await/in-trait/async-recursive-generic.rs b/tests/ui/async-await/in-trait/async-recursive-generic.rs index 6839abd381c..34f1b09756e 100644 --- a/tests/ui/async-await/in-trait/async-recursive-generic.rs +++ b/tests/ui/async-await/in-trait/async-recursive-generic.rs @@ -1,6 +1,5 @@ // edition: 2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] trait MyTrait<T> { diff --git a/tests/ui/async-await/in-trait/async-recursive-generic.stderr b/tests/ui/async-await/in-trait/async-recursive-generic.stderr index 6897bf1c999..7c2df6683f0 100644 --- a/tests/ui/async-await/in-trait/async-recursive-generic.stderr +++ b/tests/ui/async-await/in-trait/async-recursive-generic.stderr @@ -1,5 +1,5 @@ error[E0733]: recursion in an `async fn` requires boxing - --> $DIR/async-recursive-generic.rs:11:5 + --> $DIR/async-recursive-generic.rs:10:5 | LL | async fn foo_recursive(&self, n: usize) -> T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive `async fn` diff --git a/tests/ui/async-await/in-trait/async-recursive.rs b/tests/ui/async-await/in-trait/async-recursive.rs index 61119f8095b..ddf119b252f 100644 --- a/tests/ui/async-await/in-trait/async-recursive.rs +++ b/tests/ui/async-await/in-trait/async-recursive.rs @@ -1,6 +1,5 @@ // edition: 2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] trait MyTrait { diff --git a/tests/ui/async-await/in-trait/async-recursive.stderr b/tests/ui/async-await/in-trait/async-recursive.stderr index c9b4784e3b4..1253252cc40 100644 --- a/tests/ui/async-await/in-trait/async-recursive.stderr +++ b/tests/ui/async-await/in-trait/async-recursive.stderr @@ -1,5 +1,5 @@ error[E0733]: recursion in an `async fn` requires boxing - --> $DIR/async-recursive.rs:11:5 + --> $DIR/async-recursive.rs:10:5 | LL | async fn foo_recursive(&self, n: usize) -> i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive `async fn` diff --git a/tests/ui/async-await/in-trait/auxiliary/foreign-async-fn.rs b/tests/ui/async-await/in-trait/auxiliary/foreign-async-fn.rs index bba886f175e..57c9b3ae8b3 100644 --- a/tests/ui/async-await/in-trait/auxiliary/foreign-async-fn.rs +++ b/tests/ui/async-await/in-trait/auxiliary/foreign-async-fn.rs @@ -1,7 +1,5 @@ // edition:2021 -#![feature(async_fn_in_trait)] - pub trait Foo { async fn test(); } diff --git a/tests/ui/async-await/in-trait/bad-signatures.rs b/tests/ui/async-await/in-trait/bad-signatures.rs index 98dddc126c5..5adede5b5cf 100644 --- a/tests/ui/async-await/in-trait/bad-signatures.rs +++ b/tests/ui/async-await/in-trait/bad-signatures.rs @@ -1,6 +1,5 @@ // edition:2021 -#![feature(async_fn_in_trait)] trait MyTrait { async fn bar(&abc self); diff --git a/tests/ui/async-await/in-trait/bad-signatures.stderr b/tests/ui/async-await/in-trait/bad-signatures.stderr index 7cbd96e2487..127a343a930 100644 --- a/tests/ui/async-await/in-trait/bad-signatures.stderr +++ b/tests/ui/async-await/in-trait/bad-signatures.stderr @@ -1,11 +1,11 @@ error: expected identifier, found keyword `self` - --> $DIR/bad-signatures.rs:6:23 + --> $DIR/bad-signatures.rs:5:23 | LL | async fn bar(&abc self); | ^^^^ expected identifier, found keyword error: expected one of `:`, `@`, or `|`, found keyword `self` - --> $DIR/bad-signatures.rs:6:23 + --> $DIR/bad-signatures.rs:5:23 | LL | async fn bar(&abc self); | -----^^^^ diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs index afd3db5e052..18b0fa4856d 100644 --- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs @@ -1,7 +1,6 @@ // edition: 2021 // known-bug: #108309 -#![feature(async_fn_in_trait)] #![feature(min_specialization)] struct MyStruct; diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr index 4ba6d4cba0c..5e2be08623b 100644 --- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr @@ -1,11 +1,11 @@ error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/dont-project-to-specializable-projection.rs:14:5 + --> $DIR/dont-project-to-specializable-projection.rs:13:5 | LL | default async fn foo(_: T) -> &'static str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found future | note: type in trait - --> $DIR/dont-project-to-specializable-projection.rs:10:5 + --> $DIR/dont-project-to-specializable-projection.rs:9:5 | LL | async fn foo(_: T) -> &'static str; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,12 +13,12 @@ LL | async fn foo(_: T) -> &'static str; found signature `fn(_) -> impl Future<Output = &'static str>` error: async associated function in trait cannot be specialized - --> $DIR/dont-project-to-specializable-projection.rs:14:5 + --> $DIR/dont-project-to-specializable-projection.rs:13:5 | LL | default async fn foo(_: T) -> &'static str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: specialization behaves in inconsistent and surprising ways with `#![feature(async_fn_in_trait)]`, and for now is disallowed + = note: specialization behaves in inconsistent and surprising ways with async functions in traits, and for now is disallowed error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/in-trait/early-bound-1.rs b/tests/ui/async-await/in-trait/early-bound-1.rs index bc410cc2954..f79d6f23c93 100644 --- a/tests/ui/async-await/in-trait/early-bound-1.rs +++ b/tests/ui/async-await/in-trait/early-bound-1.rs @@ -1,7 +1,6 @@ // check-pass // edition:2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] pub trait Foo { diff --git a/tests/ui/async-await/in-trait/early-bound-2.rs b/tests/ui/async-await/in-trait/early-bound-2.rs index 1974b1d9f7a..3eba5bf757f 100644 --- a/tests/ui/async-await/in-trait/early-bound-2.rs +++ b/tests/ui/async-await/in-trait/early-bound-2.rs @@ -1,7 +1,6 @@ // check-pass // edition:2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] pub trait Foo { diff --git a/tests/ui/async-await/in-trait/fn-not-async-err.rs b/tests/ui/async-await/in-trait/fn-not-async-err.rs index 9598d53bce8..60077a7e00c 100644 --- a/tests/ui/async-await/in-trait/fn-not-async-err.rs +++ b/tests/ui/async-await/in-trait/fn-not-async-err.rs @@ -1,6 +1,5 @@ // edition: 2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] trait MyTrait { diff --git a/tests/ui/async-await/in-trait/fn-not-async-err.stderr b/tests/ui/async-await/in-trait/fn-not-async-err.stderr index 579801d0f39..cd085074ae3 100644 --- a/tests/ui/async-await/in-trait/fn-not-async-err.stderr +++ b/tests/ui/async-await/in-trait/fn-not-async-err.stderr @@ -1,5 +1,5 @@ error: method `foo` should be async because the method from the trait is async - --> $DIR/fn-not-async-err.rs:11:5 + --> $DIR/fn-not-async-err.rs:10:5 | LL | async fn foo(&self) -> i32; | --------------------------- required because the trait method is async diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.rs b/tests/ui/async-await/in-trait/fn-not-async-err2.rs index e1703415dbd..ed626edc4c4 100644 --- a/tests/ui/async-await/in-trait/fn-not-async-err2.rs +++ b/tests/ui/async-await/in-trait/fn-not-async-err2.rs @@ -1,6 +1,6 @@ // edition: 2021 +// check-pass -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] use std::future::Future; @@ -11,7 +11,6 @@ trait MyTrait { impl MyTrait for i32 { fn foo(&self) -> impl Future<Output = i32> { - //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types, not in `impl` method return types async { *self } } } diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.stderr b/tests/ui/async-await/in-trait/fn-not-async-err2.stderr deleted file mode 100644 index a7c897f786e..00000000000 --- a/tests/ui/async-await/in-trait/fn-not-async-err2.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `impl` method return types - --> $DIR/fn-not-async-err2.rs:13:22 - | -LL | fn foo(&self) -> impl Future<Output = i32> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/async-await/in-trait/generics-mismatch.rs b/tests/ui/async-await/in-trait/generics-mismatch.rs index fc29783c0e3..51fdc2fe8a8 100644 --- a/tests/ui/async-await/in-trait/generics-mismatch.rs +++ b/tests/ui/async-await/in-trait/generics-mismatch.rs @@ -1,6 +1,5 @@ // edition: 2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] trait Foo { diff --git a/tests/ui/async-await/in-trait/generics-mismatch.stderr b/tests/ui/async-await/in-trait/generics-mismatch.stderr index 3518aa05cec..647cc698f9f 100644 --- a/tests/ui/async-await/in-trait/generics-mismatch.stderr +++ b/tests/ui/async-await/in-trait/generics-mismatch.stderr @@ -1,5 +1,5 @@ error[E0053]: method `foo` has an incompatible generic parameter for trait `Foo` - --> $DIR/generics-mismatch.rs:11:18 + --> $DIR/generics-mismatch.rs:10:18 | LL | trait Foo { | --- diff --git a/tests/ui/async-await/in-trait/implied-bounds.rs b/tests/ui/async-await/in-trait/implied-bounds.rs index 40eebad86c2..0d8177c8e60 100644 --- a/tests/ui/async-await/in-trait/implied-bounds.rs +++ b/tests/ui/async-await/in-trait/implied-bounds.rs @@ -1,7 +1,6 @@ // check-pass // edition: 2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] trait TcpStack { diff --git a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.rs b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.rs index 2fe6b473df6..8443cbcf4ac 100644 --- a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.rs +++ b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.rs @@ -2,8 +2,6 @@ // build-fail //~^^ ERROR cycle detected when computing layout of -#![feature(async_fn_in_trait)] - fn main() { let _ = async { A.first().await.second().await; diff --git a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr index 41e84466a14..ce02c1e9967 100644 --- a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr +++ b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr @@ -1,8 +1,8 @@ -error[E0391]: cycle detected when computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:35:27: 37:6}` +error[E0391]: cycle detected when computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}` | = note: ...which requires computing layout of `<<A as First>::Second as Second>::{opaque#0}`... - = note: ...which again requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:35:27: 37:6}`, completing the cycle - = note: cycle used when computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:8:13: 10:6}` + = note: ...which again requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}`, completing the cycle + = note: cycle used when computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:6:13: 8:6}` = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/async-await/in-trait/issue-102138.rs b/tests/ui/async-await/in-trait/issue-102138.rs index 3d9cef0210f..221b830fc5f 100644 --- a/tests/ui/async-await/in-trait/issue-102138.rs +++ b/tests/ui/async-await/in-trait/issue-102138.rs @@ -1,7 +1,6 @@ // check-pass // edition:2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] use std::future::Future; diff --git a/tests/ui/async-await/in-trait/issue-102219.rs b/tests/ui/async-await/in-trait/issue-102219.rs index 4a23e4be4f7..1f32cf691eb 100644 --- a/tests/ui/async-await/in-trait/issue-102219.rs +++ b/tests/ui/async-await/in-trait/issue-102219.rs @@ -2,7 +2,6 @@ // edition:2021 // check-pass -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] trait T { diff --git a/tests/ui/async-await/in-trait/issue-102310.rs b/tests/ui/async-await/in-trait/issue-102310.rs index 327d432a6a6..c6321dfcbe8 100644 --- a/tests/ui/async-await/in-trait/issue-102310.rs +++ b/tests/ui/async-await/in-trait/issue-102310.rs @@ -1,7 +1,6 @@ // check-pass // edition:2021 -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] pub trait SpiDevice { diff --git a/tests/ui/async-await/in-trait/issue-104678.rs b/tests/ui/async-await/in-trait/issue-104678.rs index 0a334707505..db2fa3026fc 100644 --- a/tests/ui/async-await/in-trait/issue-104678.rs +++ b/tests/ui/async-await/in-trait/issue-104678.rs @@ -1,7 +1,6 @@ // edition:2021 // check-pass -#![feature(async_fn_in_trait)] #![allow(incomplete_features)] use std::future::Future; diff --git a/tests/ui/async-await/in-trait/lifetime-mismatch.rs b/tests/ui/async-await/in-trait/lifetime-mismatch.rs index bb793df5d85..b45d1758da4 100644 --- a/tests/ui/async-await/in-trait/lifetime-mismatch.rs +++ b/tests/ui/async-await/in-trait/lifetime-mismatch.rs @@ -1,6 +1,5 @@ // edition:2021 -#![feature(async_fn_in_trait)] trait MyTrait { async fn foo<'a>(&self); diff --git a/tests/ui/async-await/in-trait/lifetime-mismatch.stderr b/tests/ui/async-await/in-trait/lifetime-mismatch.stderr index 86592269c02..3841ab9345f 100644 --- a/tests/ui/async-await/in-trait/lifetime-mismatch.stderr +++ b/tests/ui/async-await/in-trait/lifetime-mismatch.stderr @@ -1,5 +1,5 @@ error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration - --> $DIR/lifetime-mismatch.rs:11:17 + --> $DIR/lifetime-mismatch.rs:10:17 | LL | async fn foo<'a>(&self); | ---- lifetimes in impl do not match this method in trait diff --git a/tests/ui/async-await/in-trait/missing-feature-flag.rs b/tests/ui/async-await/in-trait/missing-feature-flag.rs index 34dd50a1c30..898299a7d9d 100644 --- a/tests/ui/async-await/in-trait/missing-feature-flag.rs +++ b/tests/ui/async-await/in-trait/missing-feature-flag.rs @@ -1,6 +1,5 @@ // edition:2018 -#![feature(async_fn_in_trait)] #![feature(min_specialization)] struct MyStruct; diff --git a/tests/ui/async-await/in-trait/missing-feature-flag.stderr b/tests/ui/async-await/in-trait/missing-feature-flag.stderr index 87a7e85bfbb..b7a9e98fc49 100644 --- a/tests/ui/async-await/in-trait/missing-feature-flag.stderr +++ b/tests/ui/async-await/in-trait/missing-feature-flag.stderr @@ -1,5 +1,5 @@ error[E0046]: not all trait items implemented, missing: `foo` - --> $DIR/missing-feature-flag.rs:12:1 + --> $DIR/missing-feature-flag.rs:11:1 | LL | async fn foo(_: T) -> &'static str; | ----------------------------------- `foo` from trait @@ -8,13 +8,13 @@ LL | impl<T> MyTrait<T> for MyStruct {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation error[E0308]: mismatched types - --> $DIR/missing-feature-flag.rs:16:42 + --> $DIR/missing-feature-flag.rs:15:42 | LL | async fn foo(_: i32) -> &'static str {} | ^^ expected `&str`, found `()` error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default` - --> $DIR/missing-feature-flag.rs:16:5 + --> $DIR/missing-feature-flag.rs:15:5 | LL | impl<T> MyTrait<T> for MyStruct {} | ------------------------------- parent `impl` is here diff --git a/tests/ui/async-await/in-trait/missing-send-bound.rs b/tests/ui/async-await/in-trait/missing-send-bound.rs index dbcc6657618..596aece748d 100644 --- a/tests/ui/async-await/in-trait/missing-send-bound.rs +++ b/tests/ui/async-await/in-trait/missing-send-bound.rs @@ -1,6 +1,5 @@ // edition:2021 -#![feature(async_fn_in_trait)] trait Foo { async fn bar(); diff --git a/tests/ui/async-await/in-trait/missing-send-bound.stderr b/tests/ui/async-await/in-trait/missing-send-bound.stderr index 7e59d94d456..139bd06c7df 100644 --- a/tests/ui/async-await/in-trait/missing-send-bound.stderr +++ b/tests/ui/async-await/in-trait/missing-send-bound.stderr @@ -1,17 +1,17 @@ error: future cannot be sent between threads safely - --> $DIR/missing-send-bound.rs:14:20 + --> $DIR/missing-send-bound.rs:13:20 | LL | assert_is_send(test::<T>()); | ^^^^^^^^^^^ future returned by `test` is not `Send` | = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `impl Future<Output = ()>` note: future is not `Send` as it awaits another future which is not `Send` - --> $DIR/missing-send-bound.rs:10:5 + --> $DIR/missing-send-bound.rs:9:5 | LL | T::bar().await; | ^^^^^^^^ await occurs here on type `impl Future<Output = ()>`, which is not `Send` note: required by a bound in `assert_is_send` - --> $DIR/missing-send-bound.rs:18:27 + --> $DIR/missing-send-bound.rs:17:27 | LL | fn assert_is_send(_: impl Send) {} | ^^^^ required by this bound in `assert_is_send` diff --git a/tests/ui/async-await/in-trait/nested-rpit.rs b/tests/ui/async-await/in-trait/nested-rpit.rs index 8c43e1b07e2..ccae08accb6 100644 --- a/tests/ui/async-await/in-trait/nested-rpit.rs +++ b/tests/ui/async-await/in-trait/nested-rpit.rs @@ -1,8 +1,6 @@ // edition: 2021 // check-pass -#![feature(async_fn_in_trait)] -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] use std::future::Future; diff --git a/tests/ui/async-await/in-trait/normalize-opaque-with-bound-vars.rs b/tests/ui/async-await/in-trait/normalize-opaque-with-bound-vars.rs index f8fe0d1bde8..9eb396f3202 100644 --- a/tests/ui/async-await/in-trait/normalize-opaque-with-bound-vars.rs +++ b/tests/ui/async-await/in-trait/normalize-opaque-with-bound-vars.rs @@ -5,7 +5,6 @@ // We were not normalizing opaques with escaping bound vars during codegen, // leading to later errors during debuginfo computation. -#![feature(async_fn_in_trait)] #[derive(Clone, Copy)] pub struct SharedState {} diff --git a/tests/ui/async-await/in-trait/object-safety.rs b/tests/ui/async-await/in-trait/object-safety.rs index 441539e5dd4..5e5375b082b 100644 --- a/tests/ui/async-await/in-trait/object-safety.rs +++ b/tests/ui/async-await/in-trait/object-safety.rs @@ -1,6 +1,5 @@ // edition:2021 -#![feature(async_fn_in_trait)] trait Foo { async fn foo(&self); diff --git a/tests/ui/async-await/in-trait/object-safety.stderr b/tests/ui/async-await/in-trait/object-safety.stderr index ccdf9d88708..5b9fd98ac60 100644 --- a/tests/ui/async-await/in-trait/object-safety.stderr +++ b/tests/ui/async-await/in-trait/object-safety.stderr @@ -1,11 +1,11 @@ error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:10:12 + --> $DIR/object-safety.rs:9:12 | LL | let x: &dyn Foo = todo!(); | ^^^^^^^^ `Foo` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> - --> $DIR/object-safety.rs:6:14 + --> $DIR/object-safety.rs:5:14 | LL | trait Foo { | --- this trait cannot be made into an object... diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.rs b/tests/ui/async-await/in-trait/return-not-existing-pair.rs index a14dfceed75..2286316dd88 100644 --- a/tests/ui/async-await/in-trait/return-not-existing-pair.rs +++ b/tests/ui/async-await/in-trait/return-not-existing-pair.rs @@ -1,6 +1,5 @@ // edition:2021 -#![feature(async_fn_in_trait)] trait MyTrait<'a, 'b, T> { async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.stderr b/tests/ui/async-await/in-trait/return-not-existing-pair.stderr index e573b851706..4694e608097 100644 --- a/tests/ui/async-await/in-trait/return-not-existing-pair.stderr +++ b/tests/ui/async-await/in-trait/return-not-existing-pair.stderr @@ -1,5 +1,5 @@ error[E0726]: implicit elided lifetime not allowed here - --> $DIR/return-not-existing-pair.rs:10:20 + --> $DIR/return-not-existing-pair.rs:9:20 | LL | impl<'a, 'b, T, U> MyTrait<T> for U { | ^^^^^^^^^^ expected lifetime parameters @@ -10,13 +10,13 @@ LL | impl<'a, 'b, T, U> MyTrait<'_, '_, T> for U { | +++++++ error[E0412]: cannot find type `ConnImpl` in this scope - --> $DIR/return-not-existing-pair.rs:6:48 + --> $DIR/return-not-existing-pair.rs:5:48 | LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); | ^^^^^^^^ not found in this scope error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl - --> $DIR/return-not-existing-pair.rs:12:5 + --> $DIR/return-not-existing-pair.rs:11:5 | LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); | ------------------------------------------------------------ `&self` used in trait @@ -25,7 +25,7 @@ LL | async fn foo(_: T) -> (&'a U, &'b T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&self` in impl error[E0308]: mismatched types - --> $DIR/return-not-existing-pair.rs:12:42 + --> $DIR/return-not-existing-pair.rs:11:42 | LL | async fn foo(_: T) -> (&'a U, &'b T) {} | ^^ expected `(&U, &T)`, found `()` diff --git a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs index 254b9a7824f..d23ef093be1 100644 --- a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs +++ b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs @@ -1,6 +1,5 @@ // edition:2021 -#![feature(return_position_impl_trait_in_trait)] struct Wrapper<T>(T); diff --git a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.stderr b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.stderr index 059934d245c..a66dd13bb7a 100644 --- a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.stderr +++ b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `Missing` in this scope - --> $DIR/return-not-existing-type-wrapping-rpitit.rs:8:25 + --> $DIR/return-not-existing-type-wrapping-rpitit.rs:7:25 | LL | fn bar() -> Wrapper<Missing<impl Sized>>; | ^^^^^^^ not found in this scope diff --git a/tests/ui/async-await/in-trait/return-type-suggestion.rs b/tests/ui/async-await/in-trait/return-type-suggestion.rs index cdab4ea0f37..2b19b24cf7a 100644 --- a/tests/ui/async-await/in-trait/return-type-suggestion.rs +++ b/tests/ui/async-await/in-trait/return-type-suggestion.rs @@ -1,6 +1,5 @@ // edition: 2021 -#![feature(async_fn_in_trait)] trait A { async fn e() { diff --git a/tests/ui/async-await/in-trait/return-type-suggestion.stderr b/tests/ui/async-await/in-trait/return-type-suggestion.stderr index 179c9ed93db..363870619f0 100644 --- a/tests/ui/async-await/in-trait/return-type-suggestion.stderr +++ b/tests/ui/async-await/in-trait/return-type-suggestion.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/return-type-suggestion.rs:7:9 + --> $DIR/return-type-suggestion.rs:6:9 | LL | Ok(()) | ^^^^^^ expected `()`, found `Result<(), _>` diff --git a/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.fixed b/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.fixed index 33c00587439..affe6cded8f 100644 --- a/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.fixed +++ b/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.fixed @@ -1,7 +1,6 @@ // run-rustfix // edition: 2021 -#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)] #![allow(unused)] trait Foo { diff --git a/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.rs b/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.rs index 96b623d6988..02bfee1a25f 100644 --- a/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.rs +++ b/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.rs @@ -1,7 +1,6 @@ // run-rustfix // edition: 2021 -#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)] #![allow(unused)] trait Foo { diff --git a/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.stderr b/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.stderr index 4319a14118b..da51f10af94 100644 --- a/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.stderr +++ b/tests/ui/async-await/in-trait/send-on-async-fn-in-trait.stderr @@ -1,5 +1,5 @@ error[E0277]: `impl Future<Output = ()>` cannot be sent between threads safely - --> $DIR/send-on-async-fn-in-trait.rs:14:16 + --> $DIR/send-on-async-fn-in-trait.rs:13:16 | LL | needs_send(T::test()); | ---------- ^^^^^^^^^ `impl Future<Output = ()>` cannot be sent between threads safely @@ -8,7 +8,7 @@ LL | needs_send(T::test()); | = help: the trait `Send` is not implemented for `impl Future<Output = ()>` note: required by a bound in `needs_send` - --> $DIR/send-on-async-fn-in-trait.rs:13:27 + --> $DIR/send-on-async-fn-in-trait.rs:12:27 | LL | fn needs_send(_: impl Send) {} | ^^^^ required by this bound in `needs_send` @@ -19,7 +19,7 @@ LL + fn test() -> impl std::future::Future<Output = ()> + Send { async {} } | error[E0277]: `impl Future<Output = i32>` cannot be sent between threads safely - --> $DIR/send-on-async-fn-in-trait.rs:16:16 + --> $DIR/send-on-async-fn-in-trait.rs:15:16 | LL | needs_send(T::test2()); | ---------- ^^^^^^^^^^ `impl Future<Output = i32>` cannot be sent between threads safely @@ -28,7 +28,7 @@ LL | needs_send(T::test2()); | = help: the trait `Send` is not implemented for `impl Future<Output = i32>` note: required by a bound in `needs_send` - --> $DIR/send-on-async-fn-in-trait.rs:13:27 + --> $DIR/send-on-async-fn-in-trait.rs:12:27 | LL | fn needs_send(_: impl Send) {} | ^^^^ required by this bound in `needs_send` diff --git a/tests/ui/async-await/in-trait/send-on-foreign-async-fn-in-trait.rs b/tests/ui/async-await/in-trait/send-on-foreign-async-fn-in-trait.rs index 83b69d72a96..f0d750714cd 100644 --- a/tests/ui/async-await/in-trait/send-on-foreign-async-fn-in-trait.rs +++ b/tests/ui/async-await/in-trait/send-on-foreign-async-fn-in-trait.rs @@ -1,8 +1,6 @@ // aux-build:foreign-async-fn.rs // edition:2021 -#![feature(async_fn_in_trait)] - extern crate foreign_async_fn; use foreign_async_fn::Foo; diff --git a/tests/ui/async-await/in-trait/send-on-foreign-async-fn-in-trait.stderr b/tests/ui/async-await/in-trait/send-on-foreign-async-fn-in-trait.stderr index f337a04ba19..482707351d7 100644 --- a/tests/ui/async-await/in-trait/send-on-foreign-async-fn-in-trait.stderr +++ b/tests/ui/async-await/in-trait/send-on-foreign-async-fn-in-trait.stderr @@ -1,5 +1,5 @@ error[E0277]: `impl Future<Output = ()>` cannot be sent between threads safely - --> $DIR/send-on-foreign-async-fn-in-trait.rs:11:16 + --> $DIR/send-on-foreign-async-fn-in-trait.rs:9:16 | LL | needs_send(T::test()); | ---------- ^^^^^^^^^ `impl Future<Output = ()>` cannot be sent between threads safely @@ -8,12 +8,12 @@ LL | needs_send(T::test()); | = help: the trait `Send` is not implemented for `impl Future<Output = ()>` note: `<T as Foo>::test` is an `async fn` in trait, which does not automatically imply that its future is `Send` - --> $DIR/auxiliary/foreign-async-fn.rs:6:5 + --> $DIR/auxiliary/foreign-async-fn.rs:4:5 | LL | async fn test(); | ^^^^^^^^^^^^^^^^ note: required by a bound in `needs_send` - --> $DIR/send-on-foreign-async-fn-in-trait.rs:10:27 + --> $DIR/send-on-foreign-async-fn-in-trait.rs:8:27 | LL | fn needs_send(_: impl Send) {} | ^^^^ required by this bound in `needs_send` diff --git a/tests/ui/async-await/in-trait/warn.rs b/tests/ui/async-await/in-trait/warn.rs index 4f981c31f5c..71f3822dfb1 100644 --- a/tests/ui/async-await/in-trait/warn.rs +++ b/tests/ui/async-await/in-trait/warn.rs @@ -1,6 +1,5 @@ // edition: 2021 -#![feature(async_fn_in_trait)] #![deny(async_fn_in_trait)] pub trait Foo { diff --git a/tests/ui/async-await/in-trait/warn.stderr b/tests/ui/async-await/in-trait/warn.stderr index eac41a6e924..d0278628c97 100644 --- a/tests/ui/async-await/in-trait/warn.stderr +++ b/tests/ui/async-await/in-trait/warn.stderr @@ -1,16 +1,16 @@ error: use of `async fn` in public traits is discouraged as auto trait bounds cannot be specified - --> $DIR/warn.rs:7:5 + --> $DIR/warn.rs:6:5 | LL | async fn not_send(); | ^^^^^ | = note: you can suppress this lint if you plan to use the trait only in your own code, or do not care about auto traits like `Send` on the `Future` note: the lint level is defined here - --> $DIR/warn.rs:4:9 + --> $DIR/warn.rs:3:9 | LL | #![deny(async_fn_in_trait)] | ^^^^^^^^^^^^^^^^^ -help: you can alternatively desugar to a normal `fn` that returns `impl Future` and add any desired bounds such as `Send` +help: you can alternatively desugar to a normal `fn` that returns `impl Future` and add any desired bounds such as `Send`, but these cannot be relaxed without a breaking API change | LL - async fn not_send(); LL + fn not_send() -> impl std::future::Future<Output = ()> + Send; diff --git a/tests/ui/async-await/issues/issue-95307.rs b/tests/ui/async-await/issues/issue-95307.rs index f7e48070ccd..35dce2c6217 100644 --- a/tests/ui/async-await/issues/issue-95307.rs +++ b/tests/ui/async-await/issues/issue-95307.rs @@ -5,8 +5,7 @@ pub trait C { async fn new() -> [u8; _]; - //~^ ERROR: functions in traits cannot be declared `async` - //~| ERROR: using `_` for array lengths is unstable + //~^ ERROR: using `_` for array lengths is unstable //~| ERROR: in expressions, `_` can only be used on the left-hand side of an assignment } diff --git a/tests/ui/async-await/issues/issue-95307.stderr b/tests/ui/async-await/issues/issue-95307.stderr index a497cebe3c3..fdc6d5de1a8 100644 --- a/tests/ui/async-await/issues/issue-95307.stderr +++ b/tests/ui/async-await/issues/issue-95307.stderr @@ -1,16 +1,3 @@ -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/issue-95307.rs:7:5 - | -LL | async fn new() -> [u8; _]; - | -----^^^^^^^^^^^^^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - error: in expressions, `_` can only be used on the left-hand side of an assignment --> $DIR/issue-95307.rs:7:28 | @@ -26,7 +13,6 @@ LL | async fn new() -> [u8; _]; = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0658, E0706. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.rs b/tests/ui/async-await/return-type-notation/issue-110963-early.rs index 0ecbca5c13b..07f2130bab5 100644 --- a/tests/ui/async-await/return-type-notation/issue-110963-early.rs +++ b/tests/ui/async-await/return-type-notation/issue-110963-early.rs @@ -2,7 +2,6 @@ // known-bug: #110963 #![feature(return_type_notation)] -#![feature(async_fn_in_trait)] trait HealthCheck { async fn check<'a: 'a>(&'a mut self) -> bool; diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.stderr b/tests/ui/async-await/return-type-notation/issue-110963-early.stderr index 98e3cbd0d7f..feae2698e8f 100644 --- a/tests/ui/async-await/return-type-notation/issue-110963-early.stderr +++ b/tests/ui/async-await/return-type-notation/issue-110963-early.stderr @@ -8,7 +8,7 @@ LL | #![feature(return_type_notation)] = note: `#[warn(incomplete_features)]` on by default error[E0308]: mismatched types - --> $DIR/issue-110963-early.rs:15:5 + --> $DIR/issue-110963-early.rs:14:5 | LL | / spawn(async move { LL | | let mut hc = hc; @@ -21,13 +21,13 @@ LL | | }); = note: expected trait `Send` found trait `for<'a> Send` note: the lifetime requirement is introduced here - --> $DIR/issue-110963-early.rs:35:17 + --> $DIR/issue-110963-early.rs:34:17 | LL | F: Future + Send + 'static, | ^^^^ error[E0308]: mismatched types - --> $DIR/issue-110963-early.rs:15:5 + --> $DIR/issue-110963-early.rs:14:5 | LL | / spawn(async move { LL | | let mut hc = hc; @@ -40,7 +40,7 @@ LL | | }); = note: expected trait `Send` found trait `for<'a> Send` note: the lifetime requirement is introduced here - --> $DIR/issue-110963-early.rs:35:17 + --> $DIR/issue-110963-early.rs:34:17 | LL | F: Future + Send + 'static, | ^^^^ diff --git a/tests/ui/async-await/return-type-notation/issue-110963-late.rs b/tests/ui/async-await/return-type-notation/issue-110963-late.rs index 17b5d775d44..7533844fb43 100644 --- a/tests/ui/async-await/return-type-notation/issue-110963-late.rs +++ b/tests/ui/async-await/return-type-notation/issue-110963-late.rs @@ -3,7 +3,6 @@ #![feature(return_type_notation)] //~^ WARN the feature `return_type_notation` is incomplete -#![feature(async_fn_in_trait)] trait HealthCheck { async fn check(&mut self) -> bool; diff --git a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr index 8f45902035e..6a47f1ab983 100644 --- a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr +++ b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr @@ -1,5 +1,5 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/normalizing-self-auto-trait-issue-109924.rs:8:12 + --> $DIR/normalizing-self-auto-trait-issue-109924.rs:7:12 | LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #![feature(return_type_notation)] = note: `#[warn(incomplete_features)]` on by default error[E0277]: `impl Future<Output = ()> { <_ as Foo>::bar() }` cannot be sent between threads safely - --> $DIR/normalizing-self-auto-trait-issue-109924.rs:23:11 + --> $DIR/normalizing-self-auto-trait-issue-109924.rs:22:11 | LL | build(Bar); | ----- ^^^ `impl Future<Output = ()> { <_ as Foo>::bar() }` cannot be sent between threads safely @@ -17,7 +17,7 @@ LL | build(Bar); | = help: the trait `for<'a> Send` is not implemented for `impl Future<Output = ()> { <_ as Foo>::bar() }` note: this is a known limitation of the trait solver that will be lifted in the future - --> $DIR/normalizing-self-auto-trait-issue-109924.rs:23:11 + --> $DIR/normalizing-self-auto-trait-issue-109924.rs:22:11 | LL | build(Bar); | ------^^^- @@ -25,7 +25,7 @@ LL | build(Bar); | | the trait solver is unable to infer the generic types that should be inferred from this argument | add turbofish arguments to this call to specify the types manually, even if it's redundant note: required by a bound in `build` - --> $DIR/normalizing-self-auto-trait-issue-109924.rs:20:39 + --> $DIR/normalizing-self-auto-trait-issue-109924.rs:19:39 | LL | fn build<T>(_: T) where T: Foo<bar(): Send> {} | ^^^^ required by this bound in `build` diff --git a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.next.stderr b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.next.stderr index 6fab7178767..4837815fad4 100644 --- a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.next.stderr +++ b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.next.stderr @@ -1,5 +1,5 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/normalizing-self-auto-trait-issue-109924.rs:8:12 + --> $DIR/normalizing-self-auto-trait-issue-109924.rs:7:12 | LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs index b2cd9707db9..e581e5ffda7 100644 --- a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs +++ b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs @@ -4,7 +4,6 @@ //[next] compile-flags: -Ztrait-solver=next // edition:2021 -#![feature(async_fn_in_trait)] #![feature(return_type_notation)] //[next]~^ WARN the feature `return_type_notation` is incomplete diff --git a/tests/ui/async-await/return-type-notation/rtn-implied-in-supertrait.rs b/tests/ui/async-await/return-type-notation/rtn-implied-in-supertrait.rs index e55104ee968..0ceb62d449a 100644 --- a/tests/ui/async-await/return-type-notation/rtn-implied-in-supertrait.rs +++ b/tests/ui/async-await/return-type-notation/rtn-implied-in-supertrait.rs @@ -1,7 +1,7 @@ // edition:2021 // check-pass -#![feature(async_fn_in_trait, return_position_impl_trait_in_trait, return_type_notation)] +#![feature(return_type_notation)] //~^ WARN the feature `return_type_notation` is incomplete use std::future::Future; diff --git a/tests/ui/async-await/return-type-notation/rtn-implied-in-supertrait.stderr b/tests/ui/async-await/return-type-notation/rtn-implied-in-supertrait.stderr index 8626648b523..4a52e807bff 100644 --- a/tests/ui/async-await/return-type-notation/rtn-implied-in-supertrait.stderr +++ b/tests/ui/async-await/return-type-notation/rtn-implied-in-supertrait.stderr @@ -1,8 +1,8 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/rtn-implied-in-supertrait.rs:4:68 + --> $DIR/rtn-implied-in-supertrait.rs:4:12 | -LL | #![feature(async_fn_in_trait, return_position_impl_trait_in_trait, return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![feature(return_type_notation)] + | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default diff --git a/tests/ui/async-await/return-type-notation/super-method-bound-ambig.rs b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.rs index 028e526b5f5..891b30638ee 100644 --- a/tests/ui/async-await/return-type-notation/super-method-bound-ambig.rs +++ b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.rs @@ -1,6 +1,6 @@ // edition:2021 -#![feature(async_fn_in_trait, return_type_notation)] +#![feature(return_type_notation)] //~^ WARN the feature `return_type_notation` is incomplete trait Super1<'a> { diff --git a/tests/ui/async-await/return-type-notation/super-method-bound-ambig.stderr b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.stderr index 5bc8dbde4bc..d9caab5875a 100644 --- a/tests/ui/async-await/return-type-notation/super-method-bound-ambig.stderr +++ b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.stderr @@ -1,8 +1,8 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-method-bound-ambig.rs:3:31 + --> $DIR/super-method-bound-ambig.rs:3:12 | -LL | #![feature(async_fn_in_trait, return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![feature(return_type_notation)] + | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default diff --git a/tests/ui/async-await/return-type-notation/super-method-bound.current.stderr b/tests/ui/async-await/return-type-notation/super-method-bound.current.stderr index 891c802c5f4..5f482b60878 100644 --- a/tests/ui/async-await/return-type-notation/super-method-bound.current.stderr +++ b/tests/ui/async-await/return-type-notation/super-method-bound.current.stderr @@ -1,8 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/super-method-bound.rs:6:31 | -LL | #![feature(async_fn_in_trait, return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default diff --git a/tests/ui/async-await/return-type-notation/super-method-bound.next.stderr b/tests/ui/async-await/return-type-notation/super-method-bound.next.stderr index 891c802c5f4..5f482b60878 100644 --- a/tests/ui/async-await/return-type-notation/super-method-bound.next.stderr +++ b/tests/ui/async-await/return-type-notation/super-method-bound.next.stderr @@ -1,8 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/super-method-bound.rs:6:31 | -LL | #![feature(async_fn_in_trait, return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default diff --git a/tests/ui/async-await/return-type-notation/super-method-bound.rs b/tests/ui/async-await/return-type-notation/super-method-bound.rs index 58ea3578db6..6025cda2f5d 100644 --- a/tests/ui/async-await/return-type-notation/super-method-bound.rs +++ b/tests/ui/async-await/return-type-notation/super-method-bound.rs @@ -1,7 +1,7 @@ // edition:2021 // check-pass -#![feature(async_fn_in_trait, return_type_notation)] +#![feature(return_type_notation)] //~^ WARN the feature `return_type_notation` is incomplete trait Super<'a> { diff --git a/tests/ui/async-await/return-type-notation/super-method-bound.stderr b/tests/ui/async-await/return-type-notation/super-method-bound.stderr index ac0668d3c44..64fda71c1a1 100644 --- a/tests/ui/async-await/return-type-notation/super-method-bound.stderr +++ b/tests/ui/async-await/return-type-notation/super-method-bound.stderr @@ -1,8 +1,8 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-method-bound.rs:4:31 + --> $DIR/super-method-bound.rs:4:12 | -LL | #![feature(async_fn_in_trait, return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![feature(return_type_notation)] + | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default diff --git a/tests/ui/async-await/return-type-notation/supertrait-bound.current.stderr b/tests/ui/async-await/return-type-notation/supertrait-bound.current.stderr index 05cb0ca4abd..928b321697c 100644 --- a/tests/ui/async-await/return-type-notation/supertrait-bound.current.stderr +++ b/tests/ui/async-await/return-type-notation/supertrait-bound.current.stderr @@ -1,7 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/supertrait-bound.rs:5:49 | -LL | #![feature(return_position_impl_trait_in_trait, return_type_notation)] +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information diff --git a/tests/ui/async-await/return-type-notation/supertrait-bound.next.stderr b/tests/ui/async-await/return-type-notation/supertrait-bound.next.stderr index 05cb0ca4abd..928b321697c 100644 --- a/tests/ui/async-await/return-type-notation/supertrait-bound.next.stderr +++ b/tests/ui/async-await/return-type-notation/supertrait-bound.next.stderr @@ -1,7 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/supertrait-bound.rs:5:49 | -LL | #![feature(return_position_impl_trait_in_trait, return_type_notation)] +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information diff --git a/tests/ui/async-await/return-type-notation/supertrait-bound.rs b/tests/ui/async-await/return-type-notation/supertrait-bound.rs index 19bcfe3046b..a85596a9fee 100644 --- a/tests/ui/async-await/return-type-notation/supertrait-bound.rs +++ b/tests/ui/async-await/return-type-notation/supertrait-bound.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(return_position_impl_trait_in_trait, return_type_notation)] +#![feature(return_type_notation)] //~^ WARN the feature `return_type_notation` is incomplete and may not be safe to use trait IntFactory { diff --git a/tests/ui/async-await/return-type-notation/supertrait-bound.stderr b/tests/ui/async-await/return-type-notation/supertrait-bound.stderr index c8cec4946b4..eb6917fc7d5 100644 --- a/tests/ui/async-await/return-type-notation/supertrait-bound.stderr +++ b/tests/ui/async-await/return-type-notation/supertrait-bound.stderr @@ -1,8 +1,8 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/supertrait-bound.rs:3:49 + --> $DIR/supertrait-bound.rs:3:12 | -LL | #![feature(return_position_impl_trait_in_trait, return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![feature(return_type_notation)] + | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default diff --git a/tests/ui/async-await/return-type-notation/ty-or-ct-params.current.stderr b/tests/ui/async-await/return-type-notation/ty-or-ct-params.current.stderr index 1aa008fe469..e2bbb6013fc 100644 --- a/tests/ui/async-await/return-type-notation/ty-or-ct-params.current.stderr +++ b/tests/ui/async-await/return-type-notation/ty-or-ct-params.current.stderr @@ -1,8 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/ty-or-ct-params.rs:5:31 | -LL | #![feature(async_fn_in_trait, return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default diff --git a/tests/ui/async-await/return-type-notation/ty-or-ct-params.next.stderr b/tests/ui/async-await/return-type-notation/ty-or-ct-params.next.stderr index 1aa008fe469..e2bbb6013fc 100644 --- a/tests/ui/async-await/return-type-notation/ty-or-ct-params.next.stderr +++ b/tests/ui/async-await/return-type-notation/ty-or-ct-params.next.stderr @@ -1,8 +1,7 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/ty-or-ct-params.rs:5:31 | -LL | #![feature(async_fn_in_trait, return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default diff --git a/tests/ui/async-await/return-type-notation/ty-or-ct-params.rs b/tests/ui/async-await/return-type-notation/ty-or-ct-params.rs index 7871a2fed03..ac320cfc679 100644 --- a/tests/ui/async-await/return-type-notation/ty-or-ct-params.rs +++ b/tests/ui/async-await/return-type-notation/ty-or-ct-params.rs @@ -1,6 +1,6 @@ // edition: 2021 -#![feature(async_fn_in_trait, return_type_notation)] +#![feature(return_type_notation)] //~^ WARN the feature `return_type_notation` is incomplete trait Foo { diff --git a/tests/ui/async-await/return-type-notation/ty-or-ct-params.stderr b/tests/ui/async-await/return-type-notation/ty-or-ct-params.stderr index 76928c5d7a3..da94d9d1e6d 100644 --- a/tests/ui/async-await/return-type-notation/ty-or-ct-params.stderr +++ b/tests/ui/async-await/return-type-notation/ty-or-ct-params.stderr @@ -1,8 +1,8 @@ warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/ty-or-ct-params.rs:3:31 + --> $DIR/ty-or-ct-params.rs:3:12 | -LL | #![feature(async_fn_in_trait, return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![feature(return_type_notation)] + | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs index 6b2a0153f51..5f612780f39 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs @@ -3,6 +3,7 @@ // failure-status: 101 // normalize-stderr-test "note: .*\n\n" -> "" // normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" +// normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " // rustc-env:RUST_BACKTRACE=0 // This test used to cause an ICE in rustc_mir::interpret::step::eval_rvalue_into_place diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr index 25a455d3308..9b66fc502b7 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr @@ -1,9 +1,9 @@ -error: internal compiler error: compiler/rustc_const_eval/src/interpret/step.rs:272:21: SizeOf MIR operator called for unsized type dyn Debug +error: internal compiler error: compiler/rustc_const_eval/src/interpret/step.rs:LL:CC: SizeOf MIR operator called for unsized type dyn Debug --> $SRC_DIR/core/src/mem/mod.rs:LL:COL Box<dyn Any> query stack during panic: -#0 [eval_to_allocation_raw] const-evaluating + checking `<impl at $DIR/issue-80742.rs:25:1: 27:32>::{constant#0}` +#0 [eval_to_allocation_raw] const-evaluating + checking `<impl at $DIR/issue-80742.rs:26:1: 28:32>::{constant#0}` #1 [eval_to_valtree] evaluating type-level constant end of query stack error: aborting due to previous error diff --git a/tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.stderr b/tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.stderr index 69bc174b6be..8cbd1265448 100644 --- a/tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.stderr +++ b/tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.stderr @@ -7,17 +7,5 @@ LL | WHAT_A_TYPE => 0, = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details -error[E0015]: cannot match on `TypeId` in constant functions - --> $DIR/typeid-equality-by-subtyping.rs:18:9 - | -LL | WHAT_A_TYPE => 0, - | ^^^^^^^^^^^ - | - = note: `TypeId` cannot be compared in compile-time, and therefore cannot be used in `match`es -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/any.rs:LL:COL - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/const-ptr/forbidden_slices.rs b/tests/ui/const-ptr/forbidden_slices.rs index 192b6a46de6..93e3bb09ff1 100644 --- a/tests/ui/const-ptr/forbidden_slices.rs +++ b/tests/ui/const-ptr/forbidden_slices.rs @@ -2,7 +2,6 @@ // normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" // normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*a(lloc)?[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP" // normalize-stderr-test "alloc\d+" -> "allocN" -// error-pattern: could not evaluate static initializer #![feature( slice_from_ptr_range, const_slice_from_ptr_range, @@ -17,10 +16,13 @@ use std::{ // Null is never valid for reads pub static S0: &[u32] = unsafe { from_raw_parts(ptr::null(), 0) }; +//~^ ERROR: it is undefined behavior to use this value pub static S1: &[()] = unsafe { from_raw_parts(ptr::null(), 0) }; +//~^ ERROR: it is undefined behavior to use this value // Out of bounds pub static S2: &[u32] = unsafe { from_raw_parts(&D0, 2) }; +//~^ ERROR: it is undefined behavior to use this value // Reading uninitialized data pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) }; //~ ERROR: it is undefined behavior to use this value @@ -39,6 +41,7 @@ pub static S7: &[u16] = unsafe { // Unaligned read pub static S8: &[u64] = unsafe { + //~^ ERROR: it is undefined behavior to use this value let ptr = (&D4 as *const [u32; 2] as *const u32).byte_add(1).cast::<u64>(); from_raw_parts(ptr, 1) @@ -66,8 +69,9 @@ pub static R6: &[bool] = unsafe { from_ptr_range(ptr..ptr.add(4)) }; pub static R7: &[u16] = unsafe { + //~^ ERROR: it is undefined behavior to use this value let ptr = (&D2 as *const Struct as *const u16).byte_add(1); - from_ptr_range(ptr..ptr.add(4)) //~ inside `R7` + from_ptr_range(ptr..ptr.add(4)) }; pub static R8: &[u64] = unsafe { let ptr = (&D4 as *const [u32; 2] as *const u32).byte_add(1).cast::<u64>(); diff --git a/tests/ui/const-ptr/forbidden_slices.stderr b/tests/ui/const-ptr/forbidden_slices.stderr index 294bc77aa31..4ae0ffff63d 100644 --- a/tests/ui/const-ptr/forbidden_slices.stderr +++ b/tests/ui/const-ptr/forbidden_slices.stderr @@ -1,44 +1,38 @@ -error[E0080]: could not evaluate static initializer - --> $SRC_DIR/core/src/slice/raw.rs:LL:COL - | - = note: dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) - | -note: inside `std::slice::from_raw_parts::<'_, u32>` - --> $SRC_DIR/core/src/slice/raw.rs:LL:COL -note: inside `S0` - --> $DIR/forbidden_slices.rs:19:34 +error[E0080]: it is undefined behavior to use this value + --> $DIR/forbidden_slices.rs:18:1 | LL | pub static S0: &[u32] = unsafe { from_raw_parts(ptr::null(), 0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0080]: could not evaluate static initializer - --> $SRC_DIR/core/src/slice/raw.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null reference | - = note: dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) - | -note: inside `std::slice::from_raw_parts::<'_, ()>` - --> $SRC_DIR/core/src/slice/raw.rs:LL:COL -note: inside `S1` - --> $DIR/forbidden_slices.rs:20:33 - | -LL | pub static S1: &[()] = unsafe { from_raw_parts(ptr::null(), 0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = 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: $SIZE, align: $ALIGN) { + HEX_DUMP + } -error[E0080]: could not evaluate static initializer - --> $SRC_DIR/core/src/slice/raw.rs:LL:COL +error[E0080]: it is undefined behavior to use this value + --> $DIR/forbidden_slices.rs:20:1 | - = note: dereferencing pointer failed: allocN has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds +LL | pub static S1: &[()] = unsafe { from_raw_parts(ptr::null(), 0) }; + | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null reference | -note: inside `std::slice::from_raw_parts::<'_, u32>` - --> $SRC_DIR/core/src/slice/raw.rs:LL:COL -note: inside `S2` - --> $DIR/forbidden_slices.rs:23:34 + = 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: $SIZE, align: $ALIGN) { + HEX_DUMP + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/forbidden_slices.rs:24:1 | LL | pub static S2: &[u32] = unsafe { from_raw_parts(&D0, 2) }; - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) + | + = 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: $SIZE, align: $ALIGN) { + HEX_DUMP + } error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:26:1 + --> $DIR/forbidden_slices.rs:28:1 | LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) }; | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer @@ -49,7 +43,7 @@ LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) } } error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:28:1 + --> $DIR/forbidden_slices.rs:30:1 | LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, size_of::<&u32>()) }; | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer @@ -62,7 +56,7 @@ LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, size = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:30:1 + --> $DIR/forbidden_slices.rs:32:1 | LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) }; | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean @@ -73,7 +67,7 @@ LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) } error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:33:1 + --> $DIR/forbidden_slices.rs:35:1 | LL | pub static S7: &[u16] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[1]: encountered uninitialized memory, but expected an integer @@ -83,18 +77,16 @@ LL | pub static S7: &[u16] = unsafe { HEX_DUMP } -error[E0080]: could not evaluate static initializer - --> $SRC_DIR/core/src/slice/raw.rs:LL:COL - | - = note: dereferencing pointer failed: allocN has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds +error[E0080]: it is undefined behavior to use this value + --> $DIR/forbidden_slices.rs:43:1 | -note: inside `std::slice::from_raw_parts::<'_, u64>` - --> $SRC_DIR/core/src/slice/raw.rs:LL:COL -note: inside `S8` - --> $DIR/forbidden_slices.rs:44:5 +LL | pub static S8: &[u64] = unsafe { + | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) | -LL | from_raw_parts(ptr, 1) - | ^^^^^^^^^^^^^^^^^^^^^^ + = 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: $SIZE, align: $ALIGN) { + HEX_DUMP + } error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL @@ -106,7 +98,7 @@ note: inside `ptr::const_ptr::<impl *const u32>::sub_ptr` note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `R0` - --> $DIR/forbidden_slices.rs:47:34 + --> $DIR/forbidden_slices.rs:50:34 | LL | pub static R0: &[u32] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -121,7 +113,7 @@ note: inside `ptr::const_ptr::<impl *const ()>::sub_ptr` note: inside `from_ptr_range::<'_, ()>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `R1` - --> $DIR/forbidden_slices.rs:48:33 + --> $DIR/forbidden_slices.rs:51:33 | LL | pub static R1: &[()] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -135,13 +127,13 @@ error[E0080]: could not evaluate static initializer note: inside `ptr::const_ptr::<impl *const u32>::add` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `R2` - --> $DIR/forbidden_slices.rs:51:25 + --> $DIR/forbidden_slices.rs:54:25 | LL | from_ptr_range(ptr..ptr.add(2)) | ^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:53:1 + --> $DIR/forbidden_slices.rs:56:1 | LL | pub static R4: &[u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer @@ -152,7 +144,7 @@ LL | pub static R4: &[u8] = unsafe { } error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:58:1 + --> $DIR/forbidden_slices.rs:61:1 | LL | pub static R5: &[u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a pointer, but expected an integer @@ -165,7 +157,7 @@ LL | pub static R5: &[u8] = unsafe { = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:63:1 + --> $DIR/forbidden_slices.rs:66:1 | LL | pub static R6: &[bool] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean @@ -175,20 +167,16 @@ LL | pub static R6: &[bool] = unsafe { HEX_DUMP } -error[E0080]: could not evaluate static initializer - --> $SRC_DIR/core/src/slice/raw.rs:LL:COL - | - = note: accessing memory with alignment 1, but alignment 2 is required +error[E0080]: it is undefined behavior to use this value + --> $DIR/forbidden_slices.rs:71:1 | -note: inside `std::slice::from_raw_parts::<'_, u16>` - --> $SRC_DIR/core/src/slice/raw.rs:LL:COL -note: inside `from_ptr_range::<'_, u16>` - --> $SRC_DIR/core/src/slice/raw.rs:LL:COL -note: inside `R7` - --> $DIR/forbidden_slices.rs:70:5 +LL | pub static R7: &[u16] = unsafe { + | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) | -LL | from_ptr_range(ptr..ptr.add(4)) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = 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: $SIZE, align: $ALIGN) { + HEX_DUMP + } error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL @@ -198,7 +186,7 @@ error[E0080]: could not evaluate static initializer note: inside `ptr::const_ptr::<impl *const u64>::add` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `R8` - --> $DIR/forbidden_slices.rs:74:25 + --> $DIR/forbidden_slices.rs:78:25 | LL | from_ptr_range(ptr..ptr.add(1)) | ^^^^^^^^^^ @@ -213,7 +201,7 @@ note: inside `ptr::const_ptr::<impl *const u32>::sub_ptr` note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `R9` - --> $DIR/forbidden_slices.rs:79:34 + --> $DIR/forbidden_slices.rs:83:34 | LL | pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).add(1)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -228,7 +216,7 @@ note: inside `ptr::const_ptr::<impl *const u32>::sub_ptr` note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `R10` - --> $DIR/forbidden_slices.rs:80:35 + --> $DIR/forbidden_slices.rs:84:35 | LL | pub static R10: &[u32] = unsafe { from_ptr_range(&D0..&D0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/const-ptr/out_of_bounds_read.stderr b/tests/ui/const-ptr/out_of_bounds_read.stderr index c5c0a1cdefc..bfdd5859719 100644 --- a/tests/ui/const-ptr/out_of_bounds_read.stderr +++ b/tests/ui/const-ptr/out_of_bounds_read.stderr @@ -1,7 +1,7 @@ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = note: dereferencing pointer failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds + = note: memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds | note: inside `std::ptr::read::<u32>` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL @@ -14,7 +14,7 @@ LL | const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) }; error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = note: dereferencing pointer failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds + = note: memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds | note: inside `std::ptr::read::<u32>` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL @@ -29,7 +29,7 @@ LL | const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() }; error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = note: dereferencing pointer failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds + = note: memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds | note: inside `std::ptr::read::<u32>` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL diff --git a/tests/ui/consts/const-deref-ptr.rs b/tests/ui/consts/const-deref-ptr.rs index 4aca75e3a17..2607d4de229 100644 --- a/tests/ui/consts/const-deref-ptr.rs +++ b/tests/ui/consts/const-deref-ptr.rs @@ -3,5 +3,6 @@ fn main() { static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; //~^ ERROR could not evaluate static initializer + //~| dangling pointer println!("{}", C); } diff --git a/tests/ui/consts/const-deref-ptr.stderr b/tests/ui/consts/const-deref-ptr.stderr index 22cb6451e87..16eb6b0162d 100644 --- a/tests/ui/consts/const-deref-ptr.stderr +++ b/tests/ui/consts/const-deref-ptr.stderr @@ -2,7 +2,7 @@ error[E0080]: could not evaluate static initializer --> $DIR/const-deref-ptr.rs:4:29 | LL | static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: 0xdeadbeef[noalloc] is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: 0xdeadbeef[noalloc] is a dangling pointer (it has no provenance) error: aborting due to previous error diff --git a/tests/ui/consts/const-eval/const_fn_target_feature_wasm.rs b/tests/ui/consts/const-eval/const_fn_target_feature_wasm.rs new file mode 100644 index 00000000000..c1460fdd9ec --- /dev/null +++ b/tests/ui/consts/const-eval/const_fn_target_feature_wasm.rs @@ -0,0 +1,14 @@ +// only-wasm32 +// compile-flags:-C target-feature=-simd128 +// build-pass + +#![crate_type = "lib"] + +#[cfg(target_feature = "simd128")] +compile_error!("simd128 target feature should be disabled"); + +// Calling functions with `#[target_feature]` is not unsound on WASM, see #84988 +const A: () = simd128_fn(); + +#[target_feature(enable = "simd128")] +const fn simd128_fn() {} diff --git a/tests/ui/consts/const-eval/const_raw_ptr_ops2.stderr b/tests/ui/consts/const-eval/const_raw_ptr_ops2.stderr index e41dea873ac..e6cd25e42ff 100644 --- a/tests/ui/consts/const-eval/const_raw_ptr_ops2.stderr +++ b/tests/ui/consts/const-eval/const_raw_ptr_ops2.stderr @@ -2,13 +2,13 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_raw_ptr_ops2.rs:7:26 | LL | const Z2: i32 = unsafe { *(42 as *const i32) }; - | ^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: 0x2a[noalloc] is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^ memory access failed: 0x2a[noalloc] is a dangling pointer (it has no provenance) error[E0080]: evaluation of constant value failed --> $DIR/const_raw_ptr_ops2.rs:9:26 | LL | const Z3: i32 = unsafe { *(44 as *const i32) }; - | ^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: 0x2c[noalloc] is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^ memory access failed: 0x2c[noalloc] is a dangling pointer (it has no provenance) error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-eval/dangling.rs b/tests/ui/consts/const-eval/dangling.rs deleted file mode 100644 index 4fcf879218b..00000000000 --- a/tests/ui/consts/const-eval/dangling.rs +++ /dev/null @@ -1,10 +0,0 @@ -use std::mem; - -// Make sure we error with the right kind of error on a too large slice. -const TEST: () = { unsafe { - let slice: *const [u8] = mem::transmute((1usize, usize::MAX)); - let _val = &*slice; //~ ERROR: evaluation of constant value failed - //~| slice is bigger than largest supported object -} }; - -fn main() {} diff --git a/tests/ui/consts/const-eval/dangling.stderr b/tests/ui/consts/const-eval/dangling.stderr deleted file mode 100644 index 92d70573d98..00000000000 --- a/tests/ui/consts/const-eval/dangling.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0080]: evaluation of constant value failed - --> $DIR/dangling.rs:6:16 - | -LL | let _val = &*slice; - | ^^^^^^^ invalid metadata in wide pointer: slice is bigger than largest supported object - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs index b6d89a58dce..a717a5f8292 100644 --- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs +++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs @@ -5,10 +5,10 @@ use std::intrinsics; const _X: &'static u8 = unsafe { + //~^ error: dangling pointer in final constant let ptr = intrinsics::const_allocate(4, 4); intrinsics::const_deallocate(ptr, 4, 4); &*ptr - //~^ error: evaluation of constant value failed }; const _Y: u8 = unsafe { diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr index b50ef0c68a1..032dcad86a4 100644 --- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr +++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr @@ -1,14 +1,14 @@ -error[E0080]: evaluation of constant value failed - --> $DIR/dealloc_intrinsic_dangling.rs:10:5 +error: encountered dangling pointer in final constant + --> $DIR/dealloc_intrinsic_dangling.rs:7:1 | -LL | &*ptr - | ^^^^^ dereferencing pointer failed: alloc2 has been freed, so this pointer is dangling +LL | const _X: &'static u8 = unsafe { + | ^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $DIR/dealloc_intrinsic_dangling.rs:18:5 | LL | *reference - | ^^^^^^^^^^ dereferencing pointer failed: alloc4 has been freed, so this pointer is dangling + | ^^^^^^^^^^ memory access failed: alloc4 has been freed, so this pointer is dangling error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-eval/issue-114994-fail.rs b/tests/ui/consts/const-eval/issue-114994-fail.rs new file mode 100644 index 00000000000..72350464091 --- /dev/null +++ b/tests/ui/consts/const-eval/issue-114994-fail.rs @@ -0,0 +1,14 @@ +// This checks that function pointer signatures that are referenced mutably +// but contain a &mut T parameter still fail in a constant context: see issue #114994. +// +// check-fail + +const fn use_mut_const_fn(_f: &mut fn(&mut String)) { //~ ERROR mutable references are not allowed in constant functions + () +} + +const fn use_mut_const_tuple_fn(_f: (fn(), &mut u32)) { //~ ERROR mutable references are not allowed in constant functions + +} + +fn main() {} diff --git a/tests/ui/consts/const-eval/issue-114994-fail.stderr b/tests/ui/consts/const-eval/issue-114994-fail.stderr new file mode 100644 index 00000000000..4dae8ea9bca --- /dev/null +++ b/tests/ui/consts/const-eval/issue-114994-fail.stderr @@ -0,0 +1,21 @@ +error[E0658]: mutable references are not allowed in constant functions + --> $DIR/issue-114994-fail.rs:6:27 + | +LL | const fn use_mut_const_fn(_f: &mut fn(&mut String)) { + | ^^ + | + = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error[E0658]: mutable references are not allowed in constant functions + --> $DIR/issue-114994-fail.rs:10:33 + | +LL | const fn use_mut_const_tuple_fn(_f: (fn(), &mut u32)) { + | ^^ + | + = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/consts/const-eval/issue-114994.rs b/tests/ui/consts/const-eval/issue-114994.rs new file mode 100644 index 00000000000..a4cb2e61e5f --- /dev/null +++ b/tests/ui/consts/const-eval/issue-114994.rs @@ -0,0 +1,18 @@ +// This checks that function pointer signatures containing &mut T types +// work in a constant context: see issue #114994. +// +// check-pass + +const fn use_const_fn(_f: fn(&mut String)) { + () +} + +const fn get_some_fn() -> fn(&mut String) { + String::clear +} + +const fn some_const_fn() { + let _f: fn(&mut String) = String::clear; +} + +fn main() {} diff --git a/tests/ui/consts/const-eval/issue-49296.stderr b/tests/ui/consts/const-eval/issue-49296.stderr index 45ba0ea183e..1f9b1dfe31e 100644 --- a/tests/ui/consts/const-eval/issue-49296.stderr +++ b/tests/ui/consts/const-eval/issue-49296.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/issue-49296.rs:9:16 | LL | const X: u64 = *wat(42); - | ^^^^^^^^ dereferencing pointer failed: alloc3 has been freed, so this pointer is dangling + | ^^^^^^^^ memory access failed: alloc3 has been freed, so this pointer is dangling error: aborting due to previous error diff --git a/tests/ui/consts/const-eval/nonnull_as_ref_ub.rs b/tests/ui/consts/const-eval/nonnull_as_ref_ub.rs index 3b48e972923..19ab5239986 100644 --- a/tests/ui/consts/const-eval/nonnull_as_ref_ub.rs +++ b/tests/ui/consts/const-eval/nonnull_as_ref_ub.rs @@ -1,6 +1,6 @@ use std::ptr::NonNull; const NON_NULL: NonNull<u8> = unsafe { NonNull::dangling() }; -const _: () = assert!(42 == *unsafe { NON_NULL.as_ref() }); +const _: () = assert!(42 == *unsafe { NON_NULL.as_ref() }); //~ERROR: evaluation of constant value failed fn main() {} diff --git a/tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr b/tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr index de93cb0c3ca..e34f3f43c64 100644 --- a/tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr +++ b/tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr @@ -1,15 +1,8 @@ error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/non_null.rs:LL:COL - | - = note: dereferencing pointer failed: 0x1[noalloc] is a dangling pointer (it has no provenance) - | -note: inside `NonNull::<u8>::as_ref::<'_>` - --> $SRC_DIR/core/src/ptr/non_null.rs:LL:COL -note: inside `_` - --> $DIR/nonnull_as_ref_ub.rs:4:39 + --> $DIR/nonnull_as_ref_ub.rs:4:29 | LL | const _: () = assert!(42 == *unsafe { NON_NULL.as_ref() }); - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: 0x1[noalloc] is a dangling pointer (it has no provenance) error: aborting due to previous error diff --git a/tests/ui/consts/const-eval/raw-pointer-ub.rs b/tests/ui/consts/const-eval/raw-pointer-ub.rs index e53865309eb..2d09b5494c6 100644 --- a/tests/ui/consts/const-eval/raw-pointer-ub.rs +++ b/tests/ui/consts/const-eval/raw-pointer-ub.rs @@ -7,14 +7,14 @@ const MISALIGNED_LOAD: () = unsafe { let mem = [0u32; 8]; let ptr = mem.as_ptr().byte_add(1); let _val = *ptr; //~ERROR: evaluation of constant value failed - //~^NOTE: accessing memory with alignment 1, but alignment 4 is required + //~^NOTE: based on pointer with alignment 1, but alignment 4 is required }; const MISALIGNED_STORE: () = unsafe { let mut mem = [0u32; 8]; let ptr = mem.as_mut_ptr().byte_add(1); *ptr = 0; //~ERROR: evaluation of constant value failed - //~^NOTE: accessing memory with alignment 1, but alignment 4 is required + //~^NOTE: based on pointer with alignment 1, but alignment 4 is required }; const MISALIGNED_COPY: () = unsafe { @@ -26,6 +26,17 @@ const MISALIGNED_COPY: () = unsafe { // The actual error points into the implementation of `copy_to_nonoverlapping`. }; +const MISALIGNED_FIELD: () = unsafe { + #[repr(align(16))] + struct Aligned(f32); + + let mem = [0f32; 8]; + let ptr = mem.as_ptr().cast::<Aligned>(); + // Accessing an f32 field but we still require the alignment of the pointer type. + let _val = (*ptr).0; //~ERROR: evaluation of constant value failed + //~^NOTE: based on pointer with alignment 4, but alignment 16 is required +}; + const OOB: () = unsafe { let mem = [0u32; 1]; let ptr = mem.as_ptr().cast::<u64>(); diff --git a/tests/ui/consts/const-eval/raw-pointer-ub.stderr b/tests/ui/consts/const-eval/raw-pointer-ub.stderr index 96b7f4f58f9..663d49f21b4 100644 --- a/tests/ui/consts/const-eval/raw-pointer-ub.stderr +++ b/tests/ui/consts/const-eval/raw-pointer-ub.stderr @@ -2,13 +2,13 @@ error[E0080]: evaluation of constant value failed --> $DIR/raw-pointer-ub.rs:9:16 | LL | let _val = *ptr; - | ^^^^ accessing memory with alignment 1, but alignment 4 is required + | ^^^^ accessing memory based on pointer with alignment 1, but alignment 4 is required error[E0080]: evaluation of constant value failed --> $DIR/raw-pointer-ub.rs:16:5 | LL | *ptr = 0; - | ^^^^^^^^ accessing memory with alignment 1, but alignment 4 is required + | ^^^^^^^^ accessing memory based on pointer with alignment 1, but alignment 4 is required error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/intrinsics.rs:LL:COL @@ -26,11 +26,17 @@ LL | y.copy_to_nonoverlapping(&mut z, 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/raw-pointer-ub.rs:32:16 + --> $DIR/raw-pointer-ub.rs:36:16 + | +LL | let _val = (*ptr).0; + | ^^^^^^^^ accessing memory based on pointer with alignment 4, but alignment 16 is required + +error[E0080]: evaluation of constant value failed + --> $DIR/raw-pointer-ub.rs:43:16 | LL | let _val = *ptr; - | ^^^^ dereferencing pointer failed: allocN has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds + | ^^^^ memory access failed: allocN has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr b/tests/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr index 965256de21a..13c5920bd37 100644 --- a/tests/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr +++ b/tests/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr @@ -1,14 +1,24 @@ -error[E0080]: evaluation of constant value failed - --> $DIR/ub-incorrect-vtable.rs:19:14 +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-incorrect-vtable.rs:18:1 + | +LL | const INVALID_VTABLE_ALIGNMENT: &dyn Trait = + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer | -LL | unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable + = 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: 4) { + ╾─allocN──╼ ╾─allocN──╼ │ ╾──╼╾──╼ + } -error[E0080]: evaluation of constant value failed - --> $DIR/ub-incorrect-vtable.rs:24:14 +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-incorrect-vtable.rs:23:1 | -LL | unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable +LL | const INVALID_VTABLE_SIZE: &dyn Trait = + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer + | + = 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: 4) { + ╾─allocN─╼ ╾─allocN─╼ │ ╾──╼╾──╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-incorrect-vtable.rs:33:1 diff --git a/tests/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr b/tests/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr index bd542a7a5f2..ba47865bcf9 100644 --- a/tests/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr +++ b/tests/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr @@ -1,14 +1,24 @@ -error[E0080]: evaluation of constant value failed - --> $DIR/ub-incorrect-vtable.rs:19:14 +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-incorrect-vtable.rs:18:1 + | +LL | const INVALID_VTABLE_ALIGNMENT: &dyn Trait = + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer | -LL | unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable + = 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: 16, align: 8) { + ╾───────allocN────────╼ ╾───────allocN────────╼ │ ╾──────╼╾──────╼ + } -error[E0080]: evaluation of constant value failed - --> $DIR/ub-incorrect-vtable.rs:24:14 +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-incorrect-vtable.rs:23:1 | -LL | unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable +LL | const INVALID_VTABLE_SIZE: &dyn Trait = + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer + | + = 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: 16, align: 8) { + ╾───────allocN───────╼ ╾───────allocN───────╼ │ ╾──────╼╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-incorrect-vtable.rs:33:1 diff --git a/tests/ui/consts/const-eval/ub-incorrect-vtable.rs b/tests/ui/consts/const-eval/ub-incorrect-vtable.rs index 4bb30b75bc8..7fb58f43bcb 100644 --- a/tests/ui/consts/const-eval/ub-incorrect-vtable.rs +++ b/tests/ui/consts/const-eval/ub-incorrect-vtable.rs @@ -17,13 +17,13 @@ trait Trait {} const INVALID_VTABLE_ALIGNMENT: &dyn Trait = unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) }; -//~^ ERROR evaluation of constant value failed -//~| does not point to a vtable +//~^^ ERROR it is undefined behavior to use this value +//~| expected a vtable pointer const INVALID_VTABLE_SIZE: &dyn Trait = unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) }; -//~^ ERROR evaluation of constant value failed -//~| does not point to a vtable +//~^^ ERROR it is undefined behavior to use this value +//~| expected a vtable pointer #[repr(transparent)] struct W<T>(T); diff --git a/tests/ui/consts/const-eval/ub-nonnull.stderr b/tests/ui/consts/const-eval/ub-nonnull.stderr index 96164870804..2df76f2c9e2 100644 --- a/tests/ui/consts/const-eval/ub-nonnull.stderr +++ b/tests/ui/consts/const-eval/ub-nonnull.stderr @@ -10,10 +10,10 @@ LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-nonnull.rs:20:30 + --> $DIR/ub-nonnull.rs:20:29 | LL | let out_of_bounds_ptr = &ptr[255]; - | ^^^^^^^^ dereferencing pointer failed: alloc11 has size 1, so pointer to 256 bytes starting at offset 0 is out-of-bounds + | ^^^^^^^^^ out-of-bounds pointer arithmetic: alloc11 has size 1, so pointer to 255 bytes starting at offset 0 is out-of-bounds error[E0080]: it is undefined behavior to use this value --> $DIR/ub-nonnull.rs:24:1 diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.stderr b/tests/ui/consts/const-eval/ub-ref-ptr.stderr index 6d5c36cea7d..2144d147108 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.stderr +++ b/tests/ui/consts/const-eval/ub-ref-ptr.stderr @@ -151,7 +151,7 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = note: accessing memory with alignment 1, but alignment 4 is required + = note: accessing memory based on pointer with alignment 1, but alignment 4 is required | note: inside `std::ptr::read::<u32>` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.rs b/tests/ui/consts/const-eval/ub-wide-ptr.rs index a765dc71273..02cf5326c6a 100644 --- a/tests/ui/consts/const-eval/ub-wide-ptr.rs +++ b/tests/ui/consts/const-eval/ub-wide-ptr.rs @@ -122,14 +122,14 @@ const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4u //~^ ERROR it is undefined behavior to use this value //~| expected a vtable const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) }; -//~^ ERROR evaluation of constant value failed -//~| does not point to a vtable +//~^ ERROR it is undefined behavior to use this value +//~| expected a vtable const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) }; -//~^ ERROR evaluation of constant value failed -//~| does not point to a vtable +//~^ ERROR it is undefined behavior to use this value +//~| expected a vtable const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) }; -//~^ ERROR evaluation of constant value failed -//~| does not point to a vtable +//~^ ERROR it is undefined behavior to use this value +//~| expected a vtable const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; //~^ ERROR it is undefined behavior to use this value //~| expected a vtable @@ -148,12 +148,12 @@ const RAW_TRAIT_OBJ_CONTENT_INVALID: *const dyn Trait = unsafe { mem::transmute: // Const eval fails for these, so they need to be statics to error. static mut RAW_TRAIT_OBJ_VTABLE_NULL_THROUGH_REF: *const dyn Trait = unsafe { +//~^ ERROR it is undefined behavior to use this value mem::transmute::<_, &dyn Trait>((&92u8, 0usize)) - //~^ ERROR could not evaluate static initializer }; static mut RAW_TRAIT_OBJ_VTABLE_INVALID_THROUGH_REF: *const dyn Trait = unsafe { +//~^ ERROR it is undefined behavior to use this value mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) - //~^ ERROR could not evaluate static initializer }; fn main() {} diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.stderr b/tests/ui/consts/const-eval/ub-wide-ptr.stderr index d8add67fac1..d57e4720c91 100644 --- a/tests/ui/consts/const-eval/ub-wide-ptr.stderr +++ b/tests/ui/consts/const-eval/ub-wide-ptr.stderr @@ -218,23 +218,38 @@ LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u HEX_DUMP } -error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:124:57 +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:124:1 | LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer + | + = 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: $SIZE, align: $ALIGN) { + HEX_DUMP + } -error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:127:57 +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:127:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer + | + = 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: $SIZE, align: $ALIGN) { + HEX_DUMP + } -error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:130:56 +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:130:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer + | + = 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: $SIZE, align: $ALIGN) { + HEX_DUMP + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:133:1 @@ -280,17 +295,27 @@ LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transm HEX_DUMP } -error[E0080]: could not evaluate static initializer - --> $DIR/ub-wide-ptr.rs:151:5 +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:150:1 + | +LL | static mut RAW_TRAIT_OBJ_VTABLE_NULL_THROUGH_REF: *const dyn Trait = unsafe { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer | -LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize)) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) + = 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: $SIZE, align: $ALIGN) { + HEX_DUMP + } -error[E0080]: could not evaluate static initializer - --> $DIR/ub-wide-ptr.rs:155:5 +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:154:1 + | +LL | static mut RAW_TRAIT_OBJ_VTABLE_INVALID_THROUGH_REF: *const dyn Trait = unsafe { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer | -LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable + = 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: $SIZE, align: $ALIGN) { + HEX_DUMP + } error: aborting due to 29 previous errors diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.32bit.stderr b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.32bit.stderr new file mode 100644 index 00000000000..33d4fec7016 --- /dev/null +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.32bit.stderr @@ -0,0 +1,20 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/mut_ref_in_final_dynamic_check.rs:17:1 + | +LL | const A: Option<&mut i32> = helper(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0: encountered mutable reference in a `const` + | + = 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) { + 2a 00 00 00 │ *... + } + +error: encountered dangling pointer in final constant + --> $DIR/mut_ref_in_final_dynamic_check.rs:24:1 + | +LL | const B: Option<&mut i32> = helper2(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.64bit.stderr b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.64bit.stderr new file mode 100644 index 00000000000..9eb2675856f --- /dev/null +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.64bit.stderr @@ -0,0 +1,20 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/mut_ref_in_final_dynamic_check.rs:17:1 + | +LL | const A: Option<&mut i32> = helper(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0: encountered mutable reference in a `const` + | + = 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) { + 2a 00 00 00 00 00 00 00 │ *....... + } + +error: encountered dangling pointer in final constant + --> $DIR/mut_ref_in_final_dynamic_check.rs:24:1 + | +LL | const B: Option<&mut i32> = helper2(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs index 074beaab2c4..22e7a74e5fb 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth #![feature(const_mut_refs)] #![feature(raw_ref_op)] @@ -9,17 +10,15 @@ const fn helper() -> Option<&'static mut i32> { unsafe { // Undefined behaviour (integer as pointer), who doesn't love tests like this. - // This code never gets executed, because the static checks fail before that. - Some(&mut *(42 as *mut i32)) //~ ERROR evaluation of constant value failed - //~| 0x2a[noalloc] is a dangling pointer + Some(&mut *(42 as *mut i32)) } } // The error is an evaluation error and not a validation error, so the error is reported // directly at the site where it occurs. -const A: Option<&mut i32> = helper(); +const A: Option<&mut i32> = helper(); //~ ERROR it is undefined behavior to use this value +//~^ encountered mutable reference in a `const` const fn helper2() -> Option<&'static mut i32> { unsafe { // Undefined behaviour (dangling pointer), who doesn't love tests like this. - // This code never gets executed, because the static checks fail before that. Some(&mut *(&mut 42 as *mut i32)) } } const B: Option<&mut i32> = helper2(); //~ ERROR encountered dangling pointer in final constant diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr deleted file mode 100644 index 6e110dbdd64..00000000000 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error[E0080]: evaluation of constant value failed - --> $DIR/mut_ref_in_final_dynamic_check.rs:13:10 - | -LL | Some(&mut *(42 as *mut i32)) - | ^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: 0x2a[noalloc] is a dangling pointer (it has no provenance) - | -note: inside `helper` - --> $DIR/mut_ref_in_final_dynamic_check.rs:13:10 - | -LL | Some(&mut *(42 as *mut i32)) - | ^^^^^^^^^^^^^^^^^^^^^^ -note: inside `A` - --> $DIR/mut_ref_in_final_dynamic_check.rs:18:29 - | -LL | const A: Option<&mut i32> = helper(); - | ^^^^^^^^ - -error: encountered dangling pointer in final constant - --> $DIR/mut_ref_in_final_dynamic_check.rs:25:1 - | -LL | const B: Option<&mut i32> = helper2(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/extra-const-ub/detect-extra-ub.rs b/tests/ui/consts/extra-const-ub/detect-extra-ub.rs index 37b37e9659e..15c06908447 100644 --- a/tests/ui/consts/extra-const-ub/detect-extra-ub.rs +++ b/tests/ui/consts/extra-const-ub/detect-extra-ub.rs @@ -88,4 +88,15 @@ const PARTIAL_POINTER: () = unsafe { const VALID_ENUM1: E = { let e = E::A; e }; const VALID_ENUM2: Result<&'static [u8], ()> = { let e = Err(()); e }; +// Htting the (non-integer) array code in validation with an immediate local. +const VALID_ARRAY: [Option<i32>; 0] = { let e = [None; 0]; e }; + +// Detecting oversized references. +const OVERSIZED_REF: () = { unsafe { + let slice: *const [u8] = transmute((1usize, usize::MAX)); + let _val = &*slice; + //[with_flag]~^ ERROR: evaluation of constant value failed + //[with_flag]~| slice is bigger than largest supported object +} }; + fn main() {} diff --git a/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr index 4ee12d501e8..0100aafb6b7 100644 --- a/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr +++ b/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr @@ -52,6 +52,12 @@ LL | let _val = *(&mem as *const Align as *const [*const u8; 2]); = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported -error: aborting due to 7 previous errors +error[E0080]: evaluation of constant value failed + --> $DIR/detect-extra-ub.rs:97:16 + | +LL | let _val = &*slice; + | ^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object + +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/error-codes/E0396-fixed.stderr b/tests/ui/error-codes/E0396-fixed.stderr index 2efbd6989ad..e77b2ce9a22 100644 --- a/tests/ui/error-codes/E0396-fixed.stderr +++ b/tests/ui/error-codes/E0396-fixed.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/E0396-fixed.rs:5:28 | LL | const VALUE: u8 = unsafe { *REG_ADDR }; - | ^^^^^^^^^ dereferencing pointer failed: 0x5f3759df[noalloc] is a dangling pointer (it has no provenance) + | ^^^^^^^^^ memory access failed: 0x5f3759df[noalloc] is a dangling pointer (it has no provenance) error: aborting due to previous error diff --git a/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs b/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs deleted file mode 100644 index a8d6365ca79..00000000000 --- a/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs +++ /dev/null @@ -1,18 +0,0 @@ -// edition:2021 - -// async_fn_in_trait is not enough to allow use of RPITIT -#![allow(incomplete_features)] -#![feature(async_fn_in_trait)] - -trait Foo { - fn bar() -> impl Sized; //~ ERROR `impl Trait` only allowed in function and inherent method argument and return types, not in trait method return - fn baz() -> Box<impl std::fmt::Display>; //~ ERROR `impl Trait` only allowed in function and inherent method argument and return types, not in trait method return -} - -// Both return_position_impl_trait_in_trait and async_fn_in_trait are required for this (see also -// feature-gate-async_fn_in_trait.rs) -trait AsyncFoo { - async fn bar() -> impl Sized; //~ ERROR `impl Trait` only allowed in function and inherent method argument and return types, not in trait method return -} - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr b/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr deleted file mode 100644 index 86f138fabdb..00000000000 --- a/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr +++ /dev/null @@ -1,30 +0,0 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in trait method return types - --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:8:17 - | -LL | fn bar() -> impl Sized; - | ^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable - -error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in trait method return types - --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:9:21 - | -LL | fn baz() -> Box<impl std::fmt::Display>; - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable - -error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in trait method return types - --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:15:23 - | -LL | async fn bar() -> impl Sized; - | ^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr index f6230b76463..1bdb2574ead 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr @@ -1,5 +1,5 @@ error[E0658]: return type notation is experimental - --> $DIR/feature-gate-return_type_notation.rs:15:17 + --> $DIR/feature-gate-return_type_notation.rs:14:17 | LL | fn foo<T: Trait<m(): Send>>() {} | ^^^^^^^^^ @@ -8,7 +8,7 @@ LL | fn foo<T: Trait<m(): Send>>() {} = help: add `#![feature(return_type_notation)]` to the crate attributes to enable error: parenthesized generic arguments cannot be used in associated type constraints - --> $DIR/feature-gate-return_type_notation.rs:15:17 + --> $DIR/feature-gate-return_type_notation.rs:14:17 | LL | fn foo<T: Trait<m(): Send>>() {} | ^-- @@ -16,7 +16,7 @@ LL | fn foo<T: Trait<m(): Send>>() {} | help: remove these parentheses error[E0220]: associated type `m` not found for `Trait` - --> $DIR/feature-gate-return_type_notation.rs:15:17 + --> $DIR/feature-gate-return_type_notation.rs:14:17 | LL | fn foo<T: Trait<m(): Send>>() {} | ^ associated type `m` not found diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr index c7f52d7cddc..dd6ebb61038 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr @@ -1,5 +1,5 @@ warning: return type notation is experimental - --> $DIR/feature-gate-return_type_notation.rs:15:17 + --> $DIR/feature-gate-return_type_notation.rs:14:17 | LL | fn foo<T: Trait<m(): Send>>() {} | ^^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.rs b/tests/ui/feature-gates/feature-gate-return_type_notation.rs index c0c285cef3c..86e2c48e188 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.rs +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.rs @@ -4,7 +4,6 @@ // [no] check-pass // Since we're not adding new syntax, `cfg`'d out RTN must pass. -#![feature(async_fn_in_trait)] trait Trait { #[allow(async_fn_in_trait)] diff --git a/tests/ui/impl-trait/alias-liveness/rpit-hidden-erased-unsoundness.rs b/tests/ui/impl-trait/alias-liveness/rpit-hidden-erased-unsoundness.rs new file mode 100644 index 00000000000..6863a3c73ba --- /dev/null +++ b/tests/ui/impl-trait/alias-liveness/rpit-hidden-erased-unsoundness.rs @@ -0,0 +1,25 @@ +// This test should never pass! + +#![feature(type_alias_impl_trait)] + +trait Captures<'a> {} +impl<T> Captures<'_> for T {} + +struct MyTy<'a, 'b>(Option<*mut &'a &'b ()>); +unsafe impl Send for MyTy<'_, 'static> {} + +fn step1<'a, 'b: 'a>() -> impl Sized + Captures<'b> + 'a { + MyTy::<'a, 'b>(None) +} + +fn step2<'a, 'b: 'a>() -> impl Sized + 'a { + step1::<'a, 'b>() + //~^ ERROR hidden type for `impl Sized + 'a` captures lifetime that does not appear in bounds +} + +fn step3<'a, 'b: 'a>() -> impl Send + 'a { + step2::<'a, 'b>() + // This should not be Send unless `'b: 'static` +} + +fn main() {} diff --git a/tests/ui/impl-trait/alias-liveness/rpit-hidden-erased-unsoundness.stderr b/tests/ui/impl-trait/alias-liveness/rpit-hidden-erased-unsoundness.stderr new file mode 100644 index 00000000000..168a5aa18ec --- /dev/null +++ b/tests/ui/impl-trait/alias-liveness/rpit-hidden-erased-unsoundness.stderr @@ -0,0 +1,18 @@ +error[E0700]: hidden type for `impl Sized + 'a` captures lifetime that does not appear in bounds + --> $DIR/rpit-hidden-erased-unsoundness.rs:16:5 + | +LL | fn step2<'a, 'b: 'a>() -> impl Sized + 'a { + | -- --------------- opaque type defined here + | | + | hidden type `impl Captures<'b> + 'a` captures the lifetime `'b` as defined here +LL | step1::<'a, 'b>() + | ^^^^^^^^^^^^^^^^^ + | +help: to declare that `impl Sized + 'a` captures `'b`, you can add an explicit `'b` lifetime bound + | +LL | fn step2<'a, 'b: 'a>() -> impl Sized + 'a + 'b { + | ++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/impl-trait/alias-liveness/rpit-hide-lifetime-for-swap.rs b/tests/ui/impl-trait/alias-liveness/rpit-hide-lifetime-for-swap.rs new file mode 100644 index 00000000000..4de2ffbb808 --- /dev/null +++ b/tests/ui/impl-trait/alias-liveness/rpit-hide-lifetime-for-swap.rs @@ -0,0 +1,32 @@ +// This test should never pass! + +use std::cell::RefCell; +use std::rc::Rc; + +trait Swap: Sized { + fn swap(self, other: Self); +} + +impl<T> Swap for Rc<RefCell<T>> { + fn swap(self, other: Self) { + <RefCell<T>>::swap(&self, &other); + } +} + +fn hide<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a { + x + //~^ ERROR hidden type for `impl Swap + 'a` captures lifetime that does not appear in bounds +} + +fn dangle() -> &'static [i32; 3] { + let long = Rc::new(RefCell::new(&[4, 5, 6])); + let x = [1, 2, 3]; + let short = Rc::new(RefCell::new(&x)); + hide(long.clone()).swap(hide(short)); + let res: &'static [i32; 3] = *long.borrow(); + res +} + +fn main() { + println!("{:?}", dangle()); +} diff --git a/tests/ui/impl-trait/alias-liveness/rpit-hide-lifetime-for-swap.stderr b/tests/ui/impl-trait/alias-liveness/rpit-hide-lifetime-for-swap.stderr new file mode 100644 index 00000000000..cabba4bafaf --- /dev/null +++ b/tests/ui/impl-trait/alias-liveness/rpit-hide-lifetime-for-swap.stderr @@ -0,0 +1,18 @@ +error[E0700]: hidden type for `impl Swap + 'a` captures lifetime that does not appear in bounds + --> $DIR/rpit-hide-lifetime-for-swap.rs:17:5 + | +LL | fn hide<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a { + | -- -------------- opaque type defined here + | | + | hidden type `Rc<RefCell<&'b T>>` captures the lifetime `'b` as defined here +LL | x + | ^ + | +help: to declare that `impl Swap + 'a` captures `'b`, you can add an explicit `'b` lifetime bound + | +LL | fn hide<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a + 'b { + | ++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.rs b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.rs new file mode 100644 index 00000000000..40efd941e33 --- /dev/null +++ b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.rs @@ -0,0 +1,28 @@ +// This test should never pass! + +#![feature(type_alias_impl_trait)] + +trait Captures<'a> {} +impl<T> Captures<'_> for T {} + +struct MyTy<'a, 'b>(Option<*mut &'a &'b ()>); +unsafe impl Send for MyTy<'_, 'static> {} + +fn step1<'a, 'b: 'a>() -> impl Sized + Captures<'b> + 'a { + MyTy::<'a, 'b>(None) +} + +mod tait { + type Tait<'a> = impl Sized + 'a; + pub(super) fn step2<'a, 'b: 'a>() -> Tait<'a> { + super::step1::<'a, 'b>() + //~^ ERROR hidden type for `Tait<'a>` captures lifetime that does not appear in bounds + } +} + +fn step3<'a, 'b: 'a>() -> impl Send + 'a { + tait::step2::<'a, 'b>() + // This should not be Send unless `'b: 'static` +} + +fn main() {} diff --git a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.stderr b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.stderr new file mode 100644 index 00000000000..baeec6d5892 --- /dev/null +++ b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.stderr @@ -0,0 +1,13 @@ +error[E0700]: hidden type for `Tait<'a>` captures lifetime that does not appear in bounds + --> $DIR/tait-hidden-erased-unsoundness.rs:18:9 + | +LL | type Tait<'a> = impl Sized + 'a; + | --------------- opaque type defined here +LL | pub(super) fn step2<'a, 'b: 'a>() -> Tait<'a> { + | -- hidden type `impl Captures<'b> + 'a` captures the lifetime `'b` as defined here +LL | super::step1::<'a, 'b>() + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/impl-trait/async_scope_creep.rs b/tests/ui/impl-trait/async_scope_creep.rs index 9a8831a299e..60975439a33 100644 --- a/tests/ui/impl-trait/async_scope_creep.rs +++ b/tests/ui/impl-trait/async_scope_creep.rs @@ -1,6 +1,6 @@ #![feature(type_alias_impl_trait)] // edition:2021 -//[rpit] check-pass +// check-pass // revisions: tait rpit struct Pending {} @@ -23,7 +23,7 @@ impl Pending { #[cfg(tait)] fn read_fut(&mut self) -> OpeningReadFuture<'_> { - self.read() //[tait]~ ERROR: cannot satisfy `impl AsyncRead + 'a == PendingReader<'a>` + self.read() } #[cfg(rpit)] diff --git a/tests/ui/impl-trait/async_scope_creep.tait.stderr b/tests/ui/impl-trait/async_scope_creep.tait.stderr deleted file mode 100644 index 165096a0574..00000000000 --- a/tests/ui/impl-trait/async_scope_creep.tait.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0284]: type annotations needed: cannot satisfy `impl AsyncRead + 'a == PendingReader<'a>` - --> $DIR/async_scope_creep.rs:26:9 - | -LL | self.read() - | ^^^^^^^^^^^ cannot satisfy `impl AsyncRead + 'a == PendingReader<'a>` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/impl-trait/auto-trait.stderr b/tests/ui/impl-trait/auto-trait-coherence.next.stderr index 81009413c9a..7833ac688ba 100644 --- a/tests/ui/impl-trait/auto-trait.stderr +++ b/tests/ui/impl-trait/auto-trait-coherence.next.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>` - --> $DIR/auto-trait.rs:21:1 + --> $DIR/auto-trait-coherence.rs:24:1 | LL | impl<T: Send> AnotherTrait for T {} | -------------------------------- first implementation here diff --git a/tests/ui/impl-trait/auto-trait-coherence.old.stderr b/tests/ui/impl-trait/auto-trait-coherence.old.stderr new file mode 100644 index 00000000000..7833ac688ba --- /dev/null +++ b/tests/ui/impl-trait/auto-trait-coherence.old.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>` + --> $DIR/auto-trait-coherence.rs:24:1 + | +LL | impl<T: Send> AnotherTrait for T {} + | -------------------------------- first implementation here +... +LL | impl AnotherTrait for D<OpaqueType> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/impl-trait/auto-trait.rs b/tests/ui/impl-trait/auto-trait-coherence.rs index 35994e4a5ba..a5cd01a87ff 100644 --- a/tests/ui/impl-trait/auto-trait.rs +++ b/tests/ui/impl-trait/auto-trait-coherence.rs @@ -1,3 +1,6 @@ +// revisions: old next +//[next] compile-flags: -Ztrait-solver=next + // Tests that type alias impls traits do not leak auto-traits for // the purposes of coherence checking #![feature(type_alias_impl_trait)] diff --git a/tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs b/tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs index e62662f2f07..09fbef2ec07 100644 --- a/tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs +++ b/tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs @@ -1,7 +1,6 @@ // compile-flags: --crate-type=lib // check-pass -#![feature(return_position_impl_trait_in_trait)] #![deny(refining_impl_trait)] pub trait Tr<T> { diff --git a/tests/ui/impl-trait/in-trait/assumed-wf-bounds-in-impl.rs b/tests/ui/impl-trait/in-trait/assumed-wf-bounds-in-impl.rs index 5de9c01e3e0..afb9992de49 100644 --- a/tests/ui/impl-trait/in-trait/assumed-wf-bounds-in-impl.rs +++ b/tests/ui/impl-trait/in-trait/assumed-wf-bounds-in-impl.rs @@ -2,7 +2,6 @@ // edition: 2021 // issue: 113796 -#![feature(async_fn_in_trait)] trait AsyncLendingIterator { type Item<'a> diff --git a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs index 6e99402113a..a213994ff86 100644 --- a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs +++ b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs @@ -1,4 +1,4 @@ -#![feature(return_position_impl_trait_in_trait, lint_reasons)] +#![feature(lint_reasons)] use std::ops::Deref; diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs index 3a93dfee57f..41d5f0f6449 100644 --- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs @@ -1,6 +1,5 @@ // issue: 114146 -#![feature(return_position_impl_trait_in_trait)] trait Foo { fn bar<'other: 'a>() -> impl Sized + 'a {} diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr index 3a1f8f90837..b0832eb33ca 100644 --- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/bad-item-bound-within-rpitit-2.rs:6:20 + --> $DIR/bad-item-bound-within-rpitit-2.rs:5:20 | LL | fn bar<'other: 'a>() -> impl Sized + 'a {} | ^^ undeclared lifetime @@ -14,7 +14,7 @@ LL | trait Foo<'a> { | ++++ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/bad-item-bound-within-rpitit-2.rs:6:42 + --> $DIR/bad-item-bound-within-rpitit-2.rs:5:42 | LL | fn bar<'other: 'a>() -> impl Sized + 'a {} | ^^ undeclared lifetime diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs index fbbbb8585d1..5ddc97f1adc 100644 --- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs @@ -1,6 +1,5 @@ // issue: 114145 -#![feature(return_position_impl_trait_in_trait)] pub trait Iterable { type Item<'a> diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr index a5fb338ea4e..324eaa37a3d 100644 --- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr @@ -1,5 +1,5 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/bad-item-bound-within-rpitit.rs:16:13 + --> $DIR/bad-item-bound-within-rpitit.rs:15:13 | LL | type Item<'a> | ------------- definition of `Item` from trait @@ -13,7 +13,7 @@ LL | where Self: 'b; | ~~~~~~~~~~~~~~ warning: impl trait in impl method signature does not match trait method signature - --> $DIR/bad-item-bound-within-rpitit.rs:19:28 + --> $DIR/bad-item-bound-within-rpitit.rs:18:28 | LL | fn iter(&self) -> impl '_ + Iterator<Item = Self::Item<'_>>; | ----------------------------------------- return type from trait method defined here diff --git a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs index f5ee4690fa9..87eb7beb1ee 100644 --- a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs +++ b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs @@ -1,6 +1,5 @@ // check-pass -#![feature(return_position_impl_trait_in_trait)] struct TestA {} struct TestB {} diff --git a/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.rs b/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.rs index 742537ffcc4..2845b401bd5 100644 --- a/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.rs +++ b/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.rs @@ -1,5 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] - struct Wrapper<G: Send>(G); trait Foo { diff --git a/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.stderr b/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.stderr index dee87d08238..1570b2ecd53 100644 --- a/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.stderr +++ b/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.stderr @@ -1,12 +1,12 @@ error[E0277]: `impl Sized` cannot be sent between threads safely - --> $DIR/check-wf-on-non-defaulted-rpitit.rs:6:17 + --> $DIR/check-wf-on-non-defaulted-rpitit.rs:4:17 | LL | fn bar() -> Wrapper<impl Sized>; | ^^^^^^^^^^^^^^^^^^^ `impl Sized` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `impl Sized` note: required by a bound in `Wrapper` - --> $DIR/check-wf-on-non-defaulted-rpitit.rs:3:19 + --> $DIR/check-wf-on-non-defaulted-rpitit.rs:1:19 | LL | struct Wrapper<G: Send>(G); | ^^^^ required by this bound in `Wrapper` diff --git a/tests/ui/impl-trait/in-trait/deep-match-works.rs b/tests/ui/impl-trait/in-trait/deep-match-works.rs index fc290f11f9d..8c992743862 100644 --- a/tests/ui/impl-trait/in-trait/deep-match-works.rs +++ b/tests/ui/impl-trait/in-trait/deep-match-works.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(return_position_impl_trait_in_trait, lint_reasons)] +#![feature(lint_reasons)] #![allow(incomplete_features)] pub struct Wrapper<T>(T); diff --git a/tests/ui/impl-trait/in-trait/deep-match.rs b/tests/ui/impl-trait/in-trait/deep-match.rs index 0cae88f349f..02889347ba4 100644 --- a/tests/ui/impl-trait/in-trait/deep-match.rs +++ b/tests/ui/impl-trait/in-trait/deep-match.rs @@ -1,4 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] struct Wrapper<T>(T); diff --git a/tests/ui/impl-trait/in-trait/deep-match.stderr b/tests/ui/impl-trait/in-trait/deep-match.stderr index f0ad3c16e9c..9cfc54f5094 100644 --- a/tests/ui/impl-trait/in-trait/deep-match.stderr +++ b/tests/ui/impl-trait/in-trait/deep-match.stderr @@ -1,5 +1,5 @@ error[E0053]: method `bar` has an incompatible return type for trait - --> $DIR/deep-match.rs:11:17 + --> $DIR/deep-match.rs:10:17 | LL | fn bar() -> i32 { | ^^^ diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err-2.rs b/tests/ui/impl-trait/in-trait/default-body-type-err-2.rs index 45ae2b8ad3a..29bcbe16d83 100644 --- a/tests/ui/impl-trait/in-trait/default-body-type-err-2.rs +++ b/tests/ui/impl-trait/in-trait/default-body-type-err-2.rs @@ -1,7 +1,6 @@ // edition:2021 #![allow(incomplete_features)] -#![feature(async_fn_in_trait)] pub trait Foo { async fn woopsie_async(&self) -> String { diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr index cc3bdf0e571..fcace10cd01 100644 --- a/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr +++ b/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/default-body-type-err-2.rs:8:9 + --> $DIR/default-body-type-err-2.rs:7:9 | LL | 42 | ^^- help: try using a conversion method: `.to_string()` diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err.rs b/tests/ui/impl-trait/in-trait/default-body-type-err.rs index ac9baf91cae..977ff8111dd 100644 --- a/tests/ui/impl-trait/in-trait/default-body-type-err.rs +++ b/tests/ui/impl-trait/in-trait/default-body-type-err.rs @@ -1,5 +1,4 @@ #![allow(incomplete_features)] -#![feature(return_position_impl_trait_in_trait)] use std::ops::Deref; diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err.stderr index 4742eb37d3e..3d9ca62b0db 100644 --- a/tests/ui/impl-trait/in-trait/default-body-type-err.stderr +++ b/tests/ui/impl-trait/in-trait/default-body-type-err.stderr @@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String` - --> $DIR/default-body-type-err.rs:7:22 + --> $DIR/default-body-type-err.rs:6:22 | LL | fn lol(&self) -> impl Deref<Target = String> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `String` diff --git a/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs b/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs index 9c60cf4e72a..1d1f555080c 100644 --- a/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs +++ b/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs @@ -1,7 +1,6 @@ // edition:2021 // check-pass -#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)] #![allow(incomplete_features)] use std::fmt::Debug; diff --git a/tests/ui/impl-trait/in-trait/default-body.rs b/tests/ui/impl-trait/in-trait/default-body.rs index d3ea9fbeabc..ff70f1e232d 100644 --- a/tests/ui/impl-trait/in-trait/default-body.rs +++ b/tests/ui/impl-trait/in-trait/default-body.rs @@ -1,7 +1,6 @@ // check-pass // edition:2021 -#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)] #![allow(incomplete_features)] use std::fmt::Debug; diff --git a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs index 817a4d7dbbe..ca41eb8bc71 100644 --- a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs +++ b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs @@ -1,6 +1,5 @@ // check-pass -#![feature(return_position_impl_trait_in_trait)] trait Trait { type Type; diff --git a/tests/ui/impl-trait/in-trait/default-method-constraint.rs b/tests/ui/impl-trait/in-trait/default-method-constraint.rs index 28d76241f27..8ab2e2797f1 100644 --- a/tests/ui/impl-trait/in-trait/default-method-constraint.rs +++ b/tests/ui/impl-trait/in-trait/default-method-constraint.rs @@ -2,7 +2,6 @@ // This didn't work in the previous default RPITIT method hack attempt -#![feature(return_position_impl_trait_in_trait)] trait Foo { fn bar(x: bool) -> impl Sized { diff --git a/tests/ui/impl-trait/in-trait/doesnt-satisfy.rs b/tests/ui/impl-trait/in-trait/doesnt-satisfy.rs index bb4e0d44f3e..5a53c9a19b5 100644 --- a/tests/ui/impl-trait/in-trait/doesnt-satisfy.rs +++ b/tests/ui/impl-trait/in-trait/doesnt-satisfy.rs @@ -1,4 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] trait Foo { diff --git a/tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr b/tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr index 7c56ffa10e1..cb9ecc7fa48 100644 --- a/tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr +++ b/tests/ui/impl-trait/in-trait/doesnt-satisfy.stderr @@ -1,5 +1,5 @@ error[E0277]: `()` doesn't implement `std::fmt::Display` - --> $DIR/doesnt-satisfy.rs:9:17 + --> $DIR/doesnt-satisfy.rs:8:17 | LL | fn bar() -> () {} | ^^ `()` cannot be formatted with the default formatter @@ -7,7 +7,7 @@ LL | fn bar() -> () {} = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead note: required by a bound in `Foo::{opaque#0}` - --> $DIR/doesnt-satisfy.rs:5:22 + --> $DIR/doesnt-satisfy.rs:4:22 | LL | fn bar() -> impl std::fmt::Display; | ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::{opaque#0}` diff --git a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.rs b/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.rs index 4719d5d3c67..fe0f011b6b0 100644 --- a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.rs +++ b/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.rs @@ -1,5 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] - trait MyTrait { fn foo(&self) -> impl Sized; fn bar(&self) -> impl Sized; diff --git a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.stderr b/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.stderr index 66ee142ccc4..830e663da37 100644 --- a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.stderr +++ b/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.stderr @@ -1,5 +1,5 @@ error[E0046]: not all trait items implemented, missing: `foo` - --> $DIR/dont-project-to-rpitit-with-no-value.rs:8:1 + --> $DIR/dont-project-to-rpitit-with-no-value.rs:6:1 | LL | fn foo(&self) -> impl Sized; | ---------------------------- `foo` from trait diff --git a/tests/ui/impl-trait/in-trait/early.rs b/tests/ui/impl-trait/in-trait/early.rs index bb5718b4934..c4996674dd1 100644 --- a/tests/ui/impl-trait/in-trait/early.rs +++ b/tests/ui/impl-trait/in-trait/early.rs @@ -1,7 +1,6 @@ // check-pass // edition:2021 -#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)] #![allow(incomplete_features)] pub trait Foo { diff --git a/tests/ui/impl-trait/in-trait/encode.rs b/tests/ui/impl-trait/in-trait/encode.rs index efb9f6498ba..4df26b0f297 100644 --- a/tests/ui/impl-trait/in-trait/encode.rs +++ b/tests/ui/impl-trait/in-trait/encode.rs @@ -1,7 +1,6 @@ // build-pass // compile-flags: --crate-type=lib -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] trait Foo { diff --git a/tests/ui/impl-trait/in-trait/gat-outlives.rs b/tests/ui/impl-trait/in-trait/gat-outlives.rs new file mode 100644 index 00000000000..83dd6cfce53 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/gat-outlives.rs @@ -0,0 +1,17 @@ +// edition: 2021 + +use std::future::Future; + +trait Trait { + type Gat<'a>; + //~^ ERROR missing required bound on `Gat` + async fn foo(&self) -> Self::Gat<'_>; +} + +trait Trait2 { + type Gat<'a>; + //~^ ERROR missing required bound on `Gat` + async fn foo(&self) -> impl Future<Output = Self::Gat<'_>>; +} + +fn main() {} diff --git a/tests/ui/impl-trait/in-trait/gat-outlives.stderr b/tests/ui/impl-trait/in-trait/gat-outlives.stderr new file mode 100644 index 00000000000..8ec4b0ab2ee --- /dev/null +++ b/tests/ui/impl-trait/in-trait/gat-outlives.stderr @@ -0,0 +1,24 @@ +error: missing required bound on `Gat` + --> $DIR/gat-outlives.rs:6:5 + | +LL | type Gat<'a>; + | ^^^^^^^^^^^^- + | | + | help: add the required where clause: `where Self: 'a` + | + = note: this bound is currently required to ensure that impls have maximum flexibility + = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information + +error: missing required bound on `Gat` + --> $DIR/gat-outlives.rs:12:5 + | +LL | type Gat<'a>; + | ^^^^^^^^^^^^- + | | + | help: add the required where clause: `where Self: 'a` + | + = note: this bound is currently required to ensure that impls have maximum flexibility + = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information + +error: aborting due to 2 previous errors + diff --git a/tests/ui/impl-trait/in-trait/generics-mismatch.rs b/tests/ui/impl-trait/in-trait/generics-mismatch.rs index cc0fc720ebb..2e5373dbd5d 100644 --- a/tests/ui/impl-trait/in-trait/generics-mismatch.rs +++ b/tests/ui/impl-trait/in-trait/generics-mismatch.rs @@ -1,4 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] struct U; diff --git a/tests/ui/impl-trait/in-trait/generics-mismatch.stderr b/tests/ui/impl-trait/in-trait/generics-mismatch.stderr index cd42683e022..3dbf2235c5e 100644 --- a/tests/ui/impl-trait/in-trait/generics-mismatch.stderr +++ b/tests/ui/impl-trait/in-trait/generics-mismatch.stderr @@ -1,5 +1,5 @@ error[E0049]: method `bar` has 1 type parameter but its trait declaration has 0 type parameters - --> $DIR/generics-mismatch.rs:11:12 + --> $DIR/generics-mismatch.rs:10:12 | LL | fn bar(&self) -> impl Sized; | - expected 0 type parameters diff --git a/tests/ui/impl-trait/in-trait/issue-102140.rs b/tests/ui/impl-trait/in-trait/issue-102140.rs index be1e012acb1..1132bd25f81 100644 --- a/tests/ui/impl-trait/in-trait/issue-102140.rs +++ b/tests/ui/impl-trait/in-trait/issue-102140.rs @@ -1,4 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] trait Marker {} diff --git a/tests/ui/impl-trait/in-trait/issue-102140.stderr b/tests/ui/impl-trait/in-trait/issue-102140.stderr index 18bb63745d7..6d50d2f3a24 100644 --- a/tests/ui/impl-trait/in-trait/issue-102140.stderr +++ b/tests/ui/impl-trait/in-trait/issue-102140.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied - --> $DIR/issue-102140.rs:23:22 + --> $DIR/issue-102140.rs:22:22 | LL | MyTrait::foo(&self) | ------------ ^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait` @@ -13,7 +13,7 @@ LL + MyTrait::foo(self) | error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied - --> $DIR/issue-102140.rs:23:9 + --> $DIR/issue-102140.rs:22:9 | LL | MyTrait::foo(&self) | ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait` @@ -21,7 +21,7 @@ LL | MyTrait::foo(&self) = help: the trait `MyTrait` is implemented for `Outer` error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied - --> $DIR/issue-102140.rs:23:9 + --> $DIR/issue-102140.rs:22:9 | LL | MyTrait::foo(&self) | ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait` diff --git a/tests/ui/impl-trait/in-trait/issue-102301.rs b/tests/ui/impl-trait/in-trait/issue-102301.rs index a93714a658e..600a21b07be 100644 --- a/tests/ui/impl-trait/in-trait/issue-102301.rs +++ b/tests/ui/impl-trait/in-trait/issue-102301.rs @@ -1,6 +1,5 @@ // check-pass -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] trait Foo<T> { diff --git a/tests/ui/impl-trait/in-trait/issue-102571.rs b/tests/ui/impl-trait/in-trait/issue-102571.rs index ccb53031c44..4534753f0d2 100644 --- a/tests/ui/impl-trait/in-trait/issue-102571.rs +++ b/tests/ui/impl-trait/in-trait/issue-102571.rs @@ -1,4 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] use std::fmt::Display; diff --git a/tests/ui/impl-trait/in-trait/issue-102571.stderr b/tests/ui/impl-trait/in-trait/issue-102571.stderr index 594b9ae9cd6..4d1a0feb22b 100644 --- a/tests/ui/impl-trait/in-trait/issue-102571.stderr +++ b/tests/ui/impl-trait/in-trait/issue-102571.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-102571.rs:12:9 + --> $DIR/issue-102571.rs:11:9 | LL | let () = t.bar(); | ^^ ------- this expression has type `impl Deref<Target = impl std::fmt::Display + ?Sized>` diff --git a/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs b/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs index 49d36d6c99c..4073ef8ac19 100644 --- a/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs +++ b/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(associated_type_bounds, return_position_impl_trait_in_trait)] +#![feature(associated_type_bounds)] trait Trait { type Type; diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr index 239c4b35c72..59139e4d5ae 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr @@ -1,5 +1,5 @@ error[E0053]: method `early` has an incompatible type for trait - --> $DIR/method-signature-matches.rs:58:27 + --> $DIR/method-signature-matches.rs:57:27 | LL | fn early<'late, T>(_: &'late ()) {} | - ^^^^^^^^^ @@ -9,7 +9,7 @@ LL | fn early<'late, T>(_: &'late ()) {} | this type parameter | note: type in trait - --> $DIR/method-signature-matches.rs:53:28 + --> $DIR/method-signature-matches.rs:52:28 | LL | fn early<'early, T>(x: &'early T) -> impl Sized; | ^^^^^^^^^ diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr index d3183b92e84..e0bd1cc4f19 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr @@ -1,5 +1,5 @@ error[E0053]: method `owo` has an incompatible type for trait - --> $DIR/method-signature-matches.rs:14:15 + --> $DIR/method-signature-matches.rs:13:15 | LL | fn owo(_: u8) {} | ^^ @@ -8,7 +8,7 @@ LL | fn owo(_: u8) {} | help: change the parameter type to match the trait: `()` | note: type in trait - --> $DIR/method-signature-matches.rs:9:15 + --> $DIR/method-signature-matches.rs:8:15 | LL | fn owo(x: ()) -> impl Sized; | ^^ diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr index 80fda1c9fe1..096e96c85c4 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr @@ -1,5 +1,5 @@ error[E0053]: method `owo` has an incompatible type for trait - --> $DIR/method-signature-matches.rs:25:21 + --> $DIR/method-signature-matches.rs:24:21 | LL | async fn owo(_: u8) {} | ^^ @@ -8,7 +8,7 @@ LL | async fn owo(_: u8) {} | help: change the parameter type to match the trait: `()` | note: type in trait - --> $DIR/method-signature-matches.rs:20:21 + --> $DIR/method-signature-matches.rs:19:21 | LL | async fn owo(x: ()) {} | ^^ diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.rs b/tests/ui/impl-trait/in-trait/method-signature-matches.rs index 294f93b30d0..99ace66facb 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.rs +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.rs @@ -1,7 +1,6 @@ // edition: 2021 // revisions: mismatch mismatch_async too_many too_few lt -#![feature(return_position_impl_trait_in_trait, async_fn_in_trait)] #![allow(incomplete_features)] #[cfg(mismatch)] diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.too_few.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.too_few.stderr index 24bcfeb748f..96eff1a5815 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.too_few.stderr +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.too_few.stderr @@ -1,5 +1,5 @@ error[E0050]: method `come_on_a_little_more_effort` has 0 parameters but the declaration in trait `TooLittle::come_on_a_little_more_effort` has 3 - --> $DIR/method-signature-matches.rs:47:5 + --> $DIR/method-signature-matches.rs:46:5 | LL | fn come_on_a_little_more_effort(_: (), _: (), _: ()) -> impl Sized; | ---------------- trait requires 3 parameters diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.too_many.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.too_many.stderr index 616cbd2905c..0fc847051c9 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.too_many.stderr +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.too_many.stderr @@ -1,5 +1,5 @@ error[E0050]: method `calm_down_please` has 3 parameters but the declaration in trait `TooMuch::calm_down_please` has 0 - --> $DIR/method-signature-matches.rs:36:28 + --> $DIR/method-signature-matches.rs:35:28 | LL | fn calm_down_please() -> impl Sized; | ------------------------------------ trait requires 0 parameters diff --git a/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.rs b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.rs index abc845d3afa..6088dcc61d6 100644 --- a/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.rs +++ b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.rs @@ -1,5 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] - trait Iterable { type Item<'a> where diff --git a/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.stderr b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.stderr index 0d74c0b69ce..1fd678a1f3a 100644 --- a/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.stderr +++ b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'missing` - --> $DIR/missing-lt-outlives-in-rpitit-114274.rs:8:55 + --> $DIR/missing-lt-outlives-in-rpitit-114274.rs:6:55 | LL | fn iter(&self) -> impl Iterator<Item = Self::Item<'missing>>; | ^^^^^^^^ undeclared lifetime diff --git a/tests/ui/impl-trait/in-trait/nested-rpitit.rs b/tests/ui/impl-trait/in-trait/nested-rpitit.rs index 58ba1acaf14..58b79c99155 100644 --- a/tests/ui/impl-trait/in-trait/nested-rpitit.rs +++ b/tests/ui/impl-trait/in-trait/nested-rpitit.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(return_position_impl_trait_in_trait, lint_reasons)] +#![feature(lint_reasons)] #![allow(incomplete_features)] use std::fmt::Display; diff --git a/tests/ui/impl-trait/in-trait/object-safety-sized.rs b/tests/ui/impl-trait/in-trait/object-safety-sized.rs index f221cfbb176..35afe80c97f 100644 --- a/tests/ui/impl-trait/in-trait/object-safety-sized.rs +++ b/tests/ui/impl-trait/in-trait/object-safety-sized.rs @@ -2,7 +2,6 @@ // revisions: current next //[next] compile-flags: -Ztrait-solver=next -#![feature(return_position_impl_trait_in_trait)] fn main() { let vec: Vec<Box<dyn Trait>> = Vec::new(); diff --git a/tests/ui/impl-trait/in-trait/object-safety.rs b/tests/ui/impl-trait/in-trait/object-safety.rs index d1c9fba4e99..15634537dae 100644 --- a/tests/ui/impl-trait/in-trait/object-safety.rs +++ b/tests/ui/impl-trait/in-trait/object-safety.rs @@ -1,4 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] use std::fmt::Debug; diff --git a/tests/ui/impl-trait/in-trait/object-safety.stderr b/tests/ui/impl-trait/in-trait/object-safety.stderr index 0170dc5d0fc..8d882391251 100644 --- a/tests/ui/impl-trait/in-trait/object-safety.stderr +++ b/tests/ui/impl-trait/in-trait/object-safety.stderr @@ -1,11 +1,11 @@ error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:17:33 + --> $DIR/object-safety.rs:16:33 | LL | let i = Box::new(42_u32) as Box<dyn Foo>; | ^^^^^^^^^^^^ `Foo` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> - --> $DIR/object-safety.rs:7:22 + --> $DIR/object-safety.rs:6:22 | LL | trait Foo { | --- this trait cannot be made into an object... @@ -14,13 +14,13 @@ LL | fn baz(&self) -> impl Debug; = help: consider moving `baz` to another trait error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:20:15 + --> $DIR/object-safety.rs:19:15 | LL | let s = i.baz(); | ^^^ `Foo` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> - --> $DIR/object-safety.rs:7:22 + --> $DIR/object-safety.rs:6:22 | LL | trait Foo { | --- this trait cannot be made into an object... @@ -29,13 +29,13 @@ LL | fn baz(&self) -> impl Debug; = help: consider moving `baz` to another trait error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:20:13 + --> $DIR/object-safety.rs:19:13 | LL | let s = i.baz(); | ^^^^^^^ `Foo` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> - --> $DIR/object-safety.rs:7:22 + --> $DIR/object-safety.rs:6:22 | LL | trait Foo { | --- this trait cannot be made into an object... @@ -44,13 +44,13 @@ LL | fn baz(&self) -> impl Debug; = help: consider moving `baz` to another trait error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:17:13 + --> $DIR/object-safety.rs:16:13 | LL | let i = Box::new(42_u32) as Box<dyn Foo>; | ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> - --> $DIR/object-safety.rs:7:22 + --> $DIR/object-safety.rs:6:22 | LL | trait Foo { | --- this trait cannot be made into an object... diff --git a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs index 3ac264e8eba..fc708536b0f 100644 --- a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs +++ b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs @@ -1,4 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] use std::fmt::Display; diff --git a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr index 15edda48340..99b62e80acd 100644 --- a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr +++ b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/opaque-in-impl-is-opaque.rs:17:19 + --> $DIR/opaque-in-impl-is-opaque.rs:16:19 | LL | fn bar(&self) -> impl Display { | ------------ the found opaque type diff --git a/tests/ui/impl-trait/in-trait/opaque-in-impl.rs b/tests/ui/impl-trait/in-trait/opaque-in-impl.rs index 2e06629699a..3edd588a1b3 100644 --- a/tests/ui/impl-trait/in-trait/opaque-in-impl.rs +++ b/tests/ui/impl-trait/in-trait/opaque-in-impl.rs @@ -1,6 +1,5 @@ // check-pass -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] use std::fmt::Debug; diff --git a/tests/ui/impl-trait/in-trait/outlives-in-nested-rpit.rs b/tests/ui/impl-trait/in-trait/outlives-in-nested-rpit.rs index 6330242ceeb..317ff7fe853 100644 --- a/tests/ui/impl-trait/in-trait/outlives-in-nested-rpit.rs +++ b/tests/ui/impl-trait/in-trait/outlives-in-nested-rpit.rs @@ -1,6 +1,5 @@ // check-pass -#![feature(return_position_impl_trait_in_trait)] trait Foo { fn early<'a, T: 'a>(x: &'a T) -> impl Iterator<Item = impl Into<&'a T>>; diff --git a/tests/ui/impl-trait/in-trait/refine.rs b/tests/ui/impl-trait/in-trait/refine.rs index f00478b0bb9..100e6da06a8 100644 --- a/tests/ui/impl-trait/in-trait/refine.rs +++ b/tests/ui/impl-trait/in-trait/refine.rs @@ -1,4 +1,3 @@ -#![feature(return_position_impl_trait_in_trait, async_fn_in_trait)] #![deny(refining_impl_trait)] pub trait Foo { diff --git a/tests/ui/impl-trait/in-trait/refine.stderr b/tests/ui/impl-trait/in-trait/refine.stderr index 1d9852c682c..96a9bc059c8 100644 --- a/tests/ui/impl-trait/in-trait/refine.stderr +++ b/tests/ui/impl-trait/in-trait/refine.stderr @@ -1,5 +1,5 @@ error: impl trait in impl method signature does not match trait method signature - --> $DIR/refine.rs:10:22 + --> $DIR/refine.rs:9:22 | LL | fn bar() -> impl Sized; | ---------- return type from trait method defined here @@ -9,7 +9,7 @@ LL | fn bar() -> impl Copy {} | = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate note: the lint level is defined here - --> $DIR/refine.rs:2:9 + --> $DIR/refine.rs:1:9 | LL | #![deny(refining_impl_trait)] | ^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | fn bar() -> impl Sized {} | ~~~~~~~~~~ error: impl trait in impl method signature does not match trait method signature - --> $DIR/refine.rs:16:5 + --> $DIR/refine.rs:15:5 | LL | fn bar() -> impl Sized; | ---------- return type from trait method defined here @@ -34,7 +34,7 @@ LL | fn bar()-> impl Sized {} | +++++++++++++ error: impl trait in impl method signature does not match trait method signature - --> $DIR/refine.rs:22:17 + --> $DIR/refine.rs:21:17 | LL | fn bar() -> impl Sized; | ---------- return type from trait method defined here @@ -49,7 +49,7 @@ LL | fn bar() -> impl Sized {} | ~~~~~~~~~~ error: impl trait in impl method signature does not match trait method signature - --> $DIR/refine.rs:44:27 + --> $DIR/refine.rs:43:27 | LL | fn bar<'a>(&'a self) -> impl Sized + 'a; | --------------- return type from trait method defined here diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs index 5d9a224ccd6..ad73b12feb5 100644 --- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs +++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs @@ -1,5 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] - trait Foo<T> { fn foo<F2>(self) -> impl Foo<T>; } diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr index 668fc6cbe7f..181d6a284da 100644 --- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr +++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr @@ -1,12 +1,12 @@ error[E0277]: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied - --> $DIR/return-dont-satisfy-bounds.rs:10:34 + --> $DIR/return-dont-satisfy-bounds.rs:8:34 | LL | fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> { | ^^^^^^^^^^^^ the trait `Foo<char>` is not implemented for `impl Foo<u8>` | = help: the trait `Foo<char>` is implemented for `Bar` note: required by a bound in `Foo::{opaque#0}` - --> $DIR/return-dont-satisfy-bounds.rs:4:30 + --> $DIR/return-dont-satisfy-bounds.rs:2:30 | LL | fn foo<F2>(self) -> impl Foo<T>; | ^^^^^^ required by this bound in `Foo::{opaque#0}` diff --git a/tests/ui/impl-trait/in-trait/reveal.rs b/tests/ui/impl-trait/in-trait/reveal.rs index b1b46d75b8f..cc78ce8fea2 100644 --- a/tests/ui/impl-trait/in-trait/reveal.rs +++ b/tests/ui/impl-trait/in-trait/reveal.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(return_position_impl_trait_in_trait, lint_reasons)] +#![feature(lint_reasons)] #![allow(incomplete_features)] pub trait Foo { diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs index 5e14a7f8e72..37b0b229776 100644 --- a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs +++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs @@ -1,5 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] - trait Extend { fn extend<'a: 'a>(_: &'a str) -> (impl Sized + 'a, &'static str); } diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr index 1d947310e12..afc59cc5b58 100644 --- a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr +++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr @@ -1,12 +1,12 @@ error[E0491]: in type `&'static &'a ()`, reference has a longer lifetime than the data it references - --> $DIR/rpitit-hidden-types-self-implied-wf-via-param.rs:8:38 + --> $DIR/rpitit-hidden-types-self-implied-wf-via-param.rs:6:38 | LL | fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the pointer is valid for the static lifetime note: but the referenced data is only valid for the lifetime `'a` as defined here - --> $DIR/rpitit-hidden-types-self-implied-wf-via-param.rs:8:15 + --> $DIR/rpitit-hidden-types-self-implied-wf-via-param.rs:6:15 | LL | fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str) | ^^ diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs index c1885af4e5e..bacd5007768 100644 --- a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs +++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs @@ -1,5 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] - trait Extend { fn extend(_: &str) -> (impl Sized + '_, &'static str); } diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr index 7b63e72acbf..7e1a8f083ac 100644 --- a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr +++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr @@ -1,12 +1,12 @@ error[E0491]: in type `&'static &()`, reference has a longer lifetime than the data it references - --> $DIR/rpitit-hidden-types-self-implied-wf.rs:8:27 + --> $DIR/rpitit-hidden-types-self-implied-wf.rs:6:27 | LL | fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the pointer is valid for the static lifetime note: but the referenced data is only valid for the anonymous lifetime defined here - --> $DIR/rpitit-hidden-types-self-implied-wf.rs:8:18 + --> $DIR/rpitit-hidden-types-self-implied-wf.rs:6:18 | LL | fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) { | ^^^^ diff --git a/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs index 44a2b430344..b9fe8d8bfc5 100644 --- a/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs +++ b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs @@ -1,6 +1,6 @@ // issue: 113903 -#![feature(return_position_impl_trait_in_trait, lint_reasons)] +#![feature(lint_reasons)] use std::ops::Deref; diff --git a/tests/ui/impl-trait/in-trait/sibling-function-constraint.rs b/tests/ui/impl-trait/in-trait/sibling-function-constraint.rs new file mode 100644 index 00000000000..fe162e6cf80 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/sibling-function-constraint.rs @@ -0,0 +1,21 @@ +// Checks that a sibling function (i.e. `foo`) cannot constrain +// an RPITIT from another function (`bar`). + +trait Trait { + fn foo(); + + fn bar() -> impl Sized; +} + +impl Trait for () { + fn foo() { + let _: String = Self::bar(); + //~^ ERROR mismatched types + } + + fn bar() -> impl Sized { + loop {} + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/in-trait/sibling-function-constraint.stderr b/tests/ui/impl-trait/in-trait/sibling-function-constraint.stderr new file mode 100644 index 00000000000..729963a8141 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/sibling-function-constraint.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/sibling-function-constraint.rs:12:25 + | +LL | let _: String = Self::bar(); + | ------ ^^^^^^^^^^^ expected `String`, found opaque type + | | + | expected due to this +... +LL | fn bar() -> impl Sized { + | ---------- the found opaque type + | + = note: expected struct `String` + found opaque type `impl Sized` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.rs b/tests/ui/impl-trait/in-trait/signature-mismatch.rs index 685c0f06e88..d85ee5fc704 100644 --- a/tests/ui/impl-trait/in-trait/signature-mismatch.rs +++ b/tests/ui/impl-trait/in-trait/signature-mismatch.rs @@ -2,7 +2,7 @@ // revisions: success failure //[success] check-pass -#![feature(return_position_impl_trait_in_trait, lint_reasons)] +#![feature(lint_reasons)] use std::future::Future; diff --git a/tests/ui/impl-trait/in-trait/specialization-broken.rs b/tests/ui/impl-trait/in-trait/specialization-broken.rs index 2fcffdf3f9a..a06cd814f7c 100644 --- a/tests/ui/impl-trait/in-trait/specialization-broken.rs +++ b/tests/ui/impl-trait/in-trait/specialization-broken.rs @@ -2,7 +2,6 @@ // But we fixed an ICE anyways. #![feature(specialization)] -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] trait Foo { diff --git a/tests/ui/impl-trait/in-trait/specialization-broken.stderr b/tests/ui/impl-trait/in-trait/specialization-broken.stderr index dc621d6b8a8..1d169b5d690 100644 --- a/tests/ui/impl-trait/in-trait/specialization-broken.stderr +++ b/tests/ui/impl-trait/in-trait/specialization-broken.stderr @@ -1,5 +1,5 @@ error[E0053]: method `bar` has an incompatible type for trait - --> $DIR/specialization-broken.rs:16:22 + --> $DIR/specialization-broken.rs:15:22 | LL | default impl<U> Foo for U | - this type parameter @@ -11,7 +11,7 @@ LL | fn bar(&self) -> U { | help: change the output type to match the trait: `impl Sized` | note: type in trait - --> $DIR/specialization-broken.rs:9:22 + --> $DIR/specialization-broken.rs:8:22 | LL | fn bar(&self) -> impl Sized; | ^^^^^^^^^^ @@ -19,12 +19,12 @@ LL | fn bar(&self) -> impl Sized; found signature `fn(&U) -> U` error: method with return-position `impl Trait` in trait cannot be specialized - --> $DIR/specialization-broken.rs:16:5 + --> $DIR/specialization-broken.rs:15:5 | LL | fn bar(&self) -> U { | ^^^^^^^^^^^^^^^^^^ | - = note: specialization behaves in inconsistent and surprising ways with `#![feature(return_position_impl_trait_in_trait)]`, and for now is disallowed + = note: specialization behaves in inconsistent and surprising ways with return position `impl Trait` in traits, and for now is disallowed error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs b/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs index 41fc285883a..05386632758 100644 --- a/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs +++ b/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs @@ -1,7 +1,7 @@ // check-pass #![feature(specialization)] -#![feature(return_position_impl_trait_in_trait, lint_reasons)] +#![feature(lint_reasons)] #![allow(incomplete_features)] pub trait Foo { diff --git a/tests/ui/impl-trait/in-trait/success.rs b/tests/ui/impl-trait/in-trait/success.rs index 7d415ea17a4..eb2349feb29 100644 --- a/tests/ui/impl-trait/in-trait/success.rs +++ b/tests/ui/impl-trait/in-trait/success.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(return_position_impl_trait_in_trait, lint_reasons)] +#![feature(lint_reasons)] #![allow(incomplete_features)] use std::fmt::Display; diff --git a/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed b/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed index 58d83384a23..8dc8e045d47 100644 --- a/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed +++ b/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed @@ -1,8 +1,6 @@ // edition:2021 // run-rustfix -#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)] - trait Trait { #[allow(async_fn_in_trait)] async fn foo(); diff --git a/tests/ui/impl-trait/in-trait/suggest-missing-item.rs b/tests/ui/impl-trait/in-trait/suggest-missing-item.rs index c27229806e1..30b04d87b9a 100644 --- a/tests/ui/impl-trait/in-trait/suggest-missing-item.rs +++ b/tests/ui/impl-trait/in-trait/suggest-missing-item.rs @@ -1,8 +1,6 @@ // edition:2021 // run-rustfix -#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)] - trait Trait { #[allow(async_fn_in_trait)] async fn foo(); diff --git a/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr b/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr index 29f6bad86dc..cec94e39a35 100644 --- a/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr +++ b/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr @@ -1,5 +1,5 @@ error[E0046]: not all trait items implemented, missing: `foo`, `bar`, `test`, `baz` - --> $DIR/suggest-missing-item.rs:21:1 + --> $DIR/suggest-missing-item.rs:19:1 | LL | async fn foo(); | --------------- `foo` from trait diff --git a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs index 0bbe50ea6fd..c905bfce852 100644 --- a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs +++ b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs @@ -1,4 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] struct S; diff --git a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.stderr b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.stderr index 8ff54cad951..e904548742d 100644 --- a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.stderr +++ b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.stderr @@ -1,5 +1,5 @@ error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter - --> $DIR/trait-more-generics-than-impl.rs:11:11 + --> $DIR/trait-more-generics-than-impl.rs:10:11 | LL | fn bar<T>() -> impl Sized; | - expected 1 type parameter diff --git a/tests/ui/impl-trait/in-trait/unconstrained-lt.rs b/tests/ui/impl-trait/in-trait/unconstrained-lt.rs index 07c8606f9fe..ff3753de5a2 100644 --- a/tests/ui/impl-trait/in-trait/unconstrained-lt.rs +++ b/tests/ui/impl-trait/in-trait/unconstrained-lt.rs @@ -1,5 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] - trait Foo { fn test() -> impl Sized; } diff --git a/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr b/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr index cfce3556720..61a0f8454d1 100644 --- a/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr +++ b/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr @@ -1,5 +1,5 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-lt.rs:7:6 + --> $DIR/unconstrained-lt.rs:5:6 | LL | impl<'a, T> Foo for T { | ^^ unconstrained lifetime parameter diff --git a/tests/ui/impl-trait/in-trait/variance.rs b/tests/ui/impl-trait/in-trait/variance.rs index f8e4ab88c19..65565dcc2a6 100644 --- a/tests/ui/impl-trait/in-trait/variance.rs +++ b/tests/ui/impl-trait/in-trait/variance.rs @@ -1,4 +1,4 @@ -#![feature(rustc_attrs, return_position_impl_trait_in_trait)] +#![feature(rustc_attrs)] #![allow(internal_features)] #![rustc_variance_of_opaques] diff --git a/tests/ui/impl-trait/in-trait/variances-of-gat.rs b/tests/ui/impl-trait/in-trait/variances-of-gat.rs index 0d19e1ff416..aabb6f830ed 100644 --- a/tests/ui/impl-trait/in-trait/variances-of-gat.rs +++ b/tests/ui/impl-trait/in-trait/variances-of-gat.rs @@ -1,6 +1,5 @@ // check-pass -#![feature(return_position_impl_trait_in_trait)] trait Foo {} diff --git a/tests/ui/impl-trait/in-trait/wf-bounds.rs b/tests/ui/impl-trait/in-trait/wf-bounds.rs index ee873f94b26..f1e372b196a 100644 --- a/tests/ui/impl-trait/in-trait/wf-bounds.rs +++ b/tests/ui/impl-trait/in-trait/wf-bounds.rs @@ -1,6 +1,5 @@ // issue #101663 -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] use std::fmt::Display; diff --git a/tests/ui/impl-trait/in-trait/wf-bounds.stderr b/tests/ui/impl-trait/in-trait/wf-bounds.stderr index 4d60b133048..c20df9b40ed 100644 --- a/tests/ui/impl-trait/in-trait/wf-bounds.stderr +++ b/tests/ui/impl-trait/in-trait/wf-bounds.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/wf-bounds.rs:15:22 + --> $DIR/wf-bounds.rs:14:22 | LL | fn nya() -> impl Wf<Vec<[u8]>>; | ^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -9,14 +9,14 @@ note: required by a bound in `Vec` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/wf-bounds.rs:18:23 + --> $DIR/wf-bounds.rs:17:23 | LL | fn nya2() -> impl Wf<[u8]>; | ^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` note: required by a bound in `Wf` - --> $DIR/wf-bounds.rs:8:10 + --> $DIR/wf-bounds.rs:7:10 | LL | trait Wf<T> { | ^ required by this bound in `Wf` @@ -26,7 +26,7 @@ LL | trait Wf<T: ?Sized> { | ++++++++ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/wf-bounds.rs:21:44 + --> $DIR/wf-bounds.rs:20:44 | LL | fn nya3() -> impl Wf<(), Output = impl Wf<Vec<[u8]>>>; | ^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -36,14 +36,14 @@ note: required by a bound in `Vec` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL error[E0277]: `T` doesn't implement `std::fmt::Display` - --> $DIR/wf-bounds.rs:24:26 + --> $DIR/wf-bounds.rs:23:26 | LL | fn nya4<T>() -> impl Wf<NeedsDisplay<T>>; | ^^^^^^^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter | = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead note: required by a bound in `NeedsDisplay` - --> $DIR/wf-bounds.rs:12:24 + --> $DIR/wf-bounds.rs:11:24 | LL | struct NeedsDisplay<T: Display>(T); | ^^^^^^^ required by this bound in `NeedsDisplay` diff --git a/tests/ui/impl-trait/in-trait/where-clause.rs b/tests/ui/impl-trait/in-trait/where-clause.rs index 87bac519cf3..f7f4980b730 100644 --- a/tests/ui/impl-trait/in-trait/where-clause.rs +++ b/tests/ui/impl-trait/in-trait/where-clause.rs @@ -1,7 +1,6 @@ // check-pass // edition: 2021 -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] use std::fmt::Debug; diff --git a/tests/ui/impl-trait/nested-return-type2-tait2.rs b/tests/ui/impl-trait/nested-return-type2-tait2.rs index af8e0663054..b7fee1d91d1 100644 --- a/tests/ui/impl-trait/nested-return-type2-tait2.rs +++ b/tests/ui/impl-trait/nested-return-type2-tait2.rs @@ -1,3 +1,5 @@ +// check-pass + #![feature(type_alias_impl_trait)] trait Duh {} @@ -17,6 +19,7 @@ impl<R: Duh, F: FnMut() -> R> Trait for F { type Sendable = impl Send; type Traitable = impl Trait<Assoc = Sendable>; +//~^ WARN opaque type `Traitable` does not satisfy its associated type bounds // The `impl Send` here is then later compared against the inference var // created, causing the inference var to be set to `impl Send` instead of @@ -25,7 +28,6 @@ type Traitable = impl Trait<Assoc = Sendable>; // type does not implement `Duh`, even if its hidden type does. So we error out. fn foo() -> Traitable { || 42 - //~^ ERROR `Sendable: Duh` is not satisfied } fn main() { diff --git a/tests/ui/impl-trait/nested-return-type2-tait2.stderr b/tests/ui/impl-trait/nested-return-type2-tait2.stderr index 125262b96e8..790e339c8b1 100644 --- a/tests/ui/impl-trait/nested-return-type2-tait2.stderr +++ b/tests/ui/impl-trait/nested-return-type2-tait2.stderr @@ -1,18 +1,13 @@ -error[E0277]: the trait bound `Sendable: Duh` is not satisfied - --> $DIR/nested-return-type2-tait2.rs:27:5 +warning: opaque type `Traitable` does not satisfy its associated type bounds + --> $DIR/nested-return-type2-tait2.rs:21:29 | -LL | || 42 - | ^^^^^ the trait `Duh` is not implemented for `Sendable` +LL | type Assoc: Duh; + | --- this associated type bound is unsatisfied for `Sendable` +... +LL | type Traitable = impl Trait<Assoc = Sendable>; + | ^^^^^^^^^^^^^^^^ | - = help: the trait `Duh` is implemented for `i32` -note: required for `{closure@$DIR/nested-return-type2-tait2.rs:27:5: 27:7}` to implement `Trait` - --> $DIR/nested-return-type2-tait2.rs:14:31 - | -LL | impl<R: Duh, F: FnMut() -> R> Trait for F { - | --- ^^^^^ ^ - | | - | unsatisfied trait bound introduced here + = note: `#[warn(opaque_hidden_inferred_bound)]` on by default -error: aborting due to previous error +warning: 1 warning emitted -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/nested-return-type2-tait3.rs b/tests/ui/impl-trait/nested-return-type2-tait3.rs index 74fd8a9dda0..eed5c271f88 100644 --- a/tests/ui/impl-trait/nested-return-type2-tait3.rs +++ b/tests/ui/impl-trait/nested-return-type2-tait3.rs @@ -1,3 +1,5 @@ +// check-pass + #![feature(type_alias_impl_trait)] trait Duh {} @@ -16,6 +18,7 @@ impl<R: Duh, F: FnMut() -> R> Trait for F { } type Traitable = impl Trait<Assoc = impl Send>; +//~^ WARN opaque type `Traitable` does not satisfy its associated type bounds // The `impl Send` here is then later compared against the inference var // created, causing the inference var to be set to `impl Send` instead of @@ -24,7 +27,6 @@ type Traitable = impl Trait<Assoc = impl Send>; // type does not implement `Duh`, even if its hidden type does. So we error out. fn foo() -> Traitable { || 42 - //~^ ERROR `impl Send: Duh` is not satisfied } fn main() { diff --git a/tests/ui/impl-trait/nested-return-type2-tait3.stderr b/tests/ui/impl-trait/nested-return-type2-tait3.stderr index c2332b6e4bd..72aa51a23f4 100644 --- a/tests/ui/impl-trait/nested-return-type2-tait3.stderr +++ b/tests/ui/impl-trait/nested-return-type2-tait3.stderr @@ -1,18 +1,17 @@ -error[E0277]: the trait bound `impl Send: Duh` is not satisfied - --> $DIR/nested-return-type2-tait3.rs:26:5 +warning: opaque type `Traitable` does not satisfy its associated type bounds + --> $DIR/nested-return-type2-tait3.rs:20:29 | -LL | || 42 - | ^^^^^ the trait `Duh` is not implemented for `impl Send` +LL | type Assoc: Duh; + | --- this associated type bound is unsatisfied for `impl Send` +... +LL | type Traitable = impl Trait<Assoc = impl Send>; + | ^^^^^^^^^^^^^^^^^ | - = help: the trait `Duh` is implemented for `i32` -note: required for `{closure@$DIR/nested-return-type2-tait3.rs:26:5: 26:7}` to implement `Trait` - --> $DIR/nested-return-type2-tait3.rs:14:31 + = note: `#[warn(opaque_hidden_inferred_bound)]` on by default +help: add this bound | -LL | impl<R: Duh, F: FnMut() -> R> Trait for F { - | --- ^^^^^ ^ - | | - | unsatisfied trait bound introduced here +LL | type Traitable = impl Trait<Assoc = impl Send + Duh>; + | +++++ -error: aborting due to previous error +warning: 1 warning emitted -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/static-lifetime-return-position-impl-trait.rs b/tests/ui/impl-trait/static-lifetime-return-position-impl-trait.rs index 98dbaf036be..91a0e0d4829 100644 --- a/tests/ui/impl-trait/static-lifetime-return-position-impl-trait.rs +++ b/tests/ui/impl-trait/static-lifetime-return-position-impl-trait.rs @@ -1,7 +1,7 @@ // check-pass #![allow(incomplete_features)] -#![feature(adt_const_params, return_position_impl_trait_in_trait)] +#![feature(adt_const_params)] pub struct Element; diff --git a/tests/ui/impl-trait/where-allowed.rs b/tests/ui/impl-trait/where-allowed.rs index d3fab326e74..158dc5ab974 100644 --- a/tests/ui/impl-trait/where-allowed.rs +++ b/tests/ui/impl-trait/where-allowed.rs @@ -104,10 +104,9 @@ trait InTraitDefnParameters { fn in_parameters(_: impl Debug); } -// Disallowed +// Allowed trait InTraitDefnReturn { fn in_return() -> impl Debug; - //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types } // Allowed and disallowed in trait impls @@ -124,7 +123,7 @@ impl DummyTrait for () { // Allowed fn in_trait_impl_return() -> impl Debug { () } - //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types + // Allowed } // Allowed diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index bd7c9a94793..2d8895030f2 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -17,7 +17,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic | outer `impl Trait` error[E0658]: `impl Trait` in associated types is unstable - --> $DIR/where-allowed.rs:120:16 + --> $DIR/where-allowed.rs:119:16 | LL | type Out = impl Debug; | ^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | type Out = impl Debug; = help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:155:23 + --> $DIR/where-allowed.rs:154:23 | LL | type InTypeAlias<R> = impl Debug; | ^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | type InTypeAlias<R> = impl Debug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:158:39 + --> $DIR/where-allowed.rs:157:39 | LL | type InReturnInTypeAlias<R> = fn() -> impl Debug; | ^^^^^^^^^^ @@ -145,146 +145,128 @@ error[E0562]: `impl Trait` only allowed in function and inherent method argument LL | InTupleVariant(impl Debug), | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in trait method return types - --> $DIR/where-allowed.rs:109:23 - | -LL | fn in_return() -> impl Debug; - | ^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable - -error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `impl` method return types - --> $DIR/where-allowed.rs:126:34 - | -LL | fn in_trait_impl_return() -> impl Debug { () } - | ^^^^^^^^^^ - | - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable - error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `extern fn` params - --> $DIR/where-allowed.rs:139:33 + --> $DIR/where-allowed.rs:138:33 | LL | fn in_foreign_parameters(_: impl Debug); | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `extern fn` return types - --> $DIR/where-allowed.rs:142:31 + --> $DIR/where-allowed.rs:141:31 | LL | fn in_foreign_return() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `fn` pointer return types - --> $DIR/where-allowed.rs:158:39 + --> $DIR/where-allowed.rs:157:39 | LL | type InReturnInTypeAlias<R> = fn() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in traits - --> $DIR/where-allowed.rs:163:16 + --> $DIR/where-allowed.rs:162:16 | LL | impl PartialEq<impl Debug> for () { | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in impl headers - --> $DIR/where-allowed.rs:168:24 + --> $DIR/where-allowed.rs:167:24 | LL | impl PartialEq<()> for impl Debug { | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in impl headers - --> $DIR/where-allowed.rs:173:6 + --> $DIR/where-allowed.rs:172:6 | LL | impl impl Debug { | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in impl headers - --> $DIR/where-allowed.rs:179:24 + --> $DIR/where-allowed.rs:178:24 | LL | impl InInherentImplAdt<impl Debug> { | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in bounds - --> $DIR/where-allowed.rs:185:11 + --> $DIR/where-allowed.rs:184:11 | LL | where impl Debug: Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in bounds - --> $DIR/where-allowed.rs:192:15 + --> $DIR/where-allowed.rs:191:15 | LL | where Vec<impl Debug>: Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in bounds - --> $DIR/where-allowed.rs:199:24 + --> $DIR/where-allowed.rs:198:24 | LL | where T: PartialEq<impl Debug> | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait params - --> $DIR/where-allowed.rs:206:17 + --> $DIR/where-allowed.rs:205:17 | LL | where T: Fn(impl Debug) | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait return types - --> $DIR/where-allowed.rs:213:22 + --> $DIR/where-allowed.rs:212:22 | LL | where T: Fn() -> impl Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generic parameter defaults - --> $DIR/where-allowed.rs:219:40 + --> $DIR/where-allowed.rs:218:40 | LL | struct InStructGenericParamDefault<T = impl Debug>(T); | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generic parameter defaults - --> $DIR/where-allowed.rs:223:36 + --> $DIR/where-allowed.rs:222:36 | LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generic parameter defaults - --> $DIR/where-allowed.rs:227:38 + --> $DIR/where-allowed.rs:226:38 | LL | trait InTraitGenericParamDefault<T = impl Debug> {} | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generic parameter defaults - --> $DIR/where-allowed.rs:231:41 + --> $DIR/where-allowed.rs:230:41 | LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T; | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generic parameter defaults - --> $DIR/where-allowed.rs:235:11 + --> $DIR/where-allowed.rs:234:11 | LL | impl <T = impl Debug> T {} | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generic parameter defaults - --> $DIR/where-allowed.rs:242:40 + --> $DIR/where-allowed.rs:241:40 | LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {} | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings - --> $DIR/where-allowed.rs:248:29 + --> $DIR/where-allowed.rs:247:29 | LL | let _in_local_variable: impl Fn() = || {}; | ^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in closure return types - --> $DIR/where-allowed.rs:250:46 + --> $DIR/where-allowed.rs:249:46 | LL | let _in_return_in_local_variable = || -> impl Fn() { || {} }; | ^^^^^^^^^ error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:235:7 + --> $DIR/where-allowed.rs:234:7 | LL | impl <T = impl Debug> T {} | ^^^^^^^^^^^^^^ @@ -294,7 +276,7 @@ LL | impl <T = impl Debug> T {} = note: `#[deny(invalid_type_param_default)]` on by default error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:242:36 + --> $DIR/where-allowed.rs:241:36 | LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {} | ^^^^^^^^^^^^^^ @@ -303,14 +285,14 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {} = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887> error[E0118]: no nominal type found for inherent implementation - --> $DIR/where-allowed.rs:235:1 + --> $DIR/where-allowed.rs:234:1 | LL | impl <T = impl Debug> T {} | ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type | = note: either implement a trait on it or create a newtype to wrap it instead -error: aborting due to 47 previous errors +error: aborting due to 45 previous errors Some errors have detailed explanations: E0118, E0562, E0658, E0666. For more information about an error, try `rustc --explain E0118`. diff --git a/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.rs b/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.rs new file mode 100644 index 00000000000..4544c898ab8 --- /dev/null +++ b/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.rs @@ -0,0 +1,61 @@ +struct MyError; + +fn foo(x: bool) -> Result<(), MyError> { + if x { + Err(MyError); + //~^ ERROR type annotations needed + } + + Ok(()) +} + +fn bar(x: bool) -> Result<(), MyError> { + if x { + Ok(()); + //~^ ERROR type annotations needed + } + + Ok(()) +} + +fn baz(x: bool) -> Result<(), MyError> { + //~^ ERROR mismatched types + if x { + 1; + } + + Err(MyError); +} + +fn error() -> Result<(), MyError> { + Err(MyError) +} + +fn bak(x: bool) -> Result<(), MyError> { + if x { + //~^ ERROR mismatched types + error(); + } else { + //~^ ERROR mismatched types + error(); + } +} + +fn bad(x: bool) -> Result<(), MyError> { + Err(MyError); //~ ERROR type annotations needed + Ok(()) +} + +fn with_closure<F, A, B>(_: F) -> i32 +where + F: FnOnce(A, B), +{ + 0 +} + +fn a() -> i32 { + with_closure(|x: u32, y| {}); //~ ERROR type annotations needed + 0 +} + +fn main() {} diff --git a/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr b/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr new file mode 100644 index 00000000000..1fea73529a8 --- /dev/null +++ b/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr @@ -0,0 +1,98 @@ +error[E0282]: type annotations needed + --> $DIR/issue-86094-suggest-add-return-to-coerce-ret-ty.rs:5:9 + | +LL | Err(MyError); + | ^^^ cannot infer type of the type parameter `T` declared on the enum `Result` + | +help: consider specifying the generic arguments + | +LL | Err::<T, MyError>(MyError); + | ++++++++++++++ +help: you might have meant to return this to infer its type parameters + | +LL | return Err(MyError); + | ++++++ + +error[E0282]: type annotations needed + --> $DIR/issue-86094-suggest-add-return-to-coerce-ret-ty.rs:14:9 + | +LL | Ok(()); + | ^^ cannot infer type of the type parameter `E` declared on the enum `Result` + | +help: consider specifying the generic arguments + | +LL | Ok::<(), E>(()); + | +++++++++ +help: you might have meant to return this to infer its type parameters + | +LL | return Ok(()); + | ++++++ + +error[E0308]: mismatched types + --> $DIR/issue-86094-suggest-add-return-to-coerce-ret-ty.rs:21:20 + | +LL | fn baz(x: bool) -> Result<(), MyError> { + | --- ^^^^^^^^^^^^^^^^^^^ expected `Result<(), MyError>`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression +... +LL | Err(MyError); + | - help: remove this semicolon to return this value + | + = note: expected enum `Result<(), MyError>` + found unit type `()` + +error[E0308]: mismatched types + --> $DIR/issue-86094-suggest-add-return-to-coerce-ret-ty.rs:35:10 + | +LL | if x { + | __________^ +LL | | +LL | | error(); + | | - help: remove this semicolon to return this value +LL | | } else { + | |_____^ expected `Result<(), MyError>`, found `()` + | + = note: expected enum `Result<(), MyError>` + found unit type `()` + +error[E0308]: mismatched types + --> $DIR/issue-86094-suggest-add-return-to-coerce-ret-ty.rs:38:12 + | +LL | } else { + | ____________^ +LL | | +LL | | error(); + | | - help: remove this semicolon to return this value +LL | | } + | |_____^ expected `Result<(), MyError>`, found `()` + | + = note: expected enum `Result<(), MyError>` + found unit type `()` + +error[E0282]: type annotations needed + --> $DIR/issue-86094-suggest-add-return-to-coerce-ret-ty.rs:45:5 + | +LL | Err(MyError); + | ^^^ cannot infer type of the type parameter `T` declared on the enum `Result` + | +help: consider specifying the generic arguments + | +LL | Err::<T, MyError>(MyError); + | ++++++++++++++ + +error[E0282]: type annotations needed + --> $DIR/issue-86094-suggest-add-return-to-coerce-ret-ty.rs:57:27 + | +LL | with_closure(|x: u32, y| {}); + | ^ + | +help: consider giving this closure parameter an explicit type + | +LL | with_closure(|x: u32, y: /* Type */| {}); + | ++++++++++++ + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0282, E0308. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/parser/fn-header-semantic-fail.rs b/tests/ui/parser/fn-header-semantic-fail.rs index 71f18a27e7c..f8b58cad7c1 100644 --- a/tests/ui/parser/fn-header-semantic-fail.rs +++ b/tests/ui/parser/fn-header-semantic-fail.rs @@ -13,25 +13,23 @@ fn main() { //~^ ERROR functions cannot be both `const` and `async` trait X { - async fn ft1(); //~ ERROR functions in traits cannot be declared `async` + async fn ft1(); // OK. unsafe fn ft2(); // OK. const fn ft3(); //~ ERROR functions in traits cannot be declared const extern "C" fn ft4(); // OK. const async unsafe extern "C" fn ft5(); - //~^ ERROR functions in traits cannot be declared `async` - //~| ERROR functions in traits cannot be declared const + //~^ ERROR functions in traits cannot be declared const //~| ERROR functions cannot be both `const` and `async` } struct Y; impl X for Y { - async fn ft1() {} //~ ERROR functions in traits cannot be declared `async` + async fn ft1() {} // OK. unsafe fn ft2() {} // OK. const fn ft3() {} //~ ERROR functions in traits cannot be declared const extern "C" fn ft4() {} const async unsafe extern "C" fn ft5() {} - //~^ ERROR functions in traits cannot be declared `async` - //~| ERROR functions in traits cannot be declared const + //~^ ERROR functions in traits cannot be declared const //~| ERROR functions cannot be both `const` and `async` } diff --git a/tests/ui/parser/fn-header-semantic-fail.stderr b/tests/ui/parser/fn-header-semantic-fail.stderr index 7f7b7e835f8..cdf01e0c5df 100644 --- a/tests/ui/parser/fn-header-semantic-fail.stderr +++ b/tests/ui/parser/fn-header-semantic-fail.stderr @@ -29,19 +29,19 @@ LL | const async unsafe extern "C" fn ft5(); | `const` because of this error[E0379]: functions in traits cannot be declared const - --> $DIR/fn-header-semantic-fail.rs:30:9 + --> $DIR/fn-header-semantic-fail.rs:29:9 | LL | const fn ft3() {} | ^^^^^ functions in traits cannot be const error[E0379]: functions in traits cannot be declared const - --> $DIR/fn-header-semantic-fail.rs:32:9 + --> $DIR/fn-header-semantic-fail.rs:31:9 | LL | const async unsafe extern "C" fn ft5() {} | ^^^^^ functions in traits cannot be const error: functions cannot be both `const` and `async` - --> $DIR/fn-header-semantic-fail.rs:32:9 + --> $DIR/fn-header-semantic-fail.rs:31:9 | LL | const async unsafe extern "C" fn ft5() {} | ^^^^^-^^^^^------------------------------ @@ -50,7 +50,7 @@ LL | const async unsafe extern "C" fn ft5() {} | `const` because of this error: functions cannot be both `const` and `async` - --> $DIR/fn-header-semantic-fail.rs:43:9 + --> $DIR/fn-header-semantic-fail.rs:41:9 | LL | const async unsafe extern "C" fn fi5() {} | ^^^^^-^^^^^------------------------------ @@ -59,7 +59,7 @@ LL | const async unsafe extern "C" fn fi5() {} | `const` because of this error: functions in `extern` blocks cannot have qualifiers - --> $DIR/fn-header-semantic-fail.rs:48:18 + --> $DIR/fn-header-semantic-fail.rs:46:18 | LL | extern "C" { | ---------- in this `extern` block @@ -72,7 +72,7 @@ LL | fn fe1(); | ~~ error: functions in `extern` blocks cannot have qualifiers - --> $DIR/fn-header-semantic-fail.rs:49:19 + --> $DIR/fn-header-semantic-fail.rs:47:19 | LL | extern "C" { | ---------- in this `extern` block @@ -86,7 +86,7 @@ LL | fn fe2(); | ~~ error: functions in `extern` blocks cannot have qualifiers - --> $DIR/fn-header-semantic-fail.rs:50:18 + --> $DIR/fn-header-semantic-fail.rs:48:18 | LL | extern "C" { | ---------- in this `extern` block @@ -100,7 +100,7 @@ LL | fn fe3(); | ~~ error: functions in `extern` blocks cannot have qualifiers - --> $DIR/fn-header-semantic-fail.rs:51:23 + --> $DIR/fn-header-semantic-fail.rs:49:23 | LL | extern "C" { | ---------- in this `extern` block @@ -114,7 +114,7 @@ LL | fn fe4(); | ~~ error: functions in `extern` blocks cannot have qualifiers - --> $DIR/fn-header-semantic-fail.rs:52:42 + --> $DIR/fn-header-semantic-fail.rs:50:42 | LL | extern "C" { | ---------- in this `extern` block @@ -128,7 +128,7 @@ LL | fn fe5(); | ~~ error: functions cannot be both `const` and `async` - --> $DIR/fn-header-semantic-fail.rs:52:9 + --> $DIR/fn-header-semantic-fail.rs:50:9 | LL | const async unsafe extern "C" fn fe5(); | ^^^^^-^^^^^---------------------------- @@ -136,59 +136,6 @@ LL | const async unsafe extern "C" fn fe5(); | | `async` because of this | `const` because of this -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/fn-header-semantic-fail.rs:16:9 - | -LL | async fn ft1(); - | -----^^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/fn-header-semantic-fail.rs:20:9 - | -LL | const async unsafe extern "C" fn ft5(); - | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/fn-header-semantic-fail.rs:28:9 - | -LL | async fn ft1() {} - | -----^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/fn-header-semantic-fail.rs:32:9 - | -LL | const async unsafe extern "C" fn ft5() {} - | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error: aborting due to 18 previous errors +error: aborting due to 14 previous errors -Some errors have detailed explanations: E0379, E0706. -For more information about an error, try `rustc --explain E0379`. +For more information about this error, try `rustc --explain E0379`. diff --git a/tests/ui/pattern/issue-115599.rs b/tests/ui/pattern/issue-115599.rs new file mode 100644 index 00000000000..7a222b90aec --- /dev/null +++ b/tests/ui/pattern/issue-115599.rs @@ -0,0 +1,7 @@ +const CONST_STRING: String = String::new(); + +fn main() { + let empty_str = String::from(""); + if let CONST_STRING = empty_str {} + //~^ ERROR to use a constant of type `Vec<u8>` in a pattern, `Vec<u8>` must be annotated with `#[derive(PartialEq, Eq)]` +} diff --git a/tests/ui/pattern/issue-115599.stderr b/tests/ui/pattern/issue-115599.stderr new file mode 100644 index 00000000000..e6cb6c1ddac --- /dev/null +++ b/tests/ui/pattern/issue-115599.stderr @@ -0,0 +1,11 @@ +error: to use a constant of type `Vec<u8>` in a pattern, `Vec<u8>` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/issue-115599.rs:5:12 + | +LL | if let CONST_STRING = empty_str {} + | ^^^^^^^^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details + +error: aborting due to previous error + diff --git a/tests/ui/pattern/usefulness/consts-opaque.rs b/tests/ui/pattern/usefulness/consts-opaque.rs index 2032cf13bc2..6dc1425cf03 100644 --- a/tests/ui/pattern/usefulness/consts-opaque.rs +++ b/tests/ui/pattern/usefulness/consts-opaque.rs @@ -52,7 +52,6 @@ fn main() { BAR => {} //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` _ => {} - //~^ ERROR unreachable pattern } match BAR { @@ -60,7 +59,6 @@ fn main() { //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` Bar => {} _ => {} - //~^ ERROR unreachable pattern } match BAR { diff --git a/tests/ui/pattern/usefulness/consts-opaque.stderr b/tests/ui/pattern/usefulness/consts-opaque.stderr index cd88e6a22e4..51f2f276bbe 100644 --- a/tests/ui/pattern/usefulness/consts-opaque.stderr +++ b/tests/ui/pattern/usefulness/consts-opaque.stderr @@ -38,7 +38,7 @@ LL | BAR => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:59:9 + --> $DIR/consts-opaque.rs:58:9 | LL | BAR => {} | ^^^ @@ -47,7 +47,7 @@ LL | BAR => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:67:9 + --> $DIR/consts-opaque.rs:65:9 | LL | BAR => {} | ^^^ @@ -56,7 +56,7 @@ LL | BAR => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:69:9 + --> $DIR/consts-opaque.rs:67:9 | LL | BAR => {} | ^^^ @@ -65,7 +65,7 @@ LL | BAR => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:75:9 + --> $DIR/consts-opaque.rs:73:9 | LL | BAZ => {} | ^^^ @@ -74,7 +74,7 @@ LL | BAZ => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:83:9 + --> $DIR/consts-opaque.rs:81:9 | LL | BAZ => {} | ^^^ @@ -83,7 +83,7 @@ LL | BAZ => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:89:9 + --> $DIR/consts-opaque.rs:87:9 | LL | BAZ => {} | ^^^ @@ -91,37 +91,14 @@ LL | BAZ => {} = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details -error: unreachable pattern - --> $DIR/consts-opaque.rs:54:9 - | -LL | Bar => {} - | --- matches any value -... -LL | _ => {} - | ^ unreachable pattern - | -note: the lint level is defined here - --> $DIR/consts-opaque.rs:6:9 - | -LL | #![deny(unreachable_patterns)] - | ^^^^^^^^^^^^^^^^^^^^ - -error: unreachable pattern - --> $DIR/consts-opaque.rs:62:9 - | -LL | Bar => {} - | --- matches any value -LL | _ => {} - | ^ unreachable pattern - error[E0004]: non-exhaustive patterns: `Wrap(_)` not covered - --> $DIR/consts-opaque.rs:124:11 + --> $DIR/consts-opaque.rs:122:11 | LL | match WRAPQUUX { | ^^^^^^^^ pattern `Wrap(_)` not covered | note: `Wrap<fn(usize, usize) -> usize>` defined here - --> $DIR/consts-opaque.rs:106:12 + --> $DIR/consts-opaque.rs:104:12 | LL | struct Wrap<T>(T); | ^^^^ @@ -132,6 +109,6 @@ LL ~ WRAPQUUX => {}, LL + Wrap(_) => todo!() | -error: aborting due to 12 previous errors; 1 warning emitted +error: aborting due to 10 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0004`. diff --git a/tests/ui/resolve/issue-55673.fixed b/tests/ui/resolve/issue-55673.fixed new file mode 100644 index 00000000000..261742a26cb --- /dev/null +++ b/tests/ui/resolve/issue-55673.fixed @@ -0,0 +1,21 @@ +// run-rustfix +#![allow(dead_code)] +trait Foo { + type Bar; +} + +fn foo<T: Foo>() +where + T::Bar: std::fmt::Debug, + //~^ ERROR associated type `Baa` not found for `T` +{ +} + +fn bar<T>() +where + T::Bar: std::fmt::Debug, T: Foo + //~^ ERROR associated type `Baa` not found for `T` +{ +} + +fn main() {} diff --git a/tests/ui/resolve/issue-55673.rs b/tests/ui/resolve/issue-55673.rs index 0436bd39742..6ac49be141c 100644 --- a/tests/ui/resolve/issue-55673.rs +++ b/tests/ui/resolve/issue-55673.rs @@ -1,3 +1,5 @@ +// run-rustfix +#![allow(dead_code)] trait Foo { type Bar; } @@ -9,4 +11,11 @@ where { } +fn bar<T>() +where + T::Baa: std::fmt::Debug, + //~^ ERROR associated type `Baa` not found for `T` +{ +} + fn main() {} diff --git a/tests/ui/resolve/issue-55673.stderr b/tests/ui/resolve/issue-55673.stderr index 39318f95905..ffc3252230a 100644 --- a/tests/ui/resolve/issue-55673.stderr +++ b/tests/ui/resolve/issue-55673.stderr @@ -1,9 +1,29 @@ error[E0220]: associated type `Baa` not found for `T` - --> $DIR/issue-55673.rs:7:8 + --> $DIR/issue-55673.rs:9:8 | LL | T::Baa: std::fmt::Debug, | ^^^ there is a similarly named associated type `Bar` in the trait `Foo` + | +help: change the associated type name to use `Bar` from `Foo` + | +LL | T::Bar: std::fmt::Debug, + | ~~~ + +error[E0220]: associated type `Baa` not found for `T` + --> $DIR/issue-55673.rs:16:8 + | +LL | T::Baa: std::fmt::Debug, + | ^^^ there is a similarly named associated type `Bar` in the trait `Foo` + | +help: consider further restricting type parameter `T` + | +LL | T::Baa: std::fmt::Debug, T: Foo + | ~~~~~~~~ +help: and also change the associated type name + | +LL | T::Bar: std::fmt::Debug, + | ~~~ -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0220`. diff --git a/tests/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs b/tests/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs index 49462f52fb4..927ecd9aee0 100644 --- a/tests/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs +++ b/tests/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs @@ -9,11 +9,9 @@ impl A { trait B { async fn associated(); - //~^ ERROR cannot be declared `async` } impl B for A { async fn associated(); //~ ERROR without body - //~^ ERROR cannot be declared `async` } fn main() {} diff --git a/tests/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr b/tests/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr index 1354abb4f14..da9eeea954a 100644 --- a/tests/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr +++ b/tests/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr @@ -15,39 +15,12 @@ LL | async fn inherent(); | help: provide a definition for the function: `{ <body> }` error: associated function in `impl` without body - --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:5 + --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:14:5 | LL | async fn associated(); | ^^^^^^^^^^^^^^^^^^^^^- | | | help: provide a definition for the function: `{ <body> }` -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:11:5 - | -LL | async fn associated(); - | -----^^^^^^^^^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error[E0706]: functions in traits cannot be declared `async` - --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:5 - | -LL | async fn associated(); - | -----^^^^^^^^^^^^^^^^^ - | | - | `async` because of this - | - = note: `async` trait functions are not currently supported - = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait - = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information - = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable - -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0706`. diff --git a/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.rs b/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.rs index 77227ebd834..1933a68c221 100644 --- a/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.rs +++ b/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.rs @@ -1,4 +1,3 @@ -#![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] mod child { diff --git a/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.stderr b/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.stderr index c4371a0024c..40f736c215d 100644 --- a/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.stderr +++ b/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `Something: Termination` is not satisfied - --> $DIR/issue-103052-2.rs:12:22 + --> $DIR/issue-103052-2.rs:11:22 | LL | fn main() -> Something { | ^^^^^^^^^ the trait `Termination` is not implemented for `Something` | note: required by a bound in `Main::{opaque#0}` - --> $DIR/issue-103052-2.rs:6:27 + --> $DIR/issue-103052-2.rs:5:27 | LL | fn main() -> impl std::process::Termination; | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::{opaque#0}` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs index f396deff4fe..8e4de57b019 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs @@ -4,7 +4,6 @@ associated_type_bounds, const_trait_impl, const_cmp, - return_position_impl_trait_in_trait, )] use std::marker::Destruct; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr index f9078e22791..4a9090d0b53 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr @@ -5,31 +5,31 @@ LL | const_cmp, | ^^^^^^^^^ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:12:30 + --> $DIR/const-impl-trait.rs:11:30 | LL | const fn cmp(a: &impl ~const PartialEq) -> bool { | ^^^^^^^^^ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:16:30 + --> $DIR/const-impl-trait.rs:15:30 | LL | const fn wrap(x: impl ~const PartialEq + ~const Destruct) | ^^^^^^^^^ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:17:20 + --> $DIR/const-impl-trait.rs:16:20 | LL | -> impl ~const PartialEq + ~const Destruct | ^^^^^^^^^ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:24:29 + --> $DIR/const-impl-trait.rs:23:29 | LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; | ^^^^^^^^^ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:28:29 + --> $DIR/const-impl-trait.rs:27:29 | LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { | ^^^^^^^^^ diff --git a/tests/ui/traits/issue-59029-1.stderr b/tests/ui/traits/issue-59029-1.stderr index 51354bcc545..5c47eefcd6c 100644 --- a/tests/ui/traits/issue-59029-1.stderr +++ b/tests/ui/traits/issue-59029-1.stderr @@ -2,13 +2,13 @@ error[E0220]: associated type `Res` not found for `Self` --> $DIR/issue-59029-1.rs:5:52 | LL | trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>; - | ^^^ there is a similarly named associated type `Res` in the trait `Svc` + | ^^^ there is an associated type `Res` in the trait `Svc` error[E0220]: associated type `Res` not found for `Self` --> $DIR/issue-59029-1.rs:5:52 | LL | trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>; - | ^^^ there is a similarly named associated type `Res` in the trait `Svc` + | ^^^ there is an associated type `Res` in the trait `Svc` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/traits/new-solver/deduce-closure-signature-after-normalization.rs b/tests/ui/traits/new-solver/deduce-closure-signature-after-normalization.rs index d67fc65032c..51f62bc2312 100644 --- a/tests/ui/traits/new-solver/deduce-closure-signature-after-normalization.rs +++ b/tests/ui/traits/new-solver/deduce-closure-signature-after-normalization.rs @@ -1,8 +1,6 @@ // compile-flags: -Ztrait-solver=next // check-pass -#![feature(return_position_impl_trait_in_trait)] - trait Foo { fn test() -> impl Fn(u32) -> u32 { |x| x.count_ones() diff --git a/tests/ui/traits/new-solver/normalize-async-closure-in-trait.rs b/tests/ui/traits/new-solver/normalize-async-closure-in-trait.rs index b6200096a89..cc16cc87169 100644 --- a/tests/ui/traits/new-solver/normalize-async-closure-in-trait.rs +++ b/tests/ui/traits/new-solver/normalize-async-closure-in-trait.rs @@ -2,8 +2,6 @@ // check-pass // edition:2021 -#![feature(async_fn_in_trait)] - trait Foo { async fn bar() {} } diff --git a/tests/ui/traits/new-solver/specialization-unconstrained.stderr b/tests/ui/traits/new-solver/specialization-unconstrained.stderr index 9915da1a27a..ed4dafa1484 100644 --- a/tests/ui/traits/new-solver/specialization-unconstrained.stderr +++ b/tests/ui/traits/new-solver/specialization-unconstrained.stderr @@ -8,12 +8,6 @@ LL | #![feature(specialization)] = help: consider using `min_specialization` instead, which is more stable and complete = note: `#[warn(incomplete_features)]` on by default -error[E0282]: type annotations needed - --> $DIR/specialization-unconstrained.rs:14:22 - | -LL | default type Id = T; - | ^ cannot infer type for associated type `<T as Default>::Id` - error[E0284]: type annotations needed: cannot satisfy `<u32 as Default>::Id == ()` --> $DIR/specialization-unconstrained.rs:20:5 | @@ -26,6 +20,12 @@ note: required by a bound in `test` LL | fn test<T: Default<Id = U>, U>() {} | ^^^^^^ required by this bound in `test` +error[E0282]: type annotations needed + --> $DIR/specialization-unconstrained.rs:14:22 + | +LL | default type Id = T; + | ^ cannot infer type for associated type `<T as Default>::Id` + error: aborting due to 2 previous errors; 1 warning emitted Some errors have detailed explanations: E0282, E0284. diff --git a/tests/ui/type-alias-impl-trait/not_well_formed.fixed b/tests/ui/type-alias-impl-trait/not_well_formed.fixed new file mode 100644 index 00000000000..d98e83ff6dd --- /dev/null +++ b/tests/ui/type-alias-impl-trait/not_well_formed.fixed @@ -0,0 +1,19 @@ +// run-rustfix +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +fn main() {} + +trait TraitWithAssoc { + type Assoc; +} + +type Foo<V: TraitWithAssoc> = impl Trait<V::Assoc>; //~ associated type `Assoc` not found for `V` + +trait Trait<U> {} + +impl<W> Trait<W> for () {} + +fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T> { + () +} diff --git a/tests/ui/type-alias-impl-trait/not_well_formed.rs b/tests/ui/type-alias-impl-trait/not_well_formed.rs index fbb7a4d58e4..18f173a693d 100644 --- a/tests/ui/type-alias-impl-trait/not_well_formed.rs +++ b/tests/ui/type-alias-impl-trait/not_well_formed.rs @@ -1,4 +1,6 @@ +// run-rustfix #![feature(type_alias_impl_trait)] +#![allow(dead_code)] fn main() {} diff --git a/tests/ui/type-alias-impl-trait/not_well_formed.stderr b/tests/ui/type-alias-impl-trait/not_well_formed.stderr index c36b95f47e8..b267e6a7544 100644 --- a/tests/ui/type-alias-impl-trait/not_well_formed.stderr +++ b/tests/ui/type-alias-impl-trait/not_well_formed.stderr @@ -1,8 +1,13 @@ error[E0220]: associated type `Assoc` not found for `V` - --> $DIR/not_well_formed.rs:9:29 + --> $DIR/not_well_formed.rs:11:29 | LL | type Foo<V> = impl Trait<V::Assoc>; - | ^^^^^ there is a similarly named associated type `Assoc` in the trait `TraitWithAssoc` + | ^^^^^ there is an associated type `Assoc` in the trait `TraitWithAssoc` + | +help: consider restricting type parameter `V` + | +LL | type Foo<V: TraitWithAssoc> = impl Trait<V::Assoc>; + | ++++++++++++++++ error: aborting due to previous error diff --git a/triagebot.toml b/triagebot.toml index 4b051db0d73..fbdc28787ff 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -23,6 +23,18 @@ allow-unauthenticated = [ "needs-triage", ] +[review-submitted] +# This label is added when a "request changes" review is submitted. +reviewed_label = "S-waiting-on-author" +# These labels are removed when a "request changes" review is submitted. +review_labels = ["S-waiting-on-review"] + +[review-requested] +# Those labels are removed when PR author requests a review from an assignee +remove_labels = ["S-waiting-on-author"] +# Those labels are added when PR author requests a review from an assignee +add_labels = ["S-waiting-on-review"] + [glacier] [ping.icebreakers-llvm] @@ -402,6 +414,10 @@ message_on_add = """\ Issue #{number} "{title}" has been added. """ +[no-merges] +exclude_titles = ["Rollup of", "subtree update"] +labels = ["has-merge-commits", "S-waiting-on-author"] + [github-releases] format = "rustc" project-name = "Rust" @@ -540,7 +556,7 @@ cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"] [mentions."compiler/rustc_smir"] message = "This PR changes Stable MIR" -cc = ["@oli-obk", "@celinval", "@spastorino"] +cc = ["@oli-obk", "@celinval", "@spastorino", "@ouz-a"] [mentions."compiler/stable_mir"] message = "This PR changes Stable MIR" @@ -722,7 +738,7 @@ style-team = [ "/compiler/rustc_traits" = ["compiler", "types"] "/compiler/rustc_type_ir" = ["compiler", "types"] "/library/alloc" = ["libs"] -"/library/core" = ["libs", "@scottmcm"] +"/library/core" = ["libs"] "/library/panic_abort" = ["libs"] "/library/panic_unwind" = ["libs"] "/library/proc_macro" = ["@petrochenkov"] diff --git a/x b/x index ef3eb8b04b4..426b58d0d4e 100755 --- a/x +++ b/x @@ -11,10 +11,13 @@ set -eu sh -n "$0" realpath() { - if [ -d "$1" ]; then - CDPATH='' command cd "$1" && pwd -P + local path="$1" + if [ -L "$path" ]; then + readlink -f "$path" + elif [ -d "$path" ]; then + (cd -P "$path" && pwd) else - echo "$(realpath "$(dirname "$1")")/$(basename "$1")" + echo "$(realpath "$(dirname "$path")")/$(basename "$path")" fi } |
